Compare commits
132 Commits
3.1.0-exp.
...
main
| Author | SHA1 | Date |
|---|---|---|
|
|
d4e8dc834f | |
|
|
130daa99a0 | |
|
|
001942b055 | |
|
|
09e1ec4aeb | |
|
|
01b9c19b81 | |
|
|
e144df7c70 | |
|
|
80b891393a | |
|
|
03dbf2e2d4 | |
|
|
e22b1ffcb0 | |
|
|
05ef07db93 | |
|
|
5ba8d712f9 | |
|
|
866a74e333 | |
|
|
7b4c9ebba3 | |
|
|
f96a0fee44 | |
|
|
2e239ad871 | |
|
|
d7a81ac4a4 | |
|
|
0a4a409553 | |
|
|
4f1aaabadf | |
|
|
e9a2e59fe3 | |
|
|
5d28e64cd4 | |
|
|
c9a9a180d0 | |
|
|
632583462d | |
|
|
09bc00b76b | |
|
|
01ce850c1b | |
|
|
4aaafed025 | |
|
|
b554210266 | |
|
|
844d634cf2 | |
|
|
16ae1feb54 | |
|
|
aee157eed6 | |
|
|
ca1643f2ec | |
|
|
37d49b5266 | |
|
|
5f331f414b | |
|
|
2b353b579e | |
|
|
88af8ff46f | |
|
|
d1b75694e7 | |
|
|
ac89655e3d | |
|
|
c3a29d1d91 | |
|
|
985a0c04d2 | |
|
|
9200063d64 | |
|
|
d6e6249765 | |
|
|
6538f64b7d | |
|
|
8289073020 | |
|
|
0e46feeced | |
|
|
4af125703d | |
|
|
8feaeaae38 | |
|
|
e24eb78092 | |
|
|
46a045c485 | |
|
|
d65cd0b95e | |
|
|
80892ce7d0 | |
|
|
cef8d001ad | |
|
|
008b81dc70 | |
|
|
65a7747d33 | |
|
|
e592a60a44 | |
|
|
e5f1430219 | |
|
|
ba102703fd | |
|
|
616f04efd3 | |
|
|
e9d5c694b2 | |
|
|
3820af30c8 | |
|
|
d6b0abc2f9 | |
|
|
ac9c780d34 | |
|
|
87f560a7fb | |
|
|
6522cfcee0 | |
|
|
1712bca887 | |
|
|
8d621e6274 | |
|
|
cdf3a00253 | |
|
|
5b155ccc68 | |
|
|
08123b386a | |
|
|
b16408251a | |
|
|
0bebc23cf0 | |
|
|
709176bb38 | |
|
|
baad23fabd | |
|
|
59880141f2 | |
|
|
dec9148ab3 | |
|
|
8412c11e7d | |
|
|
da7de69803 | |
|
|
85eeae6762 | |
|
|
043835d4af | |
|
|
1817738725 | |
|
|
555026b987 | |
|
|
3dbcc541ab | |
|
|
8d1277e3b1 | |
|
|
b584a4cc6c | |
|
|
a920648bcc | |
|
|
f996875333 | |
|
|
4aeb53a4d7 | |
|
|
dfe82dee43 | |
|
|
cfd7b7252b | |
|
|
cf76f13df2 | |
|
|
48ab2b6eb2 | |
|
|
973f8acba5 | |
|
|
7aa362a028 | |
|
|
ee88e26987 | |
|
|
d0c74e3e32 | |
|
|
9ab26c4b9c | |
|
|
8a70507a73 | |
|
|
623c7cb61b | |
|
|
32b881b96a | |
|
|
90c705f9cd | |
|
|
838fe095a1 | |
|
|
f8b2222cd6 | |
|
|
f06b37a91c | |
|
|
ba9c3ddc86 | |
|
|
d1fbce348a | |
|
|
06f100928d | |
|
|
7ef33dc19f | |
|
|
579f88d4e7 | |
|
|
d0930e3880 | |
|
|
22a662dee7 | |
|
|
7c29abb4f5 | |
|
|
6e046135ec | |
|
|
d874de464f | |
|
|
b6fb8dfeb3 | |
|
|
b2d600be62 | |
|
|
33cec295fd | |
|
|
2a0b9de442 | |
|
|
af278a497e | |
|
|
c62166cd3e | |
|
|
af7df8044a | |
|
|
2dd1d8bcb5 | |
|
|
e1444d478a | |
|
|
c64b1b07bc | |
|
|
c9955ddb48 | |
|
|
0410dff10a | |
|
|
9de88a5dda | |
|
|
53ff13db46 | |
|
|
afeac3f58d | |
|
|
05d2edd5cd | |
|
|
1165e0f743 | |
|
|
2080d509b7 | |
|
|
5c88b8c51f | |
|
|
5f2f36c79f | |
|
|
c139b86d26 |
|
|
@ -27,6 +27,10 @@ body:
|
|||
What version of the package are you using?
|
||||
You can check the Unity version in Package Manager Window. See [manual](https://docs.unity3d.com/Manual/upm-ui.html).
|
||||
options:
|
||||
- 3.1.0-exp.8
|
||||
- 3.1.0-exp.7
|
||||
- 3.1.0-exp.6
|
||||
- 3.1.0-exp.5
|
||||
- 3.1.0-exp.4
|
||||
- 3.1.0-exp.3
|
||||
- 3.1.0-exp.2
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
compile_test_for_package_version:
|
||||
name: Compilation Test for Package Version
|
||||
agent:
|
||||
type: Unity::VM
|
||||
flavor: b1.large
|
||||
image: package-ci/win10:v4
|
||||
variables:
|
||||
VERSION: 3.1.0-exp.7
|
||||
commands:
|
||||
# When unity-config will be part of the image, this will turn into a no-op
|
||||
- |
|
||||
where /q unity-config
|
||||
if ERRORLEVEL 1 (
|
||||
%GSUDO% choco install unity-config -y -s https://artifactory.prd.it.unity3d.com/artifactory/api/nuget/unity-choco-local
|
||||
)
|
||||
- unity-downloader-cli -c editor -u 2020.3 --wait
|
||||
- .Editor\Unity.exe -createProject CompilationTestProject -logFile logs\CreateProject.log -batchmode -quit
|
||||
- |
|
||||
unity-config project set registry --project-path CompilationTestProject candidates
|
||||
unity-config project add dependency --project-path CompilationTestProject com.unity.renderstreaming@%VERSION%
|
||||
- .Editor\Unity.exe -projectPath CompilationTestProject -logFile logs\CompilePackage.log -batchmode -quit
|
||||
artifacts:
|
||||
logs:
|
||||
paths:
|
||||
- logs/*
|
||||
|
||||
compile_test_for_local_path:
|
||||
name: Compilation Test for Local Path
|
||||
agent:
|
||||
type: Unity::VM
|
||||
flavor: b1.large
|
||||
image: package-ci/win10:v4
|
||||
commands:
|
||||
# When unity-config will be part of the image, this will turn into a no-op
|
||||
- |
|
||||
where /q unity-config
|
||||
if ERRORLEVEL 1 (
|
||||
%GSUDO% choco install unity-config -y -s https://artifactory.prd.it.unity3d.com/artifactory/api/nuget/unity-choco-local
|
||||
)
|
||||
- unity-downloader-cli -c editor -u 2020.3 --wait
|
||||
- .Editor\Unity.exe -createProject CompilationTestProject -logFile logs\CreateProject.log -batchmode -quit
|
||||
- |
|
||||
unity-config project set registry --project-path CompilationTestProject candidates
|
||||
unity-config project add dependency --project-path CompilationTestProject .\com.unity.renderstreaming
|
||||
- .Editor\Unity.exe -projectPath CompilationTestProject -logFile logs\CompilePackage.log -batchmode -quit
|
||||
artifacts:
|
||||
logs:
|
||||
paths:
|
||||
- logs/*
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
{% metadata_file .yamato/package.metafile %}
|
||||
|
||||
# todo(kazuki): Use old version because Code Coverage 1.2.2 has some issues.
|
||||
coverage_pkg_version: 1.1.1
|
||||
---
|
||||
|
||||
{% for platform in platforms %}
|
||||
{% if platform.name != "macos" and platform.name != "macos-m1" %}
|
||||
{% for editor in editors %}
|
||||
codecoverage_{{ packagename }}_{{ platform.name }}_{{ editor.version }}:
|
||||
name: Code coverage {{ package_displayname }} {{ platform.name }} {{ editor.version }}
|
||||
agent:
|
||||
type: {{ platform.type }}
|
||||
image: {{ platform.image }}
|
||||
flavor: {{ platform.flavor }}
|
||||
commands:
|
||||
- pip config set global.index-url https://artifactory.prd.it.unity3d.com/artifactory/api/pypi/pypi/simple
|
||||
- pip install unity-downloader-cli --index-url https://artifactory.prd.it.unity3d.com/artifactory/api/pypi/pypi/simple
|
||||
- npm install upm-ci-utils@{{ upm.package_version }} -g --registry {{ upm.registry_url }}
|
||||
{% if platform.name == "win" %}
|
||||
- |
|
||||
set WEBAPP_PATH=%cd%\Webapp\bin~\{{ platform.packed_webapp_name }}
|
||||
upm-ci package test -u {{ editor.version }} --extra-utr-arg=--coverage-pkg-version={{ coverage_pkg_version }} --package-path {{ packagename }} --enable-code-coverage --code-coverage-options "generateAdditionalMetrics;generateHtmlReport;generateBadgeReport;assemblyFilters:-UnityEngine.*,+Unity.RenderStreaming"
|
||||
{% else %}
|
||||
- |
|
||||
export WEBAPP_PATH=$(pwd)/WebApp/bin~/{{ platform.packed_webapp_name }}
|
||||
upm-ci package test -u {{ editor.version }} --extra-utr-arg=--coverage-pkg-version={{ coverage_pkg_version }} --package-path {{ packagename }} --enable-code-coverage --code-coverage-options "generateAdditionalMetrics;generateHtmlReport;generateBadgeReport;assemblyFilters:-UnityEngine.*,+Unity.RenderStreaming"
|
||||
{% endif %}
|
||||
artifacts:
|
||||
{{ packagename }}_{{ editor.version }}_{{ platform.name }}_coverage_results:
|
||||
paths:
|
||||
- "upm-ci~/test-results/**"
|
||||
dependencies:
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#pack
|
||||
- .yamato/upm-ci-webapp.yml#pack_{{ platform.packed_webapp_platform }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
# Check formatting using dotnet-format tool.
|
||||
check_formatting_dotnet-format:
|
||||
name: Checking codes formatting using dotnet-format tool
|
||||
agent:
|
||||
type: Unity::VM::osx
|
||||
image: package-ci/macos-12:v4
|
||||
flavor: b1.large
|
||||
commands:
|
||||
- dotnet tool install --tool-path tools dotnet-format || echo dotnet format already installed
|
||||
- tools/dotnet-format --check --exclude RenderStreaming~ -f . 1>formatting.log 2>formatting_errors.log
|
||||
artifacts:
|
||||
logs:
|
||||
paths:
|
||||
- formatting.log
|
||||
- formatting_errors.log
|
||||
|
|
@ -2,13 +2,16 @@ upm:
|
|||
registry_url: https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-npm
|
||||
package_version: stable
|
||||
intra_pypi_url: https://artifactory.prd.it.unity3d.com/artifactory/api/pypi/pypi/simple
|
||||
packagename: com.unity.renderstreaming
|
||||
package_displayname: Render Streaming
|
||||
editors:
|
||||
- version: 2020.3
|
||||
- version: 2021.3
|
||||
- version: 2022.1
|
||||
- version: 2022.3
|
||||
- version: 2023.1
|
||||
- version: trunk
|
||||
platforms:
|
||||
- name: win
|
||||
- name: win-gpu
|
||||
type: Unity::VM::GPU
|
||||
image: renderstreaming/win10:v0.3.13-1084240
|
||||
flavor: b1.large
|
||||
|
|
@ -27,9 +30,24 @@ platforms:
|
|||
platform: standalone
|
||||
- backend: il2cpp
|
||||
platform: standalone
|
||||
- name: win
|
||||
type: Unity::VM
|
||||
image: renderstreaming/win10:v0.3.13-1084239
|
||||
flavor: b1.large
|
||||
packed_webapp_name: webserver.exe
|
||||
packed_webapp_platform: win
|
||||
test_params:
|
||||
- backend: mono
|
||||
platform: editmode
|
||||
- backend: mono
|
||||
platform: playmode
|
||||
- backend: mono
|
||||
platform: standalone
|
||||
- backend: il2cpp
|
||||
platform: standalone
|
||||
- name: macos
|
||||
type: Unity::metal::macmini
|
||||
image: package-ci/mac:v1.20.0-1079282
|
||||
image: package-ci/macos-12:v4.10.0-1271191
|
||||
flavor: m1.mac
|
||||
architecture: x64
|
||||
packed_webapp_name: webserver_mac
|
||||
|
|
@ -49,7 +67,7 @@ platforms:
|
|||
platform: standalone
|
||||
- name: macos-m1
|
||||
type: Unity::metal::devkit
|
||||
image: package-ci/mac:v1.20.0-1079282
|
||||
image: package-ci/macos-12:v4.10.0-1271191
|
||||
flavor: m1.mac
|
||||
architecture: arm64
|
||||
packed_webapp_name: webserver_mac
|
||||
|
|
@ -68,7 +86,7 @@ platforms:
|
|||
# - backend: il2cpp
|
||||
# additional_component_arg: StandaloneSupport-IL2CPP
|
||||
# platform: standalone
|
||||
- name: linux
|
||||
- name: linux-gpu
|
||||
type: Unity::VM::GPU
|
||||
image: renderstreaming/ubuntu:v0.2.4-1104053
|
||||
flavor: b1.large
|
||||
|
|
@ -1,16 +1,12 @@
|
|||
{% metadata_file .yamato/meta/environments.yml %}
|
||||
{% metadata_file .yamato/package.metafile %}
|
||||
|
||||
test_platforms:
|
||||
- name: win
|
||||
type: Unity::VM
|
||||
image: package-ci/win10:v1.21.0-1103459
|
||||
image: package-ci/win10:v4
|
||||
flavor: b1.large
|
||||
packages:
|
||||
- name: renderstreaming
|
||||
packagename: com.unity.renderstreaming
|
||||
---
|
||||
|
||||
{% for package in packages %}
|
||||
{% for editor in editors %}
|
||||
{% for platform in test_platforms %}
|
||||
promotion_test_{{ platform.name }}_{{ editor.version }}:
|
||||
|
|
@ -23,13 +19,13 @@ promotion_test_{{ platform.name }}_{{ editor.version }}:
|
|||
UPMCI_PROMOTION: 1
|
||||
commands:
|
||||
- npm install upm-ci-utils@{{ upm.package_version }} -g --registry {{ upm.registry_url }}
|
||||
- upm-ci package test --unity-version {{ editor.version }} --package-path {{ package.packagename }} --platform editmode --backend mono
|
||||
- upm-ci package test --unity-version {{ editor.version }} --package-path {{ packagename }} --platform editmode --backend mono
|
||||
artifacts:
|
||||
logs:
|
||||
paths:
|
||||
- "upm-ci~/test-results/**/*"
|
||||
dependencies:
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#pack_{{ package.name }}
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#pack
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
|
|
@ -37,13 +33,13 @@ promote_dry_run:
|
|||
name: Promote Dry Run to Production
|
||||
agent:
|
||||
type: Unity::VM
|
||||
image: package-ci/win10:v1.21.0-1103459
|
||||
image: package-ci/win10:v4
|
||||
flavor: b1.large
|
||||
variables:
|
||||
UPMCI_PROMOTION: 1
|
||||
commands:
|
||||
- npm install upm-ci-utils@{{ upm.package_version }} -g --registry {{ upm.registry_url }}
|
||||
- upm-ci package promote --dry-run --package-path {{ package.packagename }}
|
||||
- upm-ci package promote --dry-run --package-path {{ packagename }}
|
||||
triggers:
|
||||
tags:
|
||||
only:
|
||||
|
|
@ -53,7 +49,7 @@ promote_dry_run:
|
|||
paths:
|
||||
- "upm-ci~/packages/*.tgz"
|
||||
dependencies:
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#pack_{{ package.name }}
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#pack
|
||||
{% for editor in editors %}
|
||||
{% if editor.version != "trunk" -%} # exclude trunk to test
|
||||
{% for platform in test_platforms %}
|
||||
|
|
@ -66,13 +62,13 @@ promote:
|
|||
name: Promote to Production
|
||||
agent:
|
||||
type: Unity::VM
|
||||
image: package-ci/win10:v1.21.0-1103459
|
||||
image: package-ci/win10:v4
|
||||
flavor: b1.large
|
||||
variables:
|
||||
UPMCI_PROMOTION: 1
|
||||
commands:
|
||||
- npm install upm-ci-utils@{{ upm.package_version }} -g --registry {{ upm.registry_url }}
|
||||
- upm-ci package promote --package-path {{ package.packagename }}
|
||||
- upm-ci package promote --package-path {{ packagename }}
|
||||
triggers:
|
||||
tags:
|
||||
only:
|
||||
|
|
@ -82,7 +78,7 @@ promote:
|
|||
paths:
|
||||
- "upm-ci~/packages/*.tgz"
|
||||
dependencies:
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#pack_{{ package.name }}
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#pack
|
||||
{% for editor in editors %}
|
||||
{% if editor.version != "trunk" -%} # exclude trunk to test
|
||||
{% for platform in test_platforms %}
|
||||
|
|
@ -90,5 +86,3 @@ promote:
|
|||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
# .yamato/upm-ci-publish-github-release.yml
|
||||
{% metadata_file .yamato/meta/environments.yml %}
|
||||
{% metadata_file .yamato/package.metafile %}
|
||||
|
||||
webapp-platforms:
|
||||
- name: win
|
||||
|
|
|
|||
|
|
@ -1,12 +1,9 @@
|
|||
{% metadata_file .yamato/meta/environments.yml %}
|
||||
{% metadata_file .yamato/package.metafile %}
|
||||
|
||||
packages:
|
||||
- name: renderstreaming
|
||||
packagename: com.unity.renderstreaming
|
||||
---
|
||||
{% for package in packages %}
|
||||
pack_{{ package.name }}:
|
||||
name: Pack {{ package.packagename }}
|
||||
|
||||
pack:
|
||||
name: Pack {{ package_displayname }}
|
||||
agent:
|
||||
type: Unity::VM
|
||||
image: package-ci/ubuntu-20:v1.4.0-1081009
|
||||
|
|
@ -14,18 +11,18 @@ pack_{{ package.name }}:
|
|||
commands:
|
||||
- npm install upm-ci-utils@{{ upm.package_version }} -g --registry {{ upm.registry_url }}
|
||||
- find ./{{ project.packagename }} -type l -exec bash -c 'sh BuildScripts~/convert_symlinks.sh "$0"' {} \;
|
||||
- upm-ci package pack --package-path {{ package.packagename }}
|
||||
- upm-ci package pack --package-path {{ packagename }}
|
||||
artifacts:
|
||||
{{ package.name }}_package:
|
||||
{{ packagename }}_package:
|
||||
paths:
|
||||
- "upm-ci~/packages/**/*"
|
||||
|
||||
{% for editor in editors %}
|
||||
build_{{ package.name }}_{{ editor.version }}_ios:
|
||||
name : Build {{ package.packagename }} with {{ editor.version }} for ios device
|
||||
build_{{ editor.version }}_ios:
|
||||
name : Build {{ package_displayname }} with {{ editor.version }} for ios device
|
||||
agent:
|
||||
type: Unity::VM::osx
|
||||
image: package-ci/mac:v1.20.0-1079282
|
||||
image: package-ci/macos-12:v4.10.0-1271191
|
||||
flavor: b1.large
|
||||
commands:
|
||||
- find upm-ci~/packages/ -name "*.tgz" | xargs -I file tar xvf file -C upm-ci~
|
||||
|
|
@ -42,13 +39,14 @@ build_{{ package.name }}_{{ editor.version }}_ios:
|
|||
paths:
|
||||
- "build/logs/**"
|
||||
dependencies:
|
||||
- .yamato/upm-ci-{{ package.name }}-packages.yml#pack_{{ package.name }}
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#pack
|
||||
|
||||
test_{{ package.name }}_{{ editor.version }}_ios:
|
||||
name: Test {{ package.packagename }} with {{ editor.version }} on ios device
|
||||
test_{{ packagename }}_{{ editor.version }}_ios:
|
||||
name: Test {{ package_displayname }} with {{ editor.version }} on ios device
|
||||
agent:
|
||||
type: Unity::mobile::iPhone
|
||||
image: mobile/macos-10.15-testing:v0.0.7-909915
|
||||
image: package-ci/macos-12:v4.10.0-1271191
|
||||
model: SE
|
||||
flavor: b1.medium
|
||||
skip_checkout: true
|
||||
commands:
|
||||
|
|
@ -63,22 +61,22 @@ test_{{ package.name }}_{{ editor.version }}_ios:
|
|||
paths:
|
||||
- "build/test-results/**"
|
||||
dependencies:
|
||||
- .yamato/upm-ci-{{ package.name }}-packages.yml#build_{{ package.name }}_{{ editor.version }}_ios
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#build_{{ editor.version }}_ios
|
||||
|
||||
{% for target in test_targets_android %}
|
||||
build_{{ package.name }}_{{ editor.version }}_android_{{ target.name }}:
|
||||
name : Build {{ package.packagename }} with {{ editor.version }} for android device {{ target.name }}
|
||||
build_{{ editor.version }}_android_{{ target.name }}:
|
||||
name : Build {{ package_displayname }} with {{ editor.version }} for android device {{ target.name }}
|
||||
agent:
|
||||
type: Unity::VM::osx
|
||||
image: package-ci/mac:v1.20.0-1079282
|
||||
image: package-ci/macos-12:v4.10.0-1271191
|
||||
flavor: b1.xlarge
|
||||
commands:
|
||||
- |
|
||||
find upm-ci~/packages/ -name "*.tgz" | xargs -I file tar xvf file -C upm-ci~
|
||||
cp -rf upm-ci~/package/Runtime/Plugins Runtime/
|
||||
{% if target.name == "vulkan" -%}
|
||||
{% if target.name == "vulkan" %}
|
||||
cp -f TestProjects/Empty/ProjectSettings/ProjectSettings-android-vulkan.asset TestProjects/Empty/ProjectSettings/ProjectSettings.asset
|
||||
{% endif -%}
|
||||
{% endif %}
|
||||
- pip install unity-downloader-cli --index-url https://artifactory.prd.it.unity3d.com/artifactory/api/pypi/pypi/simple
|
||||
- unity-downloader-cli -c Editor -c Android -u {{ editor.version }} --fast -w
|
||||
- curl -s https://artifactory.prd.it.unity3d.com/artifactory/unity-tools/utr-standalone/utr --output utr
|
||||
|
|
@ -92,17 +90,17 @@ build_{{ package.name }}_{{ editor.version }}_android_{{ target.name }}:
|
|||
paths:
|
||||
- "build/logs/**"
|
||||
dependencies:
|
||||
- .yamato/upm-ci-{{ package.name }}-packages.yml#pack_{{ package.name }}
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#pack
|
||||
|
||||
test_{{ package.name }}_{{ editor.version }}_android_{{ target.name }}:
|
||||
name: Test {{ package.packagename }} with {{ editor.version }} on android device {{ target.name }}
|
||||
test_{{ packagename }}_{{ editor.version }}_android_{{ target.name }}:
|
||||
name: Test {{ package_displayname }} with {{ editor.version }} on android device {{ target.name }}
|
||||
agent:
|
||||
type: Unity::mobile::shield
|
||||
image: mobile/android-execution-base:v0.0.2-791667
|
||||
image: mobile/android-package-ci-win:v0.1.4-1212670
|
||||
flavor: b1.medium
|
||||
skip_checkout: true
|
||||
dependencies:
|
||||
- .yamato/upm-ci-{{ package.name }}-packages.yml#build_{{ package.name }}_{{ editor.version }}_android_{{ target.name }}
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#build_{{ editor.version }}_android_{{ target.name }}
|
||||
commands:
|
||||
- wget http://artifactory-slo.bf.unity3d.com/artifactory/mobile-generic/android/ADBKeys.zip!/adbkey.pub -O %USERPROFILE%/.android/adbkey.pub
|
||||
- wget http://artifactory-slo.bf.unity3d.com/artifactory/mobile-generic/android/ADBKeys.zip!/adbkey -O %USERPROFILE%/.android/adbkey
|
||||
|
|
@ -126,8 +124,8 @@ test_{{ package.name }}_{{ editor.version }}_android_{{ target.name }}:
|
|||
{% for platform in platforms %}
|
||||
{% if platform.name != "macos" and platform.name != "macos-m1" %}
|
||||
{% for param in platform.test_params %}
|
||||
test_{{ package.name }}_{{ param.platform }}_{{ param.backend }}_{{ platform.name }}_{{ editor.version }}:
|
||||
name : Test {{ package.packagename }} {{ param.platform }} {{ param.backend }} {{ editor.version }} on {{ platform.name }}
|
||||
test_{{ packagename }}_{{ param.platform }}_{{ param.backend }}_{{ platform.name }}_{{ editor.version }}:
|
||||
name : Test {{ package_displayname }} {{ param.platform }} {{ param.backend }} {{ editor.version }} on {{ platform.name }}
|
||||
agent:
|
||||
type: {{ platform.type }}
|
||||
image: {{ platform.image }}
|
||||
|
|
@ -139,21 +137,21 @@ test_{{ package.name }}_{{ param.platform }}_{{ param.backend }}_{{ platform.nam
|
|||
- pip config set global.index-url https://artifactory.prd.it.unity3d.com/artifactory/api/pypi/pypi/simple
|
||||
- pip install unity-downloader-cli --index-url https://artifactory.prd.it.unity3d.com/artifactory/api/pypi/pypi/simple
|
||||
- npm install upm-ci-utils@{{ upm.package_version }} -g --registry {{ upm.registry_url }}
|
||||
{% if platform.name == "win" %}
|
||||
{% if platform.name == "win" or platform.name == "win-gpu" %}
|
||||
- |
|
||||
set WEBAPP_PATH=%cd%\Webapp\bin~\{{ platform.packed_webapp_name }}
|
||||
upm-ci package test -u {{ editor.version }} --package-path {{ package.packagename }} --platform {{ param.platform }} --backend {{ param.backend }} --extra-utr-arg="--timeout=3000"
|
||||
upm-ci package test -u {{ editor.version }} --package-path {{ packagename }} --platform {{ param.platform }} --backend {{ param.backend }} --enable-load-and-test-isolation
|
||||
{% else %}
|
||||
- |
|
||||
export WEBAPP_PATH=$(pwd)/WebApp/bin~/{{ platform.packed_webapp_name }}
|
||||
upm-ci package test -u {{ editor.version }} --package-path {{ package.packagename }} --platform {{ param.platform }} --backend {{ param.backend }} --extra-utr-arg="--timeout=3000 --testfilter=!HttpSignaling"
|
||||
upm-ci package test -u {{ editor.version }} --package-path {{ packagename }} --platform {{ param.platform }} --backend {{ param.backend }} --extra-utr-arg="--testfilter=!HttpSignaling" --enable-load-and-test-isolation
|
||||
{% endif %}
|
||||
artifacts:
|
||||
{{ package.name }}_{{ editor.version }}_{{ platform.name }}_test_results:
|
||||
{{ packagename }}_{{ editor.version }}_{{ platform.name }}_test_results:
|
||||
paths:
|
||||
- "upm-ci~/test-results/**/*"
|
||||
dependencies:
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#pack_{{ package.name }}
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#pack
|
||||
- .yamato/upm-ci-webapp.yml#pack_{{ platform.packed_webapp_platform }}
|
||||
|
||||
{% for project in test_projects %}
|
||||
|
|
@ -170,21 +168,21 @@ test_{{ project.name }}_{{ param.platform }}_{{ param.backend }}_{{ platform.nam
|
|||
- pip config set global.index-url https://artifactory.prd.it.unity3d.com/artifactory/api/pypi/pypi/simple
|
||||
- pip install unity-downloader-cli --index-url https://artifactory.prd.it.unity3d.com/artifactory/api/pypi/pypi/simple
|
||||
- npm install upm-ci-utils@{{ upm.package_version }} -g --registry {{ upm.registry_url }}
|
||||
{% if platform.name != "win" %}
|
||||
- find ./{{ package.packagename }} -type l -exec bash -c 'sh BuildScripts~/convert_symlinks.sh "$0"' {} \;
|
||||
{% if platform.name != "win" and platform.name != "win-gpu" %}
|
||||
- find ./{{ packagename }} -type l -exec bash -c 'sh BuildScripts~/convert_symlinks.sh "$0"' {} \;
|
||||
{% endif %}
|
||||
- upm-ci project pack --project-path {{ project.path }}
|
||||
{% if platform.name == "win" %}
|
||||
{% if platform.name == "win" or platform.name == "win-gpu" %}
|
||||
- |
|
||||
set WEBAPP_PATH=%cd%\Webapp\bin~\{{ platform.packed_webapp_name }}
|
||||
upm-ci project test -u {{ editor.version }} --project-path {{ project.path }} --platform {{ param.platform }} --backend {{ param.backend }} --extra-utr-arg="--timeout=3000"
|
||||
upm-ci project test -u {{ editor.version }} --project-path {{ project.path }} --platform {{ param.platform }} --backend {{ param.backend }}
|
||||
{% else %}
|
||||
- |
|
||||
export WEBAPP_PATH=$(pwd)/WebApp/bin~/{{ platform.packed_webapp_name }}
|
||||
upm-ci project test -u {{ editor.version }} --project-path {{ project.path }} --platform {{ param.platform }} --backend {{ param.backend }} --extra-utr-arg="--timeout=3000 --testfilter=!HttpSignaling"
|
||||
upm-ci project test -u {{ editor.version }} --project-path {{ project.path }} --platform {{ param.platform }} --backend {{ param.backend }} --extra-utr-arg="--testfilter=!HttpSignaling"
|
||||
{% endif %}
|
||||
artifacts:
|
||||
{{ package.name }}_{{ editor.version }}_{{ platform.name }}_test_results:
|
||||
{{ packagename }}_{{ editor.version }}_{{ platform.name }}_test_results:
|
||||
paths:
|
||||
- "upm-ci~/test-results/**/*"
|
||||
dependencies:
|
||||
|
|
@ -197,11 +195,11 @@ test_{{ project.name }}_{{ param.platform }}_{{ param.backend }}_{{ platform.nam
|
|||
|
||||
{% if param.platform == "standalone" %} # platform.name == "macos" or platform.name == "macos-m1" and param.platform == "standalone"
|
||||
|
||||
build_{{ package.name }}_{{ param.platform }}_{{ param.backend }}_{{ platform.name }}_{{ editor.version }}:
|
||||
name : Build {{ package.packagename }} with {{ param.platform }} {{ param.backend }} {{ editor.version }} on {{ platform.name }}
|
||||
build_{{ param.platform }}_{{ param.backend }}_{{ platform.name }}_{{ editor.version }}:
|
||||
name : Build {{ package_displayname }} with {{ param.platform }} {{ param.backend }} {{ editor.version }} on {{ platform.name }}
|
||||
agent:
|
||||
type: Unity::VM::osx
|
||||
image: package-ci/mac:v1.20.0-1079282
|
||||
image: package-ci/macos-12:v4.10.0-1271191
|
||||
flavor: m1.mac
|
||||
commands:
|
||||
- |
|
||||
|
|
@ -210,7 +208,7 @@ build_{{ package.name }}_{{ param.platform }}_{{ param.backend }}_{{ platform.na
|
|||
- unity-downloader-cli -c Editor -c {{ param.additional_component_arg }} -u {{ editor.version }} --fast -w
|
||||
- curl -s https://artifactory.prd.it.unity3d.com/artifactory/unity-tools/utr-standalone/utr --output utr
|
||||
- chmod +x ./utr
|
||||
- ./utr --suite=playmode --platform=StandaloneOSX --editor-location=.Editor --testproject=TestProjects/Empty --player-save-path=build/players --architecture=x64 --artifacts_path=build/logs --scripting-backend={{ param.backend }} --build-only --timeout=3000 --testfilter=!HttpSignaling
|
||||
- ./utr --suite=playmode --platform=StandaloneOSX --editor-location=.Editor --testproject=TestProjects/Empty --player-save-path=build/players --architecture=x64 --artifacts_path=build/logs --scripting-backend={{ param.backend }} --build-only --testfilter=!HttpSignaling
|
||||
artifacts:
|
||||
players:
|
||||
paths:
|
||||
|
|
@ -219,10 +217,10 @@ build_{{ package.name }}_{{ param.platform }}_{{ param.backend }}_{{ platform.na
|
|||
paths:
|
||||
- "build/logs/**"
|
||||
dependencies:
|
||||
- .yamato/upm-ci-{{ package.name }}-packages.yml#pack_{{ package.name }}
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#pack
|
||||
|
||||
test_{{ package.name }}_{{ param.platform }}_{{ param.backend }}_{{ platform.name }}_{{ editor.version }}:
|
||||
name : Test {{ package.packagename }} {{ param.platform }} {{ param.backend }} {{ editor.version }} on {{ platform.name }}
|
||||
test_{{ packagename }}_{{ param.platform }}_{{ param.backend }}_{{ platform.name }}_{{ editor.version }}:
|
||||
name : Test {{ package_displayname }} {{ param.platform }} {{ param.backend }} {{ editor.version }} on {{ platform.name }}
|
||||
agent:
|
||||
type: {{ platform.type }}
|
||||
image: {{ platform.image }}
|
||||
|
|
@ -242,17 +240,17 @@ test_{{ package.name }}_{{ param.platform }}_{{ param.backend }}_{{ platform.nam
|
|||
commands:
|
||||
- BuildScripts~/test_package_mac.sh
|
||||
artifacts:
|
||||
{{ package.name }}_{{ param.backend }}_{{ editor.version }}_{{ platform.name }}_test_results:
|
||||
{{ packagename }}_{{ param.backend }}_{{ editor.version }}_{{ platform.name }}_test_results:
|
||||
paths:
|
||||
- "upm-ci~/test-results/**"
|
||||
dependencies:
|
||||
- .yamato/upm-ci-{{ package.name }}-packages.yml#build_{{ package.name }}_{{ param.platform }}_{{ param.backend }}_{{ platform.name }}_{{ editor.version }}
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#build_{{ param.platform }}_{{ param.backend }}_{{ platform.name }}_{{ editor.version }}
|
||||
- .yamato/upm-ci-webapp.yml#pack_{{ platform.packed_webapp_platform }}
|
||||
|
||||
{% else %} # platform.name == "macos" or platform.name == "macos-m1" and param.platform != "standalone"
|
||||
|
||||
test_{{ package.name }}_{{ param.platform }}_{{ param.backend }}_{{ platform.name }}_{{ editor.version }}:
|
||||
name : Test {{ package.packagename }} {{ param.platform }} {{ param.backend }} {{ editor.version }} on {{ platform.name }}
|
||||
test_{{ packagename }}_{{ param.platform }}_{{ param.backend }}_{{ platform.name }}_{{ editor.version }}:
|
||||
name : Test {{ package_displayname }} {{ param.platform }} {{ param.backend }} {{ editor.version }} on {{ platform.name }}
|
||||
agent:
|
||||
type: {{ platform.type }}
|
||||
image: {{ platform.image }}
|
||||
|
|
@ -269,16 +267,16 @@ test_{{ package.name }}_{{ param.platform }}_{{ param.backend }}_{{ platform.nam
|
|||
TEST_ARCHITECTURE: {{ platform.architecture }}
|
||||
SCRIPTING_BACKEND: {{ param.backend }}
|
||||
EDITOR_VERSION: {{ editor.version }}
|
||||
EXTRA_UTR_ARG: --timeout=3000 --testfilter=!HttpSignaling
|
||||
EXTRA_UTR_ARG: --testfilter=!HttpSignaling
|
||||
commands:
|
||||
- find upm-ci~/packages/ -name "*.tgz" | xargs -I file tar xvf file -C upm-ci~
|
||||
- BuildScripts~/test_package_mac.sh
|
||||
artifacts:
|
||||
{{ package.name }}_{{ param.backend }}_{{ editor.version }}_{{ platform.name }}_test_results:
|
||||
{{ packagename }}_{{ param.backend }}_{{ editor.version }}_{{ platform.name }}_test_results:
|
||||
paths:
|
||||
- "upm-ci~/test-results/**"
|
||||
dependencies:
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#pack_{{ package.name }}
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#pack
|
||||
- .yamato/upm-ci-webapp.yml#pack_{{ platform.packed_webapp_platform }}
|
||||
|
||||
{% endif %}
|
||||
|
|
@ -301,33 +299,34 @@ test_{{ project.name }}_{{ param.platform }}_{{ param.backend }}_{{ platform.nam
|
|||
TEST_PLATFORM: {{ param.platform }}
|
||||
SCRIPTING_BACKEND: {{ param.backend }}
|
||||
EDITOR_VERSION: {{ editor.version }}
|
||||
EXTRA_UTR_ARG: --timeout=3000 --testfilter=!HttpSignaling
|
||||
EXTRA_UTR_ARG: --testfilter=!HttpSignaling
|
||||
commands:
|
||||
- find ./{{ package.packagename }} -type l -exec bash -c 'sh BuildScripts~/convert_symlinks.sh "$0"' {} \;
|
||||
- find ./{{ packagename }} -type l -exec bash -c 'sh BuildScripts~/convert_symlinks.sh "$0"' {} \;
|
||||
- BuildScripts~/test_package_mac.sh
|
||||
artifacts:
|
||||
{{ package.name }}_{{ editor.version }}_{{ platform.name }}_test_results:
|
||||
{{ packagename }}_{{ editor.version }}_{{ platform.name }}_test_results:
|
||||
paths:
|
||||
- "upm-ci~/test-results/**"
|
||||
dependencies:
|
||||
- .yamato/upm-ci-webapp.yml#pack_{{ platform.packed_webapp_platform }}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
trigger_test_{{ package.name }}_{{ editor.version }}:
|
||||
name : Trigger test {{ package.packagename }} {{ editor.version }} all platforms
|
||||
trigger_test_{{ packagename }}_{{ editor.version }}:
|
||||
name : Trigger test {{ package_displayname }} {{ editor.version }} all platforms
|
||||
dependencies:
|
||||
- .yamato/upm-ci-{{ package.name }}-packages.yml#test_{{ package.name }}_{{ editor.version }}
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#test_{{ packagename }}_{{ editor.version }}
|
||||
{% if editor.version == "2020.3" -%}
|
||||
triggers:
|
||||
expression: pull_request.target eq "develop"
|
||||
{% endif -%}
|
||||
expression: pull_request.target eq "main"
|
||||
{% endif %}
|
||||
|
||||
test_{{ package.name }}_{{ editor.version }}:
|
||||
name : Test {{ package.packagename }} {{ editor.version }} all platforms
|
||||
test_{{ packagename }}_{{ editor.version }}:
|
||||
name : Test {{ package_displayname }} {{ editor.version }} all platforms
|
||||
dependencies:
|
||||
- .yamato/format.yml#check_formatting_dotnet-format
|
||||
{% for platform in platforms %}
|
||||
{% for param in platform.test_params %}
|
||||
# todo(kazuki) :
|
||||
|
|
@ -335,113 +334,78 @@ test_{{ package.name }}_{{ editor.version }}:
|
|||
# XCode command line tools has not installed on m1 mac device (Standalone test don't need to install them)
|
||||
{% if platform.name == "macos-m1" %}
|
||||
{% if param.platform == "standalone" %}
|
||||
- .yamato/upm-ci-{{ package.name }}-packages.yml#test_{{ package.name }}_{{ param.platform }}_{{ param.backend }}_{{ platform.name }}_{{ editor.version }}
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#test_{{ packagename }}_{{ param.platform }}_{{ param.backend }}_{{ platform.name }}_{{ editor.version }}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
- .yamato/upm-ci-{{ package.name }}-packages.yml#test_{{ package.name }}_{{ param.platform }}_{{ param.backend }}_{{ platform.name }}_{{ editor.version }}
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#test_{{ packagename }}_{{ param.platform }}_{{ param.backend }}_{{ platform.name }}_{{ editor.version }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
- .yamato/upm-ci-{{ package.name }}-packages.yml#test_{{ package.name }}_{{ editor.version }}_ios
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#test_{{ packagename }}_{{ editor.version }}_ios
|
||||
{% for target in test_targets_android %}
|
||||
- .yamato/upm-ci-{{ package.name }}-packages.yml#test_{{ package.name }}_{{ editor.version }}_android_{{ target.name }}
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#test_{{ packagename }}_{{ editor.version }}_android_{{ target.name }}
|
||||
{% endfor %}
|
||||
|
||||
test_renderpipeline_{{ package.name }}_{{ editor.version }}:
|
||||
name : test {{ package.packagename }} {{ editor.version }} all RenderPipeline
|
||||
test_renderpipeline_{{ packagename }}_{{ editor.version }}:
|
||||
name : Test {{ package_displayname }} {{ editor.version }} all RenderPipeline
|
||||
dependencies:
|
||||
{% for platform in platforms %}
|
||||
{% for param in platform.test_params %}
|
||||
{% for project in test_projects %}
|
||||
- .yamato/upm-ci-{{ package.name }}-packages.yml#test_{{ project.name }}_{{ param.platform }}_{{ param.backend }}_{{ platform.name }}_{{ editor.version }}
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#test_{{ project.name }}_{{ param.platform }}_{{ param.backend }}_{{ platform.name }}_{{ editor.version }}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
publish_dry_run_{{ package.name }}:
|
||||
name: Publish Dry Run {{ package.packagename }}
|
||||
publish_dry_run_{{ packagename }}:
|
||||
name: Publish Dry Run {{ package_displayname }}
|
||||
agent:
|
||||
type: Unity::VM
|
||||
image: package-ci/win10:v1.21.0-1103459
|
||||
image: package-ci/win10:v4
|
||||
flavor: b1.large
|
||||
commands:
|
||||
- npm install upm-ci-utils@{{ upm.package_version }} -g --registry {{ upm.registry_url }}
|
||||
- upm-ci package publish --dry-run --package-path {{ package.packagename }}
|
||||
- upm-ci package publish --dry-run --package-path {{ packagename }}
|
||||
triggers:
|
||||
tags:
|
||||
only:
|
||||
- /^(r|R)(c|C)-\d+\.\d+\.\d+(-preview(\.\d+)?)?$/
|
||||
artifacts:
|
||||
{{ package.name }}_artifacts.zip:
|
||||
{{ packagename }}_artifacts.zip:
|
||||
paths:
|
||||
- "upm-ci~/packages/*.tgz"
|
||||
dependencies:
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#pack_{{ package.name }}
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#pack
|
||||
{% for editor in editors %}
|
||||
{% if editor.version != "trunk" -%} # exclude trunk to test
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#test_{{ package.name }}_editmode_mono_win_{{ editor.version }}
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#test_{{ package.name }}_editmode_mono_macos_{{ editor.version }}
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#test_{{ package.name }}_editmode_mono_linux_{{ editor.version }}
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#test_{{ packagename }}_editmode_mono_win-gpu_{{ editor.version }}
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#test_{{ packagename }}_editmode_mono_macos_{{ editor.version }}
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#test_{{ packagename }}_editmode_mono_linux-gpu_{{ editor.version }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
publish_{{ package.name }}:
|
||||
name: Publish {{ package.packagename }}
|
||||
publish_{{ packagename }}:
|
||||
name: Publish {{ package_displayname }}
|
||||
agent:
|
||||
type: Unity::VM
|
||||
image: package-ci/win10:v1.21.0-1103459
|
||||
image: package-ci/win10:v4
|
||||
flavor: b1.large
|
||||
commands:
|
||||
- npm install upm-ci-utils@{{ upm.package_version }} -g --registry {{ upm.registry_url }}
|
||||
- upm-ci package publish --package-path {{ package.packagename }}
|
||||
- upm-ci package publish --package-path {{ packagename }}
|
||||
triggers:
|
||||
tags:
|
||||
only:
|
||||
- /^(r|R)(c|C)-\d+\.\d+\.\d+(-preview(\.\d+)?)?$/
|
||||
artifacts:
|
||||
{{ package.name }}_artifacts.zip:
|
||||
{{ packagename }}_artifacts.zip:
|
||||
paths:
|
||||
- "upm-ci~/packages/*.tgz"
|
||||
dependencies:
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#pack_{{ package.name }}
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#pack
|
||||
{% for editor in editors %}
|
||||
{% if editor.version != "trunk" -%} # exclude trunk to test
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#trigger_test_{{ package.name }}_{{ editor.version }}
|
||||
{% if editor.version != "trunk" %} # exclude trunk to test
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#trigger_test_{{ packagename }}_{{ editor.version }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% for platform in platforms %}
|
||||
{% if platform.name != "macos" and platform.name != "macos-m1" %}
|
||||
{% for editor in editors %}
|
||||
codecoverage_{{ package.packagename }}_{{ platform.name }}_{{ editor.version }}:
|
||||
name: Code coverage {{ package.packagename }} {{ platform.name }} {{ editor.version }}
|
||||
agent:
|
||||
type: {{ platform.type }}
|
||||
image: {{ platform.image }}
|
||||
flavor: {{ platform.flavor }}
|
||||
commands:
|
||||
- pip config set global.index-url https://artifactory.prd.it.unity3d.com/artifactory/api/pypi/pypi/simple
|
||||
- pip install unity-downloader-cli --index-url https://artifactory.prd.it.unity3d.com/artifactory/api/pypi/pypi/simple
|
||||
- npm install upm-ci-utils@{{ upm.package_version }} -g --registry {{ upm.registry_url }}
|
||||
{% if platform.name == "win" %}
|
||||
- |
|
||||
set WEBAPP_PATH=%cd%\Webapp\bin~\{{ platform.packed_webapp_name }}
|
||||
upm-ci package test -u {{ editor.version }} --package-path {{ package.packagename }} --enable-code-coverage --code-coverage-options "generateAdditionalMetrics;generateHtmlReport;generateBadgeReport;assemblyFilters:-UnityEngine.*,+Unity.RenderStreaming" --extra-utr-arg="--timeout=3000"
|
||||
{% else %}
|
||||
- |
|
||||
export WEBAPP_PATH=$(pwd)/WebApp/bin~/{{ platform.packed_webapp_name }}
|
||||
upm-ci package test -u {{ editor.version }} --package-path {{ package.packagename }} --enable-code-coverage --code-coverage-options "generateAdditionalMetrics;generateHtmlReport;generateBadgeReport;assemblyFilters:-UnityEngine.*,+Unity.RenderStreaming" --extra-utr-arg="--timeout=3000"
|
||||
{% endif %}
|
||||
artifacts:
|
||||
{{ package.name }}_{{ editor.version }}_{{ platform.name }}_coverage_results:
|
||||
paths:
|
||||
- "upm-ci~/test-results/**"
|
||||
dependencies:
|
||||
- .yamato/upm-ci-renderstreaming-packages.yml#pack_{{ package.name }}
|
||||
- .yamato/upm-ci-webapp.yml#pack_{{ platform.packed_webapp_platform }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
# .yamato/upm-ci-template.yml
|
||||
{% metadata_file .yamato/meta/environments.yml %}
|
||||
{% metadata_file .yamato/package.metafile %}
|
||||
|
||||
---
|
||||
|
||||
{% for project in template_projects %}
|
||||
|
||||
{% for editor in editors %}
|
||||
{% if editor.version == "2020.3" -%}
|
||||
{% if editor.version == "2020.3" %}
|
||||
|
||||
prepack_{{ project.name }}_{{ editor.version }}:
|
||||
name: Pre-Pack {{ project.packagename }} {{ editor.version }} - Primed Artifacts
|
||||
agent:
|
||||
type: Unity::VM
|
||||
image: package-ci/win10:v1.21.0-1103459
|
||||
image: package-ci/win10:v4
|
||||
flavor: b1.large
|
||||
commands:
|
||||
- pip install unity-downloader-cli --index-url {{ intra_pypi_url }} --upgrade
|
||||
|
|
@ -44,7 +44,7 @@ pack_{{ project.name }}_{{ editor.version }}:
|
|||
- "upm-ci~/**/*"
|
||||
|
||||
{% for platform in platforms %}
|
||||
{% if platform.name == "win" -%}
|
||||
{% if platform.name == "win" or platform.name == "win-gpu" %}
|
||||
{% for param in platform.test_params %}
|
||||
test_{{ project.name }}_{{ param.platform }}_{{ param.backend }}_{{ platform.name }}_{{ editor.version }}:
|
||||
name : Test {{ project.packagename }} {{ param.platform }} {{ param.backend }} {{ editor.version }} on {{ platform.name }}
|
||||
|
|
@ -66,9 +66,9 @@ test_{{ project.name }}_{{ param.platform }}_{{ param.backend }}_{{ platform.nam
|
|||
- .yamato/upm-ci-template.yml#pack_{{ project.name }}_{{ editor.version }}
|
||||
- .yamato/upm-ci-webapp.yml#pack_{{ platform.name }}
|
||||
{% endfor %}
|
||||
{% else -%}
|
||||
{% else %}
|
||||
{% for param in platform.test_params %}
|
||||
{% if project.name != "renderstreaming-rtx" -%}
|
||||
{% if project.name != "renderstreaming-rtx" %}
|
||||
test_{{ project.name }}_{{ param.platform }}_{{ param.backend }}_{{ platform.name }}_{{ editor.version }}:
|
||||
name : Test {{ project.packagename }} {{ param.platform }} {{ param.backend }} {{ editor.version }} on {{ platform.name }}
|
||||
agent:
|
||||
|
|
@ -85,36 +85,36 @@ test_{{ project.name }}_{{ param.platform }}_{{ param.backend }}_{{ platform.nam
|
|||
dependencies:
|
||||
- .yamato/upm-ci-template.yml#pack_{{ project.name }}_{{ editor.version }}
|
||||
- .yamato/upm-ci-webapp.yml#pack_{{ platform.name }}
|
||||
{% endif -%}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
trigger_template_test_{{ project.name }}_{{ editor.version }}:
|
||||
name : Trigger all Template test {{ project.packagename }} {{ editor.version }}
|
||||
dependencies:
|
||||
{% for platform in platforms %}
|
||||
{% if platform.name == "win" -%}
|
||||
{% if platform.name == "win" or platform.name == "win-gpu" %}
|
||||
{% for param in platform.test_params %}
|
||||
- .yamato/upm-ci-template.yml#test_{{ project.name }}_{{ param.platform }}_{{ param.backend }}_{{ platform.name }}_{{ editor.version }}
|
||||
{% endfor %}
|
||||
{% else -%}
|
||||
{% else %}
|
||||
{% if project.name != "renderstreaming-rtx" %}
|
||||
{% for param in platform.test_params %}
|
||||
- .yamato/upm-ci-template.yml#test_{{ project.name }}_{{ param.platform }}_{{ param.backend }}_{{ platform.name }}_{{ editor.version }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif -%}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% endif -%}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
publish_{{ project.name }}:
|
||||
name: Publish {{ project.packagename }}
|
||||
agent:
|
||||
type: Unity::VM
|
||||
image: package-ci/win10:v1.21.0-1103459
|
||||
image: package-ci/win10:v4
|
||||
flavor: b1.large
|
||||
commands:
|
||||
- npm install upm-ci-utils@{{ upm.package_version }} -g --registry {{ upm.registry_url }}
|
||||
|
|
@ -143,7 +143,7 @@ publish_dryrun_{{ project.name }}:
|
|||
name: Publish Dry Run {{ project.packagename }}
|
||||
agent:
|
||||
type: Unity::VM
|
||||
image: package-ci/win10:v1.21.0-1103459
|
||||
image: package-ci/win10:v4
|
||||
flavor: b1.large
|
||||
commands:
|
||||
- npm install upm-ci-utils@{{ upm.package_version }} -g --registry {{ upm.registry_url }}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
platforms:
|
||||
- name: win
|
||||
type: Unity::VM
|
||||
image: package-ci/win10:v1.21.0-1103459
|
||||
image: package-ci/win10:v4
|
||||
flavor: b1.xlarge
|
||||
pack_command: pack_webapp.cmd
|
||||
test_command: test_webapp.cmd
|
||||
client_test_command: test_webapp_client.cmd
|
||||
- name: macos
|
||||
type: Unity::VM::osx
|
||||
image: package-ci/mac:v1.20.0-1079282
|
||||
image: package-ci/macos-12:v4.10.0-1271191
|
||||
flavor: m1.mac
|
||||
pack_command: ./pack_webapp.sh
|
||||
test_command: ./test_webapp.sh
|
||||
|
|
@ -77,11 +77,11 @@ test_client_{{ platform.name }}:
|
|||
trigger_webapp_test_{{ project.name }}:
|
||||
name : Trigger all WebApp test {{ project.packagename }}
|
||||
triggers:
|
||||
expression: pull_request.target eq "develop"
|
||||
expression: pull_request.target eq "main"
|
||||
dependencies:
|
||||
{% for platform in platforms %}
|
||||
- .yamato/upm-ci-webapp.yml#test_{{ platform.name }}
|
||||
- .yamato/upm-ci-webapp.yml#test_client_{{ platform.name }}
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
|
|
|||
16
README.md
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<img src="https://img.shields.io/badge/unity-2020.3-green.svg?style=flat-square" alt="unity 2020.3">
|
||||
<img src="https://img.shields.io/badge/unity-2021.3-green.svg?style=flat-square" alt="unity 2021.3">
|
||||
<img src="https://img.shields.io/badge/unity-2022.1-green.svg?style=flat-square" alt="unity 2022.1">
|
||||
<img src="https://img.shields.io/badge/unity-2022.2-green.svg?style=flat-square" alt="unity 2022.3">
|
||||
|
||||
**Unity Render Streaming** is a solution that provides Unity's high quality rendering abilities via browser. It's designed to meet the needs of tasks like viewing car configurators or architectural models on mobile devices.
|
||||
This solution's streaming technology takes advantage of [WebRTC](https://webrtc.org/), and developers can even use the [WebRTC package](https://docs.unity3d.com/Packages/com.unity.webrtc@latest) to create their own unique solutions.
|
||||
|
|
@ -13,13 +13,6 @@ This solution's streaming technology takes advantage of [WebRTC](https://webrtc.
|
|||
|
||||
Please see [Requirements](com.unity.renderstreaming/Documentation~/index.md#requirements) section.
|
||||
|
||||
### Furioos compatibility
|
||||
|
||||
**Unity Render Streaming** is also supported natively by **Furioos** platform https://www.furioos.com/ .
|
||||
That means that you can easily build a Unity application, upload it on **Furioos** and enjoy all the features of **Unity Render Streaming** without worrying about the deployment and scalability issues of your project.
|
||||
|
||||
Please see [Furioos Tutorial](com.unity.renderstreaming/Documentation~/deploy-to-furioos) section to find out how it works.
|
||||
|
||||
### License
|
||||
|
||||
- `com.unity.renderstreaming` - [LICENSE.md](com.unity.renderstreaming/LICENSE.md)
|
||||
|
|
@ -54,8 +47,11 @@ Please see [Furioos Tutorial](com.unity.renderstreaming/Documentation~/deploy-to
|
|||
| `3.1.0-exp.1` | - Android platform support | Jun 2021 |
|
||||
| `3.1.0-exp.2` | - Audio Renderer support <br/> - Multiplay sample <br/> - M1 Mac support | Dec 2021 |
|
||||
| `3.1.0-exp.3` | - Fix bugs | Feb 2022 |
|
||||
| `3.1.0-exp.4` | - Streaming settings API <br/> - *Unity 2022.1* support <br/> - Remove *Unity 2019.4* from support list | Sep 2022 |
|
||||
| `3.1.0-exp.5` | | Nov 2022 |
|
||||
| `3.1.0-exp.4` | - Streaming settings API <br/> - *Unity 2022.1* support <br/> - Remove *Unity 2019.4* from support list | Oct 2022 |
|
||||
| `3.1.0-exp.5` | - Fix bugs | Jan 2023 |
|
||||
| `3.1.0-exp.6` | - Streaming Settings Window <br/> - Auto Configuration <br/> - Command line option | Feb 2023 |
|
||||
| `3.1.0-exp.7` | - Fix bugs | Jul 2023 |
|
||||
| `3.1.0-exp.8` | - Fix bugs | Nov 2023 |
|
||||
|
||||
## FAQ
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"com.unity.ide.rider": "3.0.15",
|
||||
"com.unity.ide.visualstudio": "2.0.16",
|
||||
"com.unity.ide.rider": "3.0.24",
|
||||
"com.unity.ide.visualstudio": "2.0.18",
|
||||
"com.unity.ide.vscode": "1.2.5",
|
||||
"com.unity.test-framework": "1.1.33",
|
||||
"com.unity.testtools.codecoverage": "1.2.0-exp.7",
|
||||
"com.unity.testtools.codecoverage": "1.2.4",
|
||||
"com.unity.ugui": "1.0.0",
|
||||
"com.unity.xr.arcore": "4.2.3",
|
||||
"com.unity.xr.arfoundation": "4.2.3",
|
||||
"com.unity.xr.arkit": "4.2.3",
|
||||
"com.unity.xr.arcore": "5.0.6",
|
||||
"com.unity.xr.arfoundation": "5.0.6",
|
||||
"com.unity.xr.arkit": "5.0.6",
|
||||
"com.unity.xr.management": "4.3.3",
|
||||
"com.unity.modules.androidjni": "1.0.0",
|
||||
"com.unity.modules.animation": "1.0.0",
|
||||
"com.unity.modules.audio": "1.0.0",
|
||||
|
|
@ -16,10 +17,6 @@
|
|||
"com.unity.modules.physics": "1.0.0",
|
||||
"com.unity.modules.screencapture": "1.0.0",
|
||||
"com.unity.modules.ui": "1.0.0",
|
||||
"com.unity.modules.uielements": "1.0.0",
|
||||
"com.unity.modules.unitywebrequest": "1.0.0"
|
||||
},
|
||||
"testables": [
|
||||
"com.unity.inputsystem"
|
||||
]
|
||||
"com.unity.modules.uielements": "1.0.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.ide.rider": {
|
||||
"version": "3.0.15",
|
||||
"version": "3.0.24",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.ide.visualstudio": {
|
||||
"version": "2.0.16",
|
||||
"version": "2.0.18",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
|
|
@ -40,7 +40,7 @@
|
|||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.inputsystem": {
|
||||
"version": "1.4.2",
|
||||
"version": "1.7.0",
|
||||
"depth": 1,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
|
|
@ -48,13 +48,22 @@
|
|||
},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.mathematics": {
|
||||
"version": "1.2.6",
|
||||
"depth": 1,
|
||||
"source": "registry",
|
||||
"dependencies": {},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.renderstreaming": {
|
||||
"version": "file:com.unity.renderstreaming",
|
||||
"depth": 0,
|
||||
"source": "embedded",
|
||||
"dependencies": {
|
||||
"com.unity.webrtc": "2.4.0-exp.11",
|
||||
"com.unity.inputsystem": "1.4.1"
|
||||
"com.unity.webrtc": "3.0.0-pre.7",
|
||||
"com.unity.inputsystem": "1.5.1",
|
||||
"com.unity.ugui": "1.0.0",
|
||||
"com.unity.modules.screencapture": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.settings-manager": {
|
||||
|
|
@ -64,15 +73,6 @@
|
|||
"dependencies": {},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.subsystemregistration": {
|
||||
"version": "1.1.0",
|
||||
"depth": 2,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.modules.subsystems": "1.0.0"
|
||||
},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.test-framework": {
|
||||
"version": "1.1.33",
|
||||
"depth": 0,
|
||||
|
|
@ -85,7 +85,7 @@
|
|||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.testtools.codecoverage": {
|
||||
"version": "1.2.0-exp.7",
|
||||
"version": "1.2.4",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
|
|
@ -104,21 +104,23 @@
|
|||
}
|
||||
},
|
||||
"com.unity.webrtc": {
|
||||
"version": "2.4.0-exp.11",
|
||||
"version": "3.0.0-pre.7",
|
||||
"depth": 1,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.modules.jsonserialize": "1.0.0",
|
||||
"com.unity.editorcoroutines": "1.0.0"
|
||||
"com.unity.editorcoroutines": "1.0.0",
|
||||
"com.unity.modules.audio": "1.0.0"
|
||||
},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.xr.arcore": {
|
||||
"version": "4.2.3",
|
||||
"version": "5.0.6",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.xr.arsubsystems": "4.2.3",
|
||||
"com.unity.xr.arfoundation": "5.0.6",
|
||||
"com.unity.xr.core-utils": "2.1.0",
|
||||
"com.unity.xr.management": "4.0.1",
|
||||
"com.unity.modules.androidjni": "1.0.0",
|
||||
"com.unity.modules.unitywebrequest": "1.0.0"
|
||||
|
|
@ -126,40 +128,46 @@
|
|||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.xr.arfoundation": {
|
||||
"version": "4.2.3",
|
||||
"version": "5.0.6",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.xr.arsubsystems": "4.2.3",
|
||||
"com.unity.inputsystem": "1.3.0",
|
||||
"com.unity.xr.core-utils": "2.1.0",
|
||||
"com.unity.xr.management": "4.0.1",
|
||||
"com.unity.modules.particlesystem": "1.0.0"
|
||||
"com.unity.ugui": "1.0.0",
|
||||
"com.unity.mathematics": "1.2.5",
|
||||
"com.unity.modules.particlesystem": "1.0.0",
|
||||
"com.unity.modules.ui": "1.0.0",
|
||||
"com.unity.modules.unityanalytics": "1.0.0",
|
||||
"com.unity.modules.unitywebrequest": "1.0.0"
|
||||
},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.xr.arkit": {
|
||||
"version": "4.2.3",
|
||||
"version": "5.0.6",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.editorcoroutines": "1.0.0",
|
||||
"com.unity.xr.arsubsystems": "4.2.3",
|
||||
"com.unity.xr.arfoundation": "5.0.6",
|
||||
"com.unity.xr.core-utils": "2.1.0",
|
||||
"com.unity.xr.management": "4.0.1"
|
||||
},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.xr.arsubsystems": {
|
||||
"version": "4.2.3",
|
||||
"com.unity.xr.core-utils": {
|
||||
"version": "2.2.3",
|
||||
"depth": 1,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.subsystemregistration": "1.1.0",
|
||||
"com.unity.xr.management": "4.0.1"
|
||||
"com.unity.modules.xr": "1.0.0"
|
||||
},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.xr.legacyinputhelpers": {
|
||||
"version": "2.1.10",
|
||||
"depth": 2,
|
||||
"depth": 1,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.modules.vr": "1.0.0",
|
||||
|
|
@ -168,15 +176,14 @@
|
|||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.xr.management": {
|
||||
"version": "4.2.0",
|
||||
"depth": 1,
|
||||
"version": "4.3.3",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.modules.subsystems": "1.0.0",
|
||||
"com.unity.modules.vr": "1.0.0",
|
||||
"com.unity.modules.xr": "1.0.0",
|
||||
"com.unity.xr.legacyinputhelpers": "2.1.7",
|
||||
"com.unity.subsystemregistration": "1.0.6"
|
||||
"com.unity.xr.legacyinputhelpers": "2.1.7"
|
||||
},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
|
|
@ -238,7 +245,7 @@
|
|||
},
|
||||
"com.unity.modules.subsystems": {
|
||||
"version": "1.0.0",
|
||||
"depth": 2,
|
||||
"depth": 1,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.jsonserialize": "1.0.0"
|
||||
|
|
@ -271,15 +278,24 @@
|
|||
"com.unity.modules.jsonserialize": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.unityanalytics": {
|
||||
"version": "1.0.0",
|
||||
"depth": 1,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.unitywebrequest": "1.0.0",
|
||||
"com.unity.modules.jsonserialize": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.unitywebrequest": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"depth": 1,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.vr": {
|
||||
"version": "1.0.0",
|
||||
"depth": 2,
|
||||
"depth": 1,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.jsonserialize": "1.0.0",
|
||||
|
|
@ -289,7 +305,7 @@
|
|||
},
|
||||
"com.unity.modules.xr": {
|
||||
"version": "1.0.0",
|
||||
"depth": 2,
|
||||
"depth": 1,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.physics": "1.0.0",
|
||||
|
|
|
|||
|
|
@ -42,5 +42,9 @@ EditorBuildSettings:
|
|||
type: 2}
|
||||
com.unity.input.settings: {fileID: 11400000, guid: 9d3afefa5e1574ee38fb1d298122dbc7,
|
||||
type: 2}
|
||||
com.unity.renderstreaming.settings: {fileID: 11400000, guid: 039337c008e9a5c44a60f957eae3e450,
|
||||
type: 2}
|
||||
com.unity.xr.arfoundation.simulation_settings: {fileID: 11400000, guid: 0ec671069889a6541b317d5976884498,
|
||||
type: 2}
|
||||
com.unity.xr.management.loader_settings: {fileID: 11400000, guid: 66105b57eda77e74db55e7eb2b532054,
|
||||
type: 2}
|
||||
|
|
|
|||
|
|
@ -149,7 +149,6 @@ PlayerSettings:
|
|||
enable360StereoCapture: 0
|
||||
isWsaHolographicRemotingEnabled: 0
|
||||
enableFrameTimingStats: 0
|
||||
enableOpenGLProfilerGPURecorders: 1
|
||||
useHDRDisplay: 0
|
||||
D3DHDRBitDepth: 0
|
||||
m_ColorGamuts: 00000000
|
||||
|
|
@ -175,7 +174,7 @@ PlayerSettings:
|
|||
stripEngineCode: 0
|
||||
iPhoneStrippingLevel: 0
|
||||
iPhoneScriptCallOptimization: 0
|
||||
ForceInternetPermission: 0
|
||||
ForceInternetPermission: 1
|
||||
ForceSDCardPermission: 0
|
||||
CreateWallpaper: 0
|
||||
APKExpansionFiles: 0
|
||||
|
|
@ -224,7 +223,6 @@ PlayerSettings:
|
|||
iOSLaunchScreeniPadCustomStoryboardPath:
|
||||
iOSDeviceRequirements: []
|
||||
iOSURLSchemes: []
|
||||
macOSURLSchemes: []
|
||||
iOSBackgroundModes: 0
|
||||
iOSMetalForceHardShadows: 0
|
||||
metalEditorSupport: 1
|
||||
|
|
@ -449,7 +447,6 @@ PlayerSettings:
|
|||
m_BuildTargetGroupLightmapEncodingQuality: []
|
||||
m_BuildTargetGroupLightmapSettings: []
|
||||
m_BuildTargetNormalMapEncoding: []
|
||||
m_BuildTargetDefaultTextureCompressionFormat: []
|
||||
playModeTestRunnerEnabled: 0
|
||||
runPlayModeTestAsEditModeTest: 0
|
||||
actionOnDotNetUnhandledException: 1
|
||||
|
|
@ -468,7 +465,6 @@ PlayerSettings:
|
|||
switchScreenResolutionBehavior: 2
|
||||
switchUseCPUProfiler: 0
|
||||
switchUseGOLDLinker: 0
|
||||
switchLTOSetting: 0
|
||||
switchApplicationID: 0x01004b9000490000
|
||||
switchNSODependencies:
|
||||
switchTitleNames_0:
|
||||
|
|
@ -598,6 +594,7 @@ PlayerSettings:
|
|||
switchNetworkInterfaceManagerInitializeEnabled: 1
|
||||
switchPlayerConnectionEnabled: 1
|
||||
switchUseNewStyleFilepaths: 0
|
||||
switchUseLegacyFmodPriorities: 1
|
||||
switchUseMicroSleepForYield: 1
|
||||
switchEnableRamDiskSupport: 0
|
||||
switchMicroSleepForYieldTime: 25
|
||||
|
|
@ -708,6 +705,7 @@ PlayerSettings:
|
|||
suppressCommonWarnings: 1
|
||||
allowUnsafeCode: 0
|
||||
useDeterministicCompilation: 1
|
||||
useReferenceAssemblies: 1
|
||||
enableRoslynAnalyzers: 1
|
||||
additionalIl2CppArgs:
|
||||
scriptingRuntimeVersion: 1
|
||||
|
|
@ -788,6 +786,7 @@ PlayerSettings:
|
|||
m_VersionName:
|
||||
apiCompatibilityLevel: 6
|
||||
activeInputHandler: 1
|
||||
windowsGamepadBackendHint: 0
|
||||
cloudProjectId:
|
||||
framebufferDepthMemorylessMode: 0
|
||||
qualitySettingsNames: []
|
||||
|
|
@ -795,6 +794,4 @@ PlayerSettings:
|
|||
organizationId:
|
||||
cloudEnabled: 0
|
||||
legacyClampBlendShapeWeights: 0
|
||||
playerDataPath:
|
||||
forceSRGBBlit: 1
|
||||
virtualTexturingSupportEnabled: 0
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
m_EditorVersion: 2021.3.11f1
|
||||
m_EditorVersionWithRevision: 2021.3.11f1 (0a5ca18544bf)
|
||||
m_EditorVersion: 2021.3.31f1
|
||||
m_EditorVersionWithRevision: 2021.3.31f1 (3409e2af086f)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &1
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 61
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: b4f5b5e9819c4eafb84bd87d1c2f266f, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_WizardPopupAtStart: 0
|
||||
m_WizardPopupAlreadyShownOnce: 1
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ff4235c650c6444a9bfcdff2322a547a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
using UnityEditor;
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Build.Reporting;
|
||||
#if UNITY_IOS
|
||||
using UnityEditor.iOS.Xcode;
|
||||
#endif
|
||||
|
||||
class PostProcess : IPostprocessBuildWithReport
|
||||
{
|
||||
public int callbackOrder { get { return 0; } }
|
||||
|
||||
public void OnPostprocessBuild(BuildReport report)
|
||||
{
|
||||
#if UNITY_IOS
|
||||
if (report.summary.platform == BuildTarget.iOS)
|
||||
{
|
||||
string projectPath = report.summary.outputPath + "/Unity-iPhone.xcodeproj/project.pbxproj";
|
||||
|
||||
PBXProject pbxProject = new PBXProject();
|
||||
pbxProject.ReadFromFile(projectPath);
|
||||
|
||||
//Disabling Bitcode on all targets
|
||||
|
||||
//Main
|
||||
string target = pbxProject.GetUnityMainTargetGuid();
|
||||
pbxProject.SetBuildProperty(target, "ENABLE_BITCODE", "NO");
|
||||
|
||||
//Unity Tests
|
||||
target = pbxProject.TargetGuidByName(PBXProject.GetUnityTestTargetName());
|
||||
pbxProject.SetBuildProperty(target, "ENABLE_BITCODE", "NO");
|
||||
|
||||
//Unity Framework
|
||||
target = pbxProject.GetUnityFrameworkTargetGuid();
|
||||
pbxProject.SetBuildProperty(target, "ENABLE_BITCODE", "NO");
|
||||
|
||||
pbxProject.WriteToFile(projectPath);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 12f537a158c855d4fa65dd091ad15a7e
|
||||
guid: 40f483dfdb21e42c697cf1fd36e61c0c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"com.unity.renderstreaming": "file:../../../com.unity.renderstreaming",
|
||||
"com.unity.test-framework": "1.1.31",
|
||||
"com.unity.test-framework": "1.1.33",
|
||||
"com.unity.textmeshpro": "3.0.6",
|
||||
"com.unity.timeline": "1.6.4",
|
||||
"com.unity.timeline": "1.7.5",
|
||||
"com.unity.ugui": "1.0.0",
|
||||
"com.unity.modules.ai": "1.0.0",
|
||||
"com.unity.modules.androidjni": "1.0.0",
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.inputsystem": {
|
||||
"version": "1.4.2",
|
||||
"version": "1.7.0",
|
||||
"depth": 1,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
|
|
@ -28,12 +28,14 @@
|
|||
"depth": 0,
|
||||
"source": "local",
|
||||
"dependencies": {
|
||||
"com.unity.webrtc": "2.4.0-exp.11",
|
||||
"com.unity.inputsystem": "1.4.1"
|
||||
"com.unity.webrtc": "3.0.0-pre.7",
|
||||
"com.unity.inputsystem": "1.5.1",
|
||||
"com.unity.ugui": "1.0.0",
|
||||
"com.unity.modules.screencapture": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.test-framework": {
|
||||
"version": "1.1.31",
|
||||
"version": "1.1.33",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
|
|
@ -53,7 +55,7 @@
|
|||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.timeline": {
|
||||
"version": "1.6.4",
|
||||
"version": "1.7.5",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
|
|
@ -74,12 +76,13 @@
|
|||
}
|
||||
},
|
||||
"com.unity.webrtc": {
|
||||
"version": "2.4.0-exp.11",
|
||||
"version": "3.0.0-pre.7",
|
||||
"depth": 1,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.modules.jsonserialize": "1.0.0",
|
||||
"com.unity.editorcoroutines": "1.0.0"
|
||||
"com.unity.editorcoroutines": "1.0.0",
|
||||
"com.unity.modules.audio": "1.0.0"
|
||||
},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
|
|
@ -215,17 +218,6 @@
|
|||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.ui": "1.0.0",
|
||||
"com.unity.modules.imgui": "1.0.0",
|
||||
"com.unity.modules.jsonserialize": "1.0.0",
|
||||
"com.unity.modules.uielementsnative": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.uielementsnative": {
|
||||
"version": "1.0.0",
|
||||
"depth": 1,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.ui": "1.0.0",
|
||||
"com.unity.modules.imgui": "1.0.0",
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
m_EditorVersion: 2021.3.11f1
|
||||
m_EditorVersionWithRevision: 2021.3.11f1 (0a5ca18544bf)
|
||||
m_EditorVersion: 2021.3.16f1
|
||||
m_EditorVersionWithRevision: 2021.3.16f1 (4016570cf34f)
|
||||
|
|
|
|||
|
|
@ -30,17 +30,89 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame": {
|
||||
"version": "7.18.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
|
||||
"integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
|
||||
"version": "7.22.13",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
|
||||
"integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/highlight": "^7.18.6"
|
||||
"@babel/highlight": "^7.22.13",
|
||||
"chalk": "^2.4.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame/node_modules/ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-convert": "^1.9.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame/node_modules/chalk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"supports-color": "^5.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame/node_modules/color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame/node_modules/color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@babel/code-frame/node_modules/escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame/node_modules/has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame/node_modules/supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"has-flag": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/compat-data": {
|
||||
"version": "7.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.0.tgz",
|
||||
|
|
@ -90,13 +162,14 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/generator": {
|
||||
"version": "7.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.0.tgz",
|
||||
"integrity": "sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg==",
|
||||
"version": "7.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
|
||||
"integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.19.0",
|
||||
"@babel/types": "^7.23.0",
|
||||
"@jridgewell/gen-mapping": "^0.3.2",
|
||||
"@jridgewell/trace-mapping": "^0.3.17",
|
||||
"jsesc": "^2.5.1"
|
||||
},
|
||||
"engines": {
|
||||
|
|
@ -145,34 +218,34 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/helper-environment-visitor": {
|
||||
"version": "7.18.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz",
|
||||
"integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==",
|
||||
"version": "7.22.20",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
|
||||
"integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-function-name": {
|
||||
"version": "7.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz",
|
||||
"integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==",
|
||||
"version": "7.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
|
||||
"integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/template": "^7.18.10",
|
||||
"@babel/types": "^7.19.0"
|
||||
"@babel/template": "^7.22.15",
|
||||
"@babel/types": "^7.23.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-hoist-variables": {
|
||||
"version": "7.18.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz",
|
||||
"integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==",
|
||||
"version": "7.22.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
|
||||
"integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.18.6"
|
||||
"@babel/types": "^7.22.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
|
|
@ -231,30 +304,30 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/helper-split-export-declaration": {
|
||||
"version": "7.18.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz",
|
||||
"integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==",
|
||||
"version": "7.22.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
|
||||
"integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.18.6"
|
||||
"@babel/types": "^7.22.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-string-parser": {
|
||||
"version": "7.18.10",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz",
|
||||
"integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==",
|
||||
"version": "7.22.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
|
||||
"integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-validator-identifier": {
|
||||
"version": "7.18.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz",
|
||||
"integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==",
|
||||
"version": "7.22.20",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
|
||||
"integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
|
|
@ -284,13 +357,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/highlight": {
|
||||
"version": "7.18.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
|
||||
"integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
|
||||
"version": "7.22.20",
|
||||
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
|
||||
"integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-validator-identifier": "^7.18.6",
|
||||
"chalk": "^2.0.0",
|
||||
"@babel/helper-validator-identifier": "^7.22.20",
|
||||
"chalk": "^2.4.2",
|
||||
"js-tokens": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
|
|
@ -369,9 +442,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/parser": {
|
||||
"version": "7.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.0.tgz",
|
||||
"integrity": "sha512-74bEXKX2h+8rrfQUfsBfuZZHzsEs6Eql4pqy/T4Nn6Y9wNPggQOqD6z6pn5Bl8ZfysKouFZT/UXEH94ummEeQw==",
|
||||
"version": "7.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
|
||||
"integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"parser": "bin/babel-parser.js"
|
||||
|
|
@ -558,33 +631,33 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/template": {
|
||||
"version": "7.18.10",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz",
|
||||
"integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==",
|
||||
"version": "7.22.15",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
|
||||
"integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.18.6",
|
||||
"@babel/parser": "^7.18.10",
|
||||
"@babel/types": "^7.18.10"
|
||||
"@babel/code-frame": "^7.22.13",
|
||||
"@babel/parser": "^7.22.15",
|
||||
"@babel/types": "^7.22.15"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/traverse": {
|
||||
"version": "7.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.0.tgz",
|
||||
"integrity": "sha512-4pKpFRDh+utd2mbRC8JLnlsMUii3PMHjpL6a0SZ4NMZy7YFP9aXORxEhdMVOc9CpWtDF09IkciQLEhK7Ml7gRA==",
|
||||
"version": "7.23.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
|
||||
"integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.18.6",
|
||||
"@babel/generator": "^7.19.0",
|
||||
"@babel/helper-environment-visitor": "^7.18.9",
|
||||
"@babel/helper-function-name": "^7.19.0",
|
||||
"@babel/helper-hoist-variables": "^7.18.6",
|
||||
"@babel/helper-split-export-declaration": "^7.18.6",
|
||||
"@babel/parser": "^7.19.0",
|
||||
"@babel/types": "^7.19.0",
|
||||
"@babel/code-frame": "^7.22.13",
|
||||
"@babel/generator": "^7.23.0",
|
||||
"@babel/helper-environment-visitor": "^7.22.20",
|
||||
"@babel/helper-function-name": "^7.23.0",
|
||||
"@babel/helper-hoist-variables": "^7.22.5",
|
||||
"@babel/helper-split-export-declaration": "^7.22.6",
|
||||
"@babel/parser": "^7.23.0",
|
||||
"@babel/types": "^7.23.0",
|
||||
"debug": "^4.1.0",
|
||||
"globals": "^11.1.0"
|
||||
},
|
||||
|
|
@ -602,13 +675,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/types": {
|
||||
"version": "7.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.0.tgz",
|
||||
"integrity": "sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==",
|
||||
"version": "7.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
|
||||
"integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-string-parser": "^7.18.10",
|
||||
"@babel/helper-validator-identifier": "^7.18.6",
|
||||
"@babel/helper-string-parser": "^7.22.5",
|
||||
"@babel/helper-validator-identifier": "^7.22.20",
|
||||
"to-fast-properties": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
|
|
@ -1127,13 +1200,13 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/@jridgewell/trace-mapping": {
|
||||
"version": "0.3.15",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz",
|
||||
"integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==",
|
||||
"version": "0.3.20",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz",
|
||||
"integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/resolve-uri": "^3.0.3",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||
"@jridgewell/resolve-uri": "^3.1.0",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@nodelib/fs.scandir": {
|
||||
|
|
@ -1181,9 +1254,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@sideway/formula": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz",
|
||||
"integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz",
|
||||
"integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@sideway/pinpoint": {
|
||||
|
|
@ -4032,9 +4105,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/json5": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
|
||||
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
|
||||
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"json5": "lib/cli.js"
|
||||
|
|
@ -5157,9 +5230,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/tough-cookie": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz",
|
||||
"integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==",
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
|
||||
"integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"psl": "^1.1.33",
|
||||
|
|
@ -5445,9 +5518,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/word-wrap": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
|
||||
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz",
|
||||
"integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
|
|
@ -5592,12 +5665,71 @@
|
|||
}
|
||||
},
|
||||
"@babel/code-frame": {
|
||||
"version": "7.18.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
|
||||
"integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
|
||||
"version": "7.22.13",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
|
||||
"integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/highlight": "^7.18.6"
|
||||
"@babel/highlight": "^7.22.13",
|
||||
"chalk": "^2.4.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-convert": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"chalk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"supports-color": "^5.3.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
|
||||
"dev": true
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
|
||||
"dev": true
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
|
||||
"dev": true
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@babel/compat-data": {
|
||||
|
|
@ -5638,13 +5770,14 @@
|
|||
}
|
||||
},
|
||||
"@babel/generator": {
|
||||
"version": "7.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.0.tgz",
|
||||
"integrity": "sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg==",
|
||||
"version": "7.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
|
||||
"integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/types": "^7.19.0",
|
||||
"@babel/types": "^7.23.0",
|
||||
"@jridgewell/gen-mapping": "^0.3.2",
|
||||
"@jridgewell/trace-mapping": "^0.3.17",
|
||||
"jsesc": "^2.5.1"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
@ -5682,28 +5815,28 @@
|
|||
}
|
||||
},
|
||||
"@babel/helper-environment-visitor": {
|
||||
"version": "7.18.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz",
|
||||
"integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==",
|
||||
"version": "7.22.20",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
|
||||
"integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
|
||||
"dev": true
|
||||
},
|
||||
"@babel/helper-function-name": {
|
||||
"version": "7.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz",
|
||||
"integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==",
|
||||
"version": "7.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
|
||||
"integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/template": "^7.18.10",
|
||||
"@babel/types": "^7.19.0"
|
||||
"@babel/template": "^7.22.15",
|
||||
"@babel/types": "^7.23.0"
|
||||
}
|
||||
},
|
||||
"@babel/helper-hoist-variables": {
|
||||
"version": "7.18.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz",
|
||||
"integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==",
|
||||
"version": "7.22.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
|
||||
"integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/types": "^7.18.6"
|
||||
"@babel/types": "^7.22.5"
|
||||
}
|
||||
},
|
||||
"@babel/helper-module-imports": {
|
||||
|
|
@ -5747,24 +5880,24 @@
|
|||
}
|
||||
},
|
||||
"@babel/helper-split-export-declaration": {
|
||||
"version": "7.18.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz",
|
||||
"integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==",
|
||||
"version": "7.22.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
|
||||
"integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/types": "^7.18.6"
|
||||
"@babel/types": "^7.22.5"
|
||||
}
|
||||
},
|
||||
"@babel/helper-string-parser": {
|
||||
"version": "7.18.10",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz",
|
||||
"integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==",
|
||||
"version": "7.22.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
|
||||
"integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
|
||||
"dev": true
|
||||
},
|
||||
"@babel/helper-validator-identifier": {
|
||||
"version": "7.18.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz",
|
||||
"integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==",
|
||||
"version": "7.22.20",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
|
||||
"integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
|
||||
"dev": true
|
||||
},
|
||||
"@babel/helper-validator-option": {
|
||||
|
|
@ -5785,13 +5918,13 @@
|
|||
}
|
||||
},
|
||||
"@babel/highlight": {
|
||||
"version": "7.18.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
|
||||
"integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
|
||||
"version": "7.22.20",
|
||||
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
|
||||
"integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/helper-validator-identifier": "^7.18.6",
|
||||
"chalk": "^2.0.0",
|
||||
"@babel/helper-validator-identifier": "^7.22.20",
|
||||
"chalk": "^2.4.2",
|
||||
"js-tokens": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
@ -5854,9 +5987,9 @@
|
|||
}
|
||||
},
|
||||
"@babel/parser": {
|
||||
"version": "7.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.0.tgz",
|
||||
"integrity": "sha512-74bEXKX2h+8rrfQUfsBfuZZHzsEs6Eql4pqy/T4Nn6Y9wNPggQOqD6z6pn5Bl8ZfysKouFZT/UXEH94ummEeQw==",
|
||||
"version": "7.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
|
||||
"integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
|
||||
"dev": true
|
||||
},
|
||||
"@babel/plugin-syntax-async-generators": {
|
||||
|
|
@ -5986,30 +6119,30 @@
|
|||
}
|
||||
},
|
||||
"@babel/template": {
|
||||
"version": "7.18.10",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz",
|
||||
"integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==",
|
||||
"version": "7.22.15",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
|
||||
"integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.18.6",
|
||||
"@babel/parser": "^7.18.10",
|
||||
"@babel/types": "^7.18.10"
|
||||
"@babel/code-frame": "^7.22.13",
|
||||
"@babel/parser": "^7.22.15",
|
||||
"@babel/types": "^7.22.15"
|
||||
}
|
||||
},
|
||||
"@babel/traverse": {
|
||||
"version": "7.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.0.tgz",
|
||||
"integrity": "sha512-4pKpFRDh+utd2mbRC8JLnlsMUii3PMHjpL6a0SZ4NMZy7YFP9aXORxEhdMVOc9CpWtDF09IkciQLEhK7Ml7gRA==",
|
||||
"version": "7.23.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
|
||||
"integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.18.6",
|
||||
"@babel/generator": "^7.19.0",
|
||||
"@babel/helper-environment-visitor": "^7.18.9",
|
||||
"@babel/helper-function-name": "^7.19.0",
|
||||
"@babel/helper-hoist-variables": "^7.18.6",
|
||||
"@babel/helper-split-export-declaration": "^7.18.6",
|
||||
"@babel/parser": "^7.19.0",
|
||||
"@babel/types": "^7.19.0",
|
||||
"@babel/code-frame": "^7.22.13",
|
||||
"@babel/generator": "^7.23.0",
|
||||
"@babel/helper-environment-visitor": "^7.22.20",
|
||||
"@babel/helper-function-name": "^7.23.0",
|
||||
"@babel/helper-hoist-variables": "^7.22.5",
|
||||
"@babel/helper-split-export-declaration": "^7.22.6",
|
||||
"@babel/parser": "^7.23.0",
|
||||
"@babel/types": "^7.23.0",
|
||||
"debug": "^4.1.0",
|
||||
"globals": "^11.1.0"
|
||||
},
|
||||
|
|
@ -6023,13 +6156,13 @@
|
|||
}
|
||||
},
|
||||
"@babel/types": {
|
||||
"version": "7.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.0.tgz",
|
||||
"integrity": "sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==",
|
||||
"version": "7.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
|
||||
"integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/helper-string-parser": "^7.18.10",
|
||||
"@babel/helper-validator-identifier": "^7.18.6",
|
||||
"@babel/helper-string-parser": "^7.22.5",
|
||||
"@babel/helper-validator-identifier": "^7.22.20",
|
||||
"to-fast-properties": "^2.0.0"
|
||||
}
|
||||
},
|
||||
|
|
@ -6433,13 +6566,13 @@
|
|||
"dev": true
|
||||
},
|
||||
"@jridgewell/trace-mapping": {
|
||||
"version": "0.3.15",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz",
|
||||
"integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==",
|
||||
"version": "0.3.20",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz",
|
||||
"integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jridgewell/resolve-uri": "^3.0.3",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||
"@jridgewell/resolve-uri": "^3.1.0",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
}
|
||||
},
|
||||
"@nodelib/fs.scandir": {
|
||||
|
|
@ -6478,9 +6611,9 @@
|
|||
}
|
||||
},
|
||||
"@sideway/formula": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz",
|
||||
"integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz",
|
||||
"integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==",
|
||||
"dev": true
|
||||
},
|
||||
"@sideway/pinpoint": {
|
||||
|
|
@ -8638,9 +8771,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"json5": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
|
||||
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
|
||||
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
|
||||
"dev": true
|
||||
},
|
||||
"kleur": {
|
||||
|
|
@ -9456,9 +9589,9 @@
|
|||
}
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz",
|
||||
"integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==",
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
|
||||
"integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"psl": "^1.1.33",
|
||||
|
|
@ -9658,9 +9791,9 @@
|
|||
}
|
||||
},
|
||||
"word-wrap": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
|
||||
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz",
|
||||
"integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==",
|
||||
"dev": true
|
||||
},
|
||||
"wrap-ansi": {
|
||||
|
|
|
|||
|
|
@ -16,23 +16,24 @@
|
|||
<div id="warning" hidden=true></div>
|
||||
|
||||
<div id="select">
|
||||
<label for="videoSource">Video source: </label><select id="videoSource"></select>
|
||||
<label for="audioSource">Audio source: </label><select id="audioSource"></select>
|
||||
<label for="videoSource">Video source: </label>
|
||||
<select id="videoSource" autocomplete="off"></select>
|
||||
<label for="audioSource">Audio source: </label>
|
||||
<select id="audioSource" autocomplete="off"></select>
|
||||
</div>
|
||||
|
||||
<div id="resolutionSelect">
|
||||
<label for="videoResolution">Video resolution: </label><select id="videoResolution"></select>
|
||||
<label for="videoResolution">Video resolution: </label><select id="videoResolution" autocomplete="off"></select>
|
||||
</div>
|
||||
<div id="resolutionInput">
|
||||
<label for="cameraWidth">Camera width:</label><input id="cameraWidth" type="number" min="0" max="4096" disabled>
|
||||
<label for="cameraHeight">Camera height:</label><input id="cameraHeight" type="number" min="0" max="4096"
|
||||
disabled>
|
||||
<label for="cameraWidth">Camera width:</label><input id="cameraWidth" type="number" min="0" max="4096" autocomplete="off" disabled>
|
||||
<label for="cameraHeight">Camera height:</label><input id="cameraHeight" type="number" min="0" max="4096" autocomplete="off" disabled>
|
||||
</div>
|
||||
|
||||
<div id="buttons">
|
||||
<button type="button" id="startVideoButton">Start Video</button>
|
||||
<button type="button" id="setUpButton" disabled>Set Up</button>
|
||||
<button type="button" id="hangUpButton" disabled>Hang Up</button>
|
||||
<button type="button" id="startVideoButton" autocomplete="off">Start Video</button>
|
||||
<button type="button" id="setUpButton" autocomplete="off" disabled>Set Up</button>
|
||||
<button type="button" id="hangUpButton" autocomplete="off" disabled>Hang Up</button>
|
||||
</div>
|
||||
|
||||
<div id="preview">
|
||||
|
|
@ -54,7 +55,7 @@
|
|||
</div>
|
||||
<div class="box">
|
||||
<span>Codec preferences:</span>
|
||||
<select id="codecPreferences" disabled>
|
||||
<select id="codecPreferences" autocomplete="off" disabled>
|
||||
<option selected value="">Default</option>
|
||||
</select>
|
||||
</div>
|
||||
|
|
@ -75,9 +76,8 @@
|
|||
<script type="text/javascript" src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
|
||||
<script src="https://unpkg.com/event-target@latest/min.js"></script>
|
||||
<script src="https://unpkg.com/resize-observer-polyfill@1.5.0/dist/ResizeObserver.global.js"></script>
|
||||
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=IntersectionObserver"></script>
|
||||
<script type="module" src="js/main.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -58,7 +58,9 @@ const hangUpButton = document.getElementById('hangUpButton');
|
|||
hangUpButton.addEventListener('click', hangUp);
|
||||
|
||||
window.addEventListener('beforeunload', async () => {
|
||||
await sendVideo.stop();
|
||||
if(!renderstreaming)
|
||||
return;
|
||||
await renderstreaming.stop();
|
||||
}, true);
|
||||
|
||||
setupConfig();
|
||||
|
|
@ -84,7 +86,6 @@ async function startVideo() {
|
|||
cameraWidthInput.disabled = true;
|
||||
cameraHeightInput.disabled = true;
|
||||
startButton.disabled = true;
|
||||
setupButton.disabled = false;
|
||||
|
||||
let width = 0;
|
||||
let height = 0;
|
||||
|
|
@ -98,6 +99,9 @@ async function startVideo() {
|
|||
}
|
||||
|
||||
await sendVideo.startLocalVideo(videoSelect.value, audioSelect.value, width, height);
|
||||
|
||||
// enable setup button after initializing local video.
|
||||
setupButton.disabled = false;
|
||||
}
|
||||
|
||||
async function setUp() {
|
||||
|
|
@ -112,7 +116,7 @@ async function setUp() {
|
|||
renderstreaming.onConnect = () => {
|
||||
const tracks = sendVideo.getLocalTracks();
|
||||
for (const track of tracks) {
|
||||
renderstreaming.addTrack(track);
|
||||
renderstreaming.addTransceiver(track, { direction: 'sendonly' });
|
||||
}
|
||||
setCodecPreferences();
|
||||
showStatsMessage();
|
||||
|
|
@ -280,4 +284,4 @@ function clearStatsMessage() {
|
|||
remoteVideoStatsDiv.innerHTML = '';
|
||||
messageDiv.style.display = 'none';
|
||||
messageDiv.innerHTML = '';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@ export class SendVideo {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {MediaTrackConstraints} videoSource
|
||||
* @param {MediaTrackConstraints} audioSource
|
||||
* @param {number} videoWidth
|
||||
* @param {number} videoHeight
|
||||
* @param {MediaTrackConstraints} videoSource
|
||||
* @param {MediaTrackConstraints} audioSource
|
||||
* @param {number} videoWidth
|
||||
* @param {number} videoHeight
|
||||
*/
|
||||
async startLocalVideo(videoSource, audioSource, videoWidth, videoHeight) {
|
||||
try {
|
||||
|
|
@ -42,7 +42,7 @@ export class SendVideo {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {MediaStreamTrack} track
|
||||
* @param {MediaStreamTrack} track
|
||||
*/
|
||||
addRemoteTrack(track) {
|
||||
if (this.remoteVideo.srcObject == null) {
|
||||
|
|
|
|||
|
|
@ -18,12 +18,43 @@ body {
|
|||
word-break: break-word;
|
||||
}
|
||||
|
||||
button {
|
||||
margin: 20px 10px 0 0;
|
||||
width: 130px;
|
||||
}
|
||||
|
||||
button#gather {
|
||||
display: block;
|
||||
}
|
||||
|
||||
section {
|
||||
border-bottom: 1px solid #eee;
|
||||
margin: 0 0 1.5em 0;
|
||||
padding: 0 0 1.5em 0;
|
||||
}
|
||||
|
||||
section#iceServers label {
|
||||
display: inline-block;
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
section#iceServers input {
|
||||
margin: 0 0 10px;
|
||||
width: 260px;
|
||||
}
|
||||
|
||||
select {
|
||||
margin: 0 1em 1em 0;
|
||||
position: relative;
|
||||
top: -1px;
|
||||
}
|
||||
|
||||
select#servers {
|
||||
font-size: 1em;
|
||||
padding: 5px;
|
||||
width: 420px;
|
||||
}
|
||||
|
||||
section:last-child {
|
||||
border-bottom: none;
|
||||
margin: 0;
|
||||
|
|
|
|||
|
|
@ -15,9 +15,33 @@
|
|||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Server Configuration</h2>
|
||||
<div id="startup"></div>
|
||||
</section>
|
||||
|
||||
<section id="iceServers">
|
||||
<h2>ICE servers</h2>
|
||||
<select id="servers" size="4">
|
||||
</select>
|
||||
<div>
|
||||
<label for="url">STUN or TURN URI:</label>
|
||||
<input id="url">
|
||||
</div>
|
||||
<div>
|
||||
<label for="username">TURN username:</label>
|
||||
<input id="username">
|
||||
</div>
|
||||
<div>
|
||||
<label for="password">TURN password:</label>
|
||||
<input id="password">
|
||||
</div>
|
||||
<div>
|
||||
<button id="add">Add Server</button>
|
||||
<button id="remove">Remove Server</button>
|
||||
<button id="reset">Reset to defaults</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 id="receiver"><a href="receiver/index.html">Receiver Sample</a></h2>
|
||||
<p>This is a sample for receiving video / audio from Unity.</p>
|
||||
|
|
@ -50,4 +74,4 @@
|
|||
</div>
|
||||
|
||||
<script type="module" src="js/main.js"></script>
|
||||
</body>
|
||||
</body>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import {getServers} from "./icesettings.js";
|
||||
|
||||
export async function getServerConfig() {
|
||||
const protocolEndPoint = location.origin + '/config';
|
||||
const createResponse = await fetch(protocolEndPoint);
|
||||
|
|
@ -7,6 +9,6 @@ export async function getServerConfig() {
|
|||
export function getRTCConfiguration() {
|
||||
let config = {};
|
||||
config.sdpSemantics = 'unified-plan';
|
||||
config.iceServers = [{ urls: ['stun:stun.l.google.com:19302'] }];
|
||||
config.iceServers = getServers();
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,103 @@
|
|||
// This code is referenced from webrtc sample.
|
||||
// https://github.com/webrtc/samples/blob/gh-pages/src/content/peerconnection/trickle-ice/js/main.js
|
||||
|
||||
const servers = document.querySelector('select#servers');
|
||||
const urlInput = document.querySelector('input#url');
|
||||
const usernameInput = document.querySelector('input#username');
|
||||
const passwordInput = document.querySelector('input#password');
|
||||
|
||||
const allServersKey = 'servers';
|
||||
|
||||
export function addServer() {
|
||||
const scheme = urlInput.value.split(':')[0];
|
||||
if (!['stun', 'stuns', 'turn', 'turns'].includes(scheme)) {
|
||||
alert(`URI scheme ${scheme} is not valid`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Store the ICE server as a stringified JSON object in option.value.
|
||||
const option = document.createElement('option');
|
||||
const iceServer = {
|
||||
urls: [urlInput.value],
|
||||
username: usernameInput.value,
|
||||
credential: passwordInput.value
|
||||
};
|
||||
option.value = JSON.stringify(iceServer);
|
||||
option.text = `${urlInput.value} `;
|
||||
const username = usernameInput.value;
|
||||
const password = passwordInput.value;
|
||||
if (username || password) {
|
||||
option.text += (` [${username}:${password}]`);
|
||||
}
|
||||
option.ondblclick = selectServer;
|
||||
servers.add(option);
|
||||
urlInput.value = usernameInput.value = passwordInput.value = '';
|
||||
writeServersToLocalStorage();
|
||||
}
|
||||
|
||||
export function removeServer() {
|
||||
for (let i = servers.options.length - 1; i >= 0; --i) {
|
||||
if (servers.options[i].selected) {
|
||||
servers.remove(i);
|
||||
}
|
||||
}
|
||||
writeServersToLocalStorage();
|
||||
}
|
||||
|
||||
export function reset() {
|
||||
window.localStorage.clear();
|
||||
document.querySelectorAll('select#servers option').forEach(option => option.remove());
|
||||
const serversSelect = document.querySelector('select#servers');
|
||||
setDefaultServer(serversSelect);
|
||||
}
|
||||
|
||||
function selectServer(event) {
|
||||
const option = event.target;
|
||||
const value = JSON.parse(option.value);
|
||||
urlInput.value = value.urls[0];
|
||||
usernameInput.value = value.username || '';
|
||||
passwordInput.value = value.credential || '';
|
||||
}
|
||||
|
||||
function setDefaultServer(serversSelect) {
|
||||
const option = document.createElement('option');
|
||||
option.value = '{"urls":["stun:stun.l.google.com:19302"]}';
|
||||
option.text = 'stun:stun.l.google.com:19302';
|
||||
option.ondblclick = selectServer;
|
||||
serversSelect.add(option);
|
||||
}
|
||||
|
||||
function writeServersToLocalStorage() {
|
||||
const serversSelect = document.querySelector('select#servers');
|
||||
const allServers = JSON.stringify(Object.values(serversSelect.options).map(o => JSON.parse(o.value)));
|
||||
window.localStorage.setItem(allServersKey, allServers);
|
||||
}
|
||||
|
||||
export function readServersFromLocalStorage() {
|
||||
document.querySelectorAll('select#servers option').forEach(option => option.remove());
|
||||
const serversSelect = document.querySelector('select#servers');
|
||||
const storedServers = window.localStorage.getItem(allServersKey);
|
||||
|
||||
if (storedServers === null || storedServers === '') {
|
||||
setDefaultServer(serversSelect);
|
||||
} else {
|
||||
JSON.parse(storedServers).forEach((server) => {
|
||||
const o = document.createElement('option');
|
||||
o.value = JSON.stringify(server);
|
||||
o.text = server.urls[0];
|
||||
o.ondblclick = selectServer;
|
||||
serversSelect.add(o);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function getServers() {
|
||||
const storedServers = window.localStorage.getItem(allServersKey);
|
||||
|
||||
if (storedServers === null || storedServers === '') {
|
||||
return [{ urls: ['stun:stun.l.google.com:19302'] }];
|
||||
}
|
||||
else {
|
||||
return JSON.parse(storedServers);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,15 @@
|
|||
import * as Config from "./config.js";
|
||||
import {addServer, removeServer, reset, readServersFromLocalStorage} from "./icesettings.js";
|
||||
|
||||
const addButton = document.querySelector('button#add');
|
||||
const removeButton = document.querySelector('button#remove');
|
||||
const resetButton = document.querySelector('button#reset');
|
||||
const startupDiv = document.getElementById("startup");
|
||||
startupDiv.innerHTML = "<h3>Server Configuration</h3>";
|
||||
|
||||
addButton.onclick = addServer;
|
||||
removeButton.onclick = removeServer;
|
||||
resetButton.onclick = reset;
|
||||
startupDiv.innerHTML = "";
|
||||
|
||||
const displayConfig = async () => {
|
||||
const res = await Config.getServerConfig();
|
||||
|
|
@ -16,3 +24,4 @@ const displayConfig = async () => {
|
|||
};
|
||||
|
||||
displayConfig();
|
||||
readServersFromLocalStorage();
|
||||
|
|
|
|||
|
|
@ -20,14 +20,14 @@
|
|||
|
||||
<div class="box">
|
||||
<span>Codec preferences:</span>
|
||||
<select id="codecPreferences" disabled>
|
||||
<select id="codecPreferences" autocomplete="off" disabled>
|
||||
<option selected value="">Default</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<span>Lock Cursor to Player:</span>
|
||||
<input type="checkbox" id="lockMouseCheck">
|
||||
<input type="checkbox" id="lockMouseCheck" autocomplete="off" />
|
||||
</div>
|
||||
|
||||
<p>
|
||||
|
|
@ -46,9 +46,8 @@
|
|||
<script type="text/javascript" src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
|
||||
<script src="https://unpkg.com/event-target@latest/min.js"></script>
|
||||
<script src="https://unpkg.com/resize-observer-polyfill@1.5.0/dist/ResizeObserver.global.js"></script>
|
||||
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=IntersectionObserver"></script>
|
||||
<script type="module" src="js/main.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ window.addEventListener('resize', function () {
|
|||
}, true);
|
||||
|
||||
window.addEventListener('beforeunload', async () => {
|
||||
if(!renderstreaming)
|
||||
return;
|
||||
await renderstreaming.stop();
|
||||
}, true);
|
||||
|
||||
|
|
@ -198,4 +200,4 @@ function clearStatsMessage() {
|
|||
intervalId = null;
|
||||
messageDiv.style.display = 'none';
|
||||
messageDiv.innerHTML = '';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,18 +20,18 @@
|
|||
|
||||
<div class="box">
|
||||
<span>Codec preferences:</span>
|
||||
<select id="codecPreferences" disabled>
|
||||
<select id="codecPreferences" autocomplete="off" disabled>
|
||||
<option selected value="">Default</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<span>Lock Cursor to Player:</span>
|
||||
<input type="checkbox" id="lockMouseCheck">
|
||||
<input type="checkbox" id="lockMouseCheck" autocomplete="off" />
|
||||
</div>
|
||||
|
||||
<p>
|
||||
For more information about sample, see
|
||||
For more information about sample, see
|
||||
<a href="https://docs.unity3d.com/Packages/com.unity.renderstreaming@3.1/manual/sample-broadcast.html">Broadcast sample</a> document page.
|
||||
</p>
|
||||
|
||||
|
|
@ -46,9 +46,8 @@
|
|||
<script type="text/javascript" src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
|
||||
<script src="https://unpkg.com/event-target@latest/min.js"></script>
|
||||
<script src="https://unpkg.com/resize-observer-polyfill@1.5.0/dist/ResizeObserver.global.js"></script>
|
||||
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=IntersectionObserver"></script>
|
||||
<script type="module" src="js/main.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
<script type="text/javascript" src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
|
||||
<script src="https://unpkg.com/event-target@latest/min.js"></script>
|
||||
<script src="https://unpkg.com/resize-observer-polyfill@1.5.0/dist/ResizeObserver.global.js"></script>
|
||||
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=IntersectionObserver"></script>
|
||||
<script type="module" src="js/main.js"></script>
|
||||
|
||||
</body>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,109 @@
|
|||
// KeyboardEvent.charcode is already deprecated.
|
||||
//
|
||||
export const CharNumber = {
|
||||
"Backspace": 8,
|
||||
"Tab": 9,
|
||||
"Enter": 13,
|
||||
"Shift": 16,
|
||||
"Control": 17,
|
||||
"Alt": 18,
|
||||
"Pause": 19,
|
||||
"CapsLock": 20,
|
||||
"Escape": 27,
|
||||
" ": 32,
|
||||
"!": 33,
|
||||
"\"": 34,
|
||||
"#": 35,
|
||||
"$": 36,
|
||||
"%": 37,
|
||||
"&": 38,
|
||||
"'": 39,
|
||||
"(": 40,
|
||||
")": 41,
|
||||
"*": 42,
|
||||
"+": 43,
|
||||
",": 44,
|
||||
"-": 45,
|
||||
".": 46,
|
||||
"/": 47,
|
||||
"0": 48,
|
||||
"1": 49,
|
||||
"2": 50,
|
||||
"3": 51,
|
||||
"4": 52,
|
||||
"5": 53,
|
||||
"6": 54,
|
||||
"7": 55,
|
||||
"8": 56,
|
||||
"9": 57,
|
||||
":": 58,
|
||||
";": 59,
|
||||
"<": 60,
|
||||
"=": 61,
|
||||
">": 62,
|
||||
"?": 63,
|
||||
"@": 64,
|
||||
"A": 65,
|
||||
"B": 66,
|
||||
"C": 67,
|
||||
"D": 68,
|
||||
"E": 69,
|
||||
"F": 70,
|
||||
"G": 71,
|
||||
"H": 72,
|
||||
"I": 73,
|
||||
"J": 74,
|
||||
"K": 75,
|
||||
"L": 76,
|
||||
"M": 77,
|
||||
"N": 78,
|
||||
"O": 79,
|
||||
"P": 80,
|
||||
"Q": 81,
|
||||
"R": 82,
|
||||
"S": 83,
|
||||
"T": 84,
|
||||
"U": 85,
|
||||
"V": 86,
|
||||
"W": 87,
|
||||
"X": 88,
|
||||
"Y": 89,
|
||||
"Z": 90,
|
||||
"[": 91,
|
||||
"\\": 92,
|
||||
"]": 93,
|
||||
"^": 94,
|
||||
"_": 95,
|
||||
"`": 96,
|
||||
"a": 97,
|
||||
"b": 98,
|
||||
"c": 99,
|
||||
"d": 100,
|
||||
"e": 101,
|
||||
"f": 102,
|
||||
"g": 103,
|
||||
"h": 104,
|
||||
"i": 105,
|
||||
"j": 106,
|
||||
"k": 107,
|
||||
"l": 108,
|
||||
"m": 109,
|
||||
"n": 110,
|
||||
"o": 111,
|
||||
"p": 112,
|
||||
"q": 113,
|
||||
"r": 114,
|
||||
"s": 115,
|
||||
"t": 116,
|
||||
"u": 117,
|
||||
"v": 118,
|
||||
"w": 119,
|
||||
"x": 120,
|
||||
"y": 121,
|
||||
"z": 122,
|
||||
"{": 123,
|
||||
"|": 124,
|
||||
"}": 125,
|
||||
"~": 126,
|
||||
"Delete": 127
|
||||
};
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
import {
|
||||
import {
|
||||
MemoryHelper,
|
||||
} from "./memoryhelper.js";
|
||||
|
||||
import { CharNumber } from "./charnumber.js";
|
||||
import { Keymap } from "./keymap.js";
|
||||
import { MouseButton } from "./mousebutton.js";
|
||||
import { GamepadButton } from "./gamepadbutton.js";
|
||||
|
|
@ -14,16 +15,16 @@ export class FourCC {
|
|||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {String} a
|
||||
* @param {String} b
|
||||
* @param {String} c
|
||||
* @param {String} d
|
||||
*
|
||||
* @param {String} a
|
||||
* @param {String} b
|
||||
* @param {String} c
|
||||
* @param {String} d
|
||||
*/
|
||||
constructor(a, b, c, d) {
|
||||
this._code = (a.charCodeAt() << 24)
|
||||
| (b.charCodeAt() << 16)
|
||||
| (c.charCodeAt() << 8)
|
||||
this._code = (a.charCodeAt() << 24)
|
||||
| (b.charCodeAt() << 16)
|
||||
| (c.charCodeAt() << 8)
|
||||
| d.charCodeAt();
|
||||
}
|
||||
|
||||
|
|
@ -39,37 +40,37 @@ export class FourCC {
|
|||
export class InputDevice {
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* name;
|
||||
* layout;
|
||||
* deviceId;
|
||||
* variants;
|
||||
* usages;
|
||||
* description;
|
||||
*
|
||||
*
|
||||
* _inputState;
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Number} name
|
||||
* @param {String} layout
|
||||
* @param {Number} deviceId
|
||||
* @param {String} variants
|
||||
* @param {Object} description
|
||||
*
|
||||
* @param {Number} name
|
||||
* @param {String} layout
|
||||
* @param {Number} deviceId
|
||||
* @param {String[]} usages
|
||||
* @param {Object} description
|
||||
*/
|
||||
constructor(name, layout, deviceId, variants, description) {
|
||||
constructor(name, layout, deviceId, usages, description) {
|
||||
this.name = name;
|
||||
this.layout = layout;
|
||||
this.deviceId = deviceId;
|
||||
this.variants = variants;
|
||||
this.usages = usages;
|
||||
this.description = description;
|
||||
|
||||
this._inputState = null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {IInputState} state
|
||||
*
|
||||
* @param {IInputState} state
|
||||
*/
|
||||
updateState(state) {
|
||||
this._inputState = state;
|
||||
|
|
@ -78,7 +79,7 @@ export class InputDevice {
|
|||
queueEvent(event) {
|
||||
throw new Error(`Please implement this method. event:${event}`);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @returns {IInputState}
|
||||
*/
|
||||
|
|
@ -89,7 +90,7 @@ export class InputDevice {
|
|||
|
||||
export class Mouse extends InputDevice {
|
||||
/**
|
||||
* @param {(MouseEvent|WheelEvent)} event
|
||||
* @param {(MouseEvent|WheelEvent)} event
|
||||
*/
|
||||
queueEvent(event) {
|
||||
this.updateState(new MouseState(event));
|
||||
|
|
@ -99,8 +100,8 @@ export class Mouse extends InputDevice {
|
|||
export class Keyboard extends InputDevice {
|
||||
static get keycount() { return 110; }
|
||||
/**
|
||||
*
|
||||
* @param {KeyboardEvent} event
|
||||
*
|
||||
* @param {KeyboardEvent} event
|
||||
*/
|
||||
queueEvent(event) {
|
||||
this.updateState(new KeyboardState(event, this.currentState));
|
||||
|
|
@ -109,7 +110,7 @@ export class Keyboard extends InputDevice {
|
|||
|
||||
export class Touchscreen extends InputDevice {
|
||||
/**
|
||||
* @param {TouchScreenEvent} event
|
||||
* @param {TouchScreenEvent} event
|
||||
*/
|
||||
queueEvent(event, time) {
|
||||
this.updateState(new TouchscreenState(event, this.currentState, time));
|
||||
|
|
@ -118,7 +119,7 @@ export class Touchscreen extends InputDevice {
|
|||
|
||||
export class Gamepad extends InputDevice {
|
||||
/**
|
||||
* @param {GamepadButtonEvent | GamepadAxisEvent} event
|
||||
* @param {GamepadButtonEvent | GamepadAxisEvent} event
|
||||
*/
|
||||
queueEvent(event) {
|
||||
this.updateState(new GamepadState(event));
|
||||
|
|
@ -129,29 +130,29 @@ export class InputEvent {
|
|||
static get invalidEventId() { return 0; }
|
||||
static get size() { return 20; }
|
||||
|
||||
/**
|
||||
/**
|
||||
* field offset 0
|
||||
* @member {Number} type;
|
||||
*
|
||||
*
|
||||
* field offset 4
|
||||
* @member {Number} sizeInBytes;
|
||||
*
|
||||
*
|
||||
* field offset 6
|
||||
* @member {Number} deviceId;
|
||||
*
|
||||
*
|
||||
* field offset 8
|
||||
* @member {Number} time;
|
||||
*
|
||||
*
|
||||
* field offset 16
|
||||
* @member {Number} eventId;
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Number} type
|
||||
*
|
||||
* @param {Number} type
|
||||
* @param {Number} sizeInBytes
|
||||
* @param {Number} deviceId
|
||||
* @param {Number} time
|
||||
* @param {Number} deviceId
|
||||
* @param {Number} time
|
||||
*/
|
||||
constructor(type, sizeInBytes, deviceId, time) {
|
||||
this.type = type;
|
||||
|
|
@ -187,7 +188,7 @@ export class IInputState {
|
|||
* @returns {Number}
|
||||
*/
|
||||
get format() {
|
||||
throw new Error('Please implement this field');
|
||||
throw new Error('Please implement this field');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -198,29 +199,29 @@ export class MouseState extends IInputState {
|
|||
/**
|
||||
* field offset 0
|
||||
* @member {Array} position;
|
||||
*
|
||||
*
|
||||
* field offset 8
|
||||
* @member {Array} delta;
|
||||
*
|
||||
*
|
||||
* field offset 16
|
||||
* @member {Array} scroll;
|
||||
*
|
||||
*
|
||||
* field offset 24
|
||||
* @member {ArrayBuffer} buttons;
|
||||
*
|
||||
*
|
||||
* field offset 26
|
||||
* @member {Array} displayIndex;
|
||||
*
|
||||
*
|
||||
* field offset 28
|
||||
* @member {Array} clickCount;
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {MouseEvent | WheelEvent} event
|
||||
* @param {MouseEvent | WheelEvent} event
|
||||
*/
|
||||
constructor(event) {
|
||||
super();
|
||||
|
||||
|
||||
this.position = [event.clientX, event.clientY];
|
||||
this.delta = [event.movementX, -event.movementY];
|
||||
this.scroll = [0, 0];
|
||||
|
|
@ -281,7 +282,7 @@ export class KeyboardState extends IInputState {
|
|||
*/
|
||||
|
||||
/**
|
||||
* @param {KeyboardEvent} event
|
||||
* @param {KeyboardEvent} event
|
||||
*/
|
||||
constructor(event, state) {
|
||||
super();
|
||||
|
|
@ -323,7 +324,7 @@ export class KeyboardState extends IInputState {
|
|||
export class TouchState {
|
||||
static get format() { return new FourCC('T', 'O', 'U', 'C').toInt32(); }
|
||||
static get size() { return 56; }
|
||||
static incrementTouchId() {
|
||||
static incrementTouchId() {
|
||||
if(TouchState._currentTouchId === undefined) {
|
||||
TouchState._currentTouchId = 0;
|
||||
}
|
||||
|
|
@ -332,7 +333,7 @@ export class TouchState {
|
|||
static prevTouches() {
|
||||
if(TouchState._prevTouches === undefined) {
|
||||
// max touch count is 10
|
||||
TouchState._prevTouches = new Array(10);
|
||||
TouchState._prevTouches = new Array(10);
|
||||
}
|
||||
return TouchState._prevTouches;
|
||||
}
|
||||
|
|
@ -366,42 +367,24 @@ export class TouchState {
|
|||
|
||||
|
||||
/**
|
||||
* @param {Touch} touch
|
||||
* @param {TouchState} state
|
||||
* @param {String} type
|
||||
* @param {Touch} touchId
|
||||
* @param {TouchState} prevState
|
||||
* @param {Number[]} position
|
||||
* @param {Number} pressure
|
||||
* @param {Number[]} radius
|
||||
* @param {TouchPhase} phaseId
|
||||
* @param {Number} time
|
||||
*/
|
||||
constructor(touch, type, time) {
|
||||
let phaseId = TouchPhase.Stationary;
|
||||
switch(type) {
|
||||
case 'touchstart':
|
||||
phaseId = TouchPhase.Began; break;
|
||||
case 'touchend':
|
||||
phaseId = TouchPhase.Ended; break;
|
||||
case 'touchmove':
|
||||
phaseId = TouchPhase.Moved; break;
|
||||
case 'touchcancel':
|
||||
phaseId = TouchPhase.Canceled; break;
|
||||
}
|
||||
|
||||
let touchId = 0;
|
||||
let state = null;
|
||||
if(phaseId == TouchPhase.Began) {
|
||||
touchId = TouchState.incrementTouchId();
|
||||
}
|
||||
else {
|
||||
state = TouchState.prevTouches[touch.identifier];
|
||||
touchId = state.touchId;
|
||||
}
|
||||
|
||||
constructor(touchId, prevState, position, pressure, radius, phaseId, time) {
|
||||
this.touchId = touchId;
|
||||
this.position = [touch.pageX, -touch.pageY];
|
||||
this.position = position != null ? position.slice() : null;
|
||||
if(phaseId == TouchPhase.Moved) {
|
||||
this.delta = [this.position[0] - state.position[0], this.position[1] - state.position[1]];
|
||||
this.delta = [this.position[0] - prevState.position[0], this.position[1] - prevState.position[1]];
|
||||
} else {
|
||||
this.delta = [0, 0];
|
||||
}
|
||||
this.pressure = touch.force;
|
||||
this.radius = [touch.radiusX, touch.radiusY];
|
||||
this.pressure = pressure;
|
||||
this.radius = radius != null ? radius.slice(): null;
|
||||
this.phaseId = phaseId;
|
||||
this.tapCount = 0;
|
||||
this.displayIndex = 0;
|
||||
|
|
@ -411,12 +394,27 @@ export class TouchState {
|
|||
this.startTime = time;
|
||||
this.startPosition = this.position.slice();
|
||||
} else {
|
||||
this.startTime = state.startTime;
|
||||
this.startPosition = state.startPosition.slice();
|
||||
this.startTime = prevState != null ? prevState.startTime : null;
|
||||
this.startPosition = prevState != null ? prevState.startPosition.slice() : null;
|
||||
}
|
||||
}
|
||||
|
||||
// cache state
|
||||
TouchState.prevTouches[touch.identifier] = this;
|
||||
|
||||
copy() {
|
||||
let state = new TouchState();
|
||||
state.touchId = this.touchId;
|
||||
state.position = this.position.slice();
|
||||
state.delta = this.delta.slice();
|
||||
state.pressure = this.pressure;
|
||||
state.radius = this.radius.slice();
|
||||
state.phaseId = this.phaseId;
|
||||
state.tapCount = this.tapCount;
|
||||
state.displayIndex = this.displayIndex;
|
||||
state.flags = this.flags;
|
||||
state.padding = this.padding;
|
||||
state.startTime = this.startTime;
|
||||
state.startPosition = this.startPosition.slice();
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -451,12 +449,26 @@ export class TouchState {
|
|||
*/
|
||||
get format() {
|
||||
return TouchState.format;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class TouchscreenState extends IInputState {
|
||||
static get maxTouches() { return 10; }
|
||||
static get maxTouches() { return 10; }
|
||||
static get format() { return new FourCC('T', 'S', 'C', 'R').toInt32(); }
|
||||
static convertPhaseId(type) {
|
||||
let phaseId = TouchPhase.Stationary;
|
||||
switch(type) {
|
||||
case 'touchstart':
|
||||
phaseId = TouchPhase.Began; break;
|
||||
case 'touchend':
|
||||
phaseId = TouchPhase.Ended; break;
|
||||
case 'touchmove':
|
||||
phaseId = TouchPhase.Moved; break;
|
||||
case 'touchcancel':
|
||||
phaseId = TouchPhase.Canceled; break;
|
||||
}
|
||||
return phaseId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TouchEvent} event
|
||||
|
|
@ -467,6 +479,7 @@ export class TouchscreenState extends IInputState {
|
|||
super();
|
||||
|
||||
switch(event.type) {
|
||||
// `click` event is called when releasing mouse button or finger on screen.
|
||||
case 'click' : {
|
||||
this.touchData = new Array(state.touchData.length);
|
||||
for(let i = 0; i < state.touchData.length; i++) {
|
||||
|
|
@ -482,7 +495,21 @@ export class TouchscreenState extends IInputState {
|
|||
let touches = event.changedTouches;
|
||||
this.touchData = new Array(touches.length);
|
||||
for(let i = 0; i < touches.length; i++) {
|
||||
this.touchData[i] = new TouchState(touches[i], event.type, time);
|
||||
const touch = touches[i];
|
||||
const position = [touch.clientX, touch.clientY];
|
||||
const phaseId = TouchscreenState.convertPhaseId(event.type);
|
||||
const pressure = touch.force;
|
||||
const radius = [touch.radiusX, touch.radiusY];
|
||||
|
||||
// `touchId` in InputSystem must be set uniquely.
|
||||
// The numbers of `touch.identifier` in Web API are reused, so these are not unique.
|
||||
const touchId = phaseId == TouchPhase.Began ? TouchState.incrementTouchId() : TouchState.prevTouches()[touch.identifier].touchId;
|
||||
const prevState = phaseId != TouchPhase.Began ? TouchState.prevTouches()[touch.identifier] : null;
|
||||
const touchData = new TouchState(touchId, prevState, position, pressure, radius, phaseId, time);
|
||||
|
||||
// cache state
|
||||
TouchState.prevTouches()[touch.identifier] = touchData;
|
||||
this.touchData[i] = touchData;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -513,27 +540,27 @@ export class TouchscreenState extends IInputState {
|
|||
export class GamepadState extends IInputState {
|
||||
static get size() { return 28; }
|
||||
static get format() { return new FourCC('G', 'P', 'A', 'D').toInt32(); }
|
||||
|
||||
|
||||
/**
|
||||
* field offset 0
|
||||
* @member buttons;
|
||||
*
|
||||
*
|
||||
* field offset 4
|
||||
* @member leftStick;
|
||||
*
|
||||
*
|
||||
* field offset 12
|
||||
* @member rightStick;
|
||||
*
|
||||
*
|
||||
* field offset 20
|
||||
* @member leftTrigger;
|
||||
*
|
||||
*
|
||||
* field offset 24
|
||||
* @member rightTrigger;
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {GamepadButtonEvent | GamepadAxisEvent} event
|
||||
*
|
||||
* @param {GamepadButtonEvent | GamepadAxisEvent} event
|
||||
*/
|
||||
constructor(event) {
|
||||
super();
|
||||
|
|
@ -545,7 +572,7 @@ export class GamepadState extends IInputState {
|
|||
this.rightStick = [ gamepad.axes[2], -gamepad.axes[3] ];
|
||||
this.leftTrigger = buttons[6].value;
|
||||
this.rightTrigger = buttons[7].value;
|
||||
|
||||
|
||||
// see https://w3c.github.io/gamepad/#remapping
|
||||
MemoryHelper.writeSingleBit(this.buttons, GamepadButton.A, buttons[0].pressed);
|
||||
MemoryHelper.writeSingleBit(this.buttons, GamepadButton.B, buttons[1].pressed);
|
||||
|
|
@ -562,7 +589,7 @@ export class GamepadState extends IInputState {
|
|||
MemoryHelper.writeSingleBit(this.buttons, GamepadButton.DpadUp, buttons[12].pressed);
|
||||
MemoryHelper.writeSingleBit(this.buttons, GamepadButton.DpadDown, buttons[13].pressed);
|
||||
MemoryHelper.writeSingleBit(this.buttons, GamepadButton.DpadLeft, buttons[14].pressed);
|
||||
MemoryHelper.writeSingleBit(this.buttons, GamepadButton.DpadRight, buttons[15].pressed);
|
||||
MemoryHelper.writeSingleBit(this.buttons, GamepadButton.DpadRight, buttons[15].pressed);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -596,26 +623,26 @@ export class TextEvent {
|
|||
/**
|
||||
* field offset 0
|
||||
* @member {InputEvent} baseEvent;
|
||||
*
|
||||
*
|
||||
* field offset 20
|
||||
* @member {Number} character;
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Number} deviceId
|
||||
* @param {Number} character
|
||||
* @param {Number} time
|
||||
*
|
||||
* @param {Number} deviceId
|
||||
* @param {KeyboardEvent} event
|
||||
* @param {Number} time
|
||||
* @returns {TextEvent}
|
||||
|
||||
*/
|
||||
static create(deviceId, character, time) {
|
||||
static create(deviceId, event, time) {
|
||||
const eventSize = InputEvent.size + MemoryHelper.sizeOfInt;
|
||||
|
||||
let event = new TextEvent();
|
||||
event.baseEvent = new InputEvent(TextEvent.format, eventSize, deviceId, time);
|
||||
event.character = character;
|
||||
return event;
|
||||
let textEvent = new TextEvent();
|
||||
textEvent.baseEvent = new InputEvent(TextEvent.format, eventSize, deviceId, time);
|
||||
textEvent.character = CharNumber[event.key];
|
||||
return textEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -638,18 +665,18 @@ export class StateEvent {
|
|||
/**
|
||||
* field offset 0
|
||||
* @member {InputEvent} baseEvent;
|
||||
*
|
||||
*
|
||||
* field offset 20
|
||||
* @member {Number} stateFormat;
|
||||
*
|
||||
*
|
||||
* field offset 24
|
||||
* @member {ArrayBuffer} stateData;
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {InputDevice} device
|
||||
* @param {Number} time
|
||||
*
|
||||
* @param {InputDevice} device
|
||||
* @param {Number} time
|
||||
* @returns {StateEvent}
|
||||
*/
|
||||
static from(device, time) {
|
||||
|
|
@ -657,16 +684,16 @@ export class StateEvent {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {IInputState} state
|
||||
*
|
||||
* @param {IInputState} state
|
||||
* @param {Number} deviceId
|
||||
* @param {Number} time
|
||||
* @param {Number} time
|
||||
*/
|
||||
static fromState(state, deviceId, time) {
|
||||
const stateData = state.buffer;
|
||||
const stateSize = stateData.byteLength;
|
||||
const eventSize = InputEvent.size + MemoryHelper.sizeOfInt + stateSize;
|
||||
|
||||
|
||||
let stateEvent = new StateEvent();
|
||||
stateEvent.baseEvent = new InputEvent(StateEvent.format, eventSize, deviceId, time);
|
||||
stateEvent.stateFormat = state.format;
|
||||
|
|
@ -688,4 +715,4 @@ export class StateEvent {
|
|||
uint8View.set(new Uint8Array(this.stateData), InputEvent.size+MemoryHelper.sizeOfInt);
|
||||
return _buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ export default class Peer extends EventTarget {
|
|||
try {
|
||||
await this.pc.addIceCandidate(candidate);
|
||||
} catch (e) {
|
||||
if (this.pc && !this.ignoreOffer)
|
||||
if (this.pc && !this.ignoreOffer)
|
||||
this.warn(`${this.pc} this candidate can't accept current signaling state ${this.pc.signalingState}.`);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,12 +5,12 @@ export const LetterBoxType = {
|
|||
|
||||
export class PointerCorrector {
|
||||
/**
|
||||
* @param {Number} videoWidth
|
||||
* @param {Number} videoWidth
|
||||
* @param {Number} videoHeight
|
||||
* @param {DOMRect} rect
|
||||
* @param {HTMLVideoElement} videoElem
|
||||
*/
|
||||
constructor(videoWidth, videoHeight, rect) {
|
||||
this.reset(videoWidth, videoHeight, rect);
|
||||
constructor(videoWidth, videoHeight, videoElem) {
|
||||
this.reset(videoWidth, videoHeight, videoElem);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -18,14 +18,15 @@ export class PointerCorrector {
|
|||
* @returns {Number[]}
|
||||
*/
|
||||
map(position) {
|
||||
var rect = this._videoElem.getBoundingClientRect();
|
||||
const _position = new Array(2);
|
||||
|
||||
// (1) set origin point to zero
|
||||
_position[0] = position[0] - this._rect.left;
|
||||
_position[1] = position[1] - this._rect.top;
|
||||
_position[0] = position[0] - rect.left;
|
||||
_position[1] = position[1] - rect.top;
|
||||
|
||||
// (2) translate Unity coordinate system (reverse y-axis)
|
||||
_position[1] = this._rect.height - _position[1];
|
||||
_position[1] = rect.height - _position[1];
|
||||
|
||||
// (3) add offset of letterbox
|
||||
_position[0] -= this._contentRect.x;
|
||||
|
|
@ -55,42 +56,44 @@ export class PointerCorrector {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {DOMRect} rect
|
||||
* @param {HTMLVideoElement} videoElem
|
||||
*/
|
||||
setRect(rect) {
|
||||
this._rect = rect;
|
||||
setRect(videoElem) {
|
||||
this._videoElem = videoElem;
|
||||
this._reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Number} videoWidth
|
||||
* @param {Number} videoWidth
|
||||
* @param {Number} videoHeight
|
||||
* @param {DOMRect} rect
|
||||
* @param {HTMLVideoElement} videoElem
|
||||
*/
|
||||
reset(videoWidth, videoHeight, rect) {
|
||||
reset(videoWidth, videoHeight, videoElem) {
|
||||
this._videoWidth = videoWidth;
|
||||
this._videoHeight = videoHeight;
|
||||
this._rect = rect;
|
||||
this._videoElem = videoElem;
|
||||
this._reset();
|
||||
}
|
||||
|
||||
get letterBoxType() {
|
||||
const videoRatio = this._videoHeight / this._videoWidth;
|
||||
const rectRatio = this._rect.height / this._rect.width;
|
||||
var rect = this._videoElem.getBoundingClientRect();
|
||||
const rectRatio = rect.height / rect.width;
|
||||
return videoRatio > rectRatio ? LetterBoxType.Vertical : LetterBoxType.Horizontal;
|
||||
}
|
||||
|
||||
get letterBoxSize() {
|
||||
var rect = this._videoElem.getBoundingClientRect();
|
||||
switch(this.letterBoxType) {
|
||||
case LetterBoxType.Horizontal: {
|
||||
const ratioWidth = this._rect.width / this._videoWidth;
|
||||
const ratioWidth = rect.width / this._videoWidth;
|
||||
const height = this._videoHeight * ratioWidth;
|
||||
return (this._rect.height - height) * 0.5;
|
||||
return (rect.height - height) * 0.5;
|
||||
}
|
||||
case LetterBoxType.Vertical: {
|
||||
const ratioHeight = this._rect.height / this._videoHeight;
|
||||
const ratioHeight = rect.height / this._videoHeight;
|
||||
const width = this._videoWidth * ratioHeight;
|
||||
return (this._rect.width - width) * 0.5;
|
||||
return (rect.width - width) * 0.5;
|
||||
}
|
||||
}
|
||||
throw 'invalid status';
|
||||
|
|
@ -99,16 +102,18 @@ export class PointerCorrector {
|
|||
/**
|
||||
* Returns rectangle for displaying video with the origin at the left-top of the element.
|
||||
* Not considered applying CSS like `object-fit`.
|
||||
* @returns {Object}
|
||||
*/
|
||||
* @returns {Object}
|
||||
*/
|
||||
get contentRect() {
|
||||
const letterBoxType = this.letterBoxType;
|
||||
const letterBoxSize = this.letterBoxSize;
|
||||
|
||||
var rect = this._videoElem.getBoundingClientRect();
|
||||
|
||||
const x = letterBoxType == LetterBoxType.Vertical ? letterBoxSize : 0;
|
||||
const y = letterBoxType == LetterBoxType.Horizontal ? letterBoxSize : 0;
|
||||
const width = letterBoxType == LetterBoxType.Vertical ? this._rect.width - letterBoxSize * 2 : this._rect.width;
|
||||
const height = letterBoxType == LetterBoxType.Horizontal ? this._rect.height - letterBoxSize * 2 : this._rect.height;
|
||||
const width = letterBoxType == LetterBoxType.Vertical ? rect.width - letterBoxSize * 2 : rect.width;
|
||||
const height = letterBoxType == LetterBoxType.Horizontal ? rect.height - letterBoxSize * 2 : rect.height;
|
||||
|
||||
return {x: x, y: y, width: width, height: height};
|
||||
}
|
||||
|
|
@ -116,4 +121,4 @@ export class PointerCorrector {
|
|||
_reset() {
|
||||
this._contentRect = this.contentRect;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ export class RenderStreaming {
|
|||
|
||||
/**
|
||||
* if not set argument, a generated uuid is used.
|
||||
* @param {string | null} connectionId
|
||||
* @param {string | null} connectionId
|
||||
*/
|
||||
async createConnection(connectionId) {
|
||||
this._connectionId = connectionId ? connectionId : uuid4();
|
||||
|
|
@ -150,7 +150,7 @@ export class RenderStreaming {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {string} label
|
||||
* @param {string} label
|
||||
* @returns {RTCDataChannel | null}
|
||||
*/
|
||||
createDataChannel(label) {
|
||||
|
|
@ -158,13 +158,23 @@ export class RenderStreaming {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {MediaStreamTrack} track
|
||||
* @param {MediaStreamTrack} track
|
||||
* @returns {RTCRtpSender | null}
|
||||
*/
|
||||
addTrack(track) {
|
||||
return this._peer.addTrack(this._connectionId, track);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {MediaStreamTrack | string} trackOrKind
|
||||
* @param {RTCRtpTransceiverInit | null} init
|
||||
* @returns {RTCRtpTransceiver | null}
|
||||
*/
|
||||
addTransceiver(trackOrKind, init) {
|
||||
return this._peer.addTransceiver(this._connectionId, trackOrKind, init);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @returns {RTCRtpTransceiver[] | null}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import {
|
||||
import {
|
||||
Mouse,
|
||||
Keyboard,
|
||||
Gamepad,
|
||||
|
|
@ -19,7 +19,7 @@ export class Sender extends LocalInputManager {
|
|||
this._corrector = new PointerCorrector(
|
||||
this._elem.videoWidth,
|
||||
this._elem.videoHeight,
|
||||
this._elem.getBoundingClientRect()
|
||||
this._elem
|
||||
);
|
||||
|
||||
//since line 27 cannot complete resize initialization but can only monitor div dimension changes, line 26 needs to be reserved
|
||||
|
|
@ -36,9 +36,9 @@ export class Sender extends LocalInputManager {
|
|||
m_Product: "",
|
||||
m_Serial: "",
|
||||
m_Version: "",
|
||||
m_Capabilities: ""
|
||||
};
|
||||
this.mouse = new Mouse("Mouse", "Mouse", 1, "", descriptionMouse);
|
||||
m_Capabilities: ""
|
||||
};
|
||||
this.mouse = new Mouse("Mouse", "Mouse", 1, null, descriptionMouse);
|
||||
this._devices.push(this.mouse);
|
||||
|
||||
this._elem.addEventListener('click', this._onMouseEvent.bind(this), false);
|
||||
|
|
@ -56,9 +56,9 @@ export class Sender extends LocalInputManager {
|
|||
m_Product: "",
|
||||
m_Serial: "",
|
||||
m_Version: "",
|
||||
m_Capabilities: ""
|
||||
m_Capabilities: ""
|
||||
};
|
||||
this.keyboard = new Keyboard("Keyboard", "Keyboard", 2, "", descriptionKeyboard);
|
||||
this.keyboard = new Keyboard("Keyboard", "Keyboard", 2, null, descriptionKeyboard);
|
||||
this._devices.push(this.keyboard);
|
||||
|
||||
document.addEventListener('keyup', this._onKeyEvent.bind(this), false);
|
||||
|
|
@ -75,12 +75,12 @@ export class Sender extends LocalInputManager {
|
|||
m_Version: "",
|
||||
m_Capabilities: ""
|
||||
};
|
||||
this.gamepad = new Gamepad("Gamepad", "Gamepad", 3, "", descriptionGamepad);
|
||||
this.gamepad = new Gamepad("Gamepad", "Gamepad", 3, null, descriptionGamepad);
|
||||
this._devices.push(this.gamepad);
|
||||
|
||||
window.addEventListener("gamepadconnected", this._onGamepadEvent.bind(this), false);
|
||||
window.addEventListener("gamepaddisconnected", this._onGamepadEvent.bind(this), false);
|
||||
this._gamepadHandler = new GamepadHandler();
|
||||
this._gamepadHandler = new GamepadHandler();
|
||||
this._gamepadHandler.addEventListener("gamepadupdated", this._onGamepadEvent.bind(this), false);
|
||||
}
|
||||
|
||||
|
|
@ -92,9 +92,9 @@ export class Sender extends LocalInputManager {
|
|||
m_Product: "",
|
||||
m_Serial: "",
|
||||
m_Version: "",
|
||||
m_Capabilities: ""
|
||||
m_Capabilities: ""
|
||||
};
|
||||
this.touchscreen = new Touchscreen("Touchscreen", "Touchscreen", 4, "", descriptionTouch);
|
||||
this.touchscreen = new Touchscreen("Touchscreen", "Touchscreen", 4, null, descriptionTouch);
|
||||
this._devices.push(this.touchscreen);
|
||||
|
||||
this._elem.addEventListener('touchend', this._onTouchEvent.bind(this), false);
|
||||
|
|
@ -115,7 +115,7 @@ export class Sender extends LocalInputManager {
|
|||
this._corrector.reset(
|
||||
this._elem.videoWidth,
|
||||
this._elem.videoHeight,
|
||||
this._elem.getBoundingClientRect()
|
||||
this._elem
|
||||
);
|
||||
}
|
||||
_onMouseEvent(event) {
|
||||
|
|
@ -134,8 +134,7 @@ export class Sender extends LocalInputManager {
|
|||
this._queueStateEvent(this.keyboard.currentState, this.keyboard);
|
||||
}
|
||||
// TextEvent
|
||||
const key = event.key.charCodeAt(0);
|
||||
this._queueTextEvent(this.keyboard, key);
|
||||
this._queueTextEvent(this.keyboard, event);
|
||||
}
|
||||
else if(event.type == 'keyup') {
|
||||
this.keyboard.queueEvent(event);
|
||||
|
|
@ -145,7 +144,9 @@ export class Sender extends LocalInputManager {
|
|||
_onTouchEvent(event) {
|
||||
this.touchscreen.queueEvent(event, this.timeSinceStartup);
|
||||
for(let touch of this.touchscreen.currentState.touchData) {
|
||||
this._queueStateEvent(touch, this.touchscreen);
|
||||
let clone = touch.copy();
|
||||
clone.position = this._corrector.map(clone.position);
|
||||
this._queueStateEvent(clone, this.touchscreen);
|
||||
}
|
||||
}
|
||||
_onGamepadEvent(event) {
|
||||
|
|
@ -160,21 +161,21 @@ export class Sender extends LocalInputManager {
|
|||
}
|
||||
case 'gamepadupdated': {
|
||||
this.gamepad.queueEvent(event);
|
||||
this._queueStateEvent(this.gamepad.currentState, this.gamepad);
|
||||
this._queueStateEvent(this.gamepad.currentState, this.gamepad);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_queueStateEvent(state, device) {
|
||||
const stateEvent =
|
||||
const stateEvent =
|
||||
StateEvent.fromState(state, device.deviceId, this.timeSinceStartup);
|
||||
const e = new CustomEvent(
|
||||
'event', {detail: { event: stateEvent, device: device}});
|
||||
super.onEvent.dispatchEvent(e);
|
||||
}
|
||||
_queueTextEvent(device, character) {
|
||||
const textEvent = TextEvent.create(device.deviceId, character, this.timeSinceStartup);
|
||||
_queueTextEvent(device, event) {
|
||||
const textEvent = TextEvent.create(device.deviceId, event, this.timeSinceStartup);
|
||||
const e = new CustomEvent(
|
||||
'event', {detail: { event: textEvent, device: device}});
|
||||
super.onEvent.dispatchEvent(e);
|
||||
|
|
@ -188,15 +189,15 @@ export class Sender extends LocalInputManager {
|
|||
|
||||
export class Observer {
|
||||
/**
|
||||
*
|
||||
* @param {RTCDataChannel} channel
|
||||
*
|
||||
* @param {RTCDataChannel} channel
|
||||
*/
|
||||
constructor(channel) {
|
||||
this.channel = channel;
|
||||
this.channel = channel;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param {Message} message
|
||||
*
|
||||
* @param {Message} message
|
||||
*/
|
||||
onNext(message) {
|
||||
if(this.channel == null || this.channel.readyState != 'open') {
|
||||
|
|
@ -204,4 +205,4 @@ export class Observer {
|
|||
}
|
||||
this.channel.send(message.buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,9 +2,10 @@ import * as Logger from "./logger.js";
|
|||
|
||||
export class Signaling extends EventTarget {
|
||||
|
||||
constructor() {
|
||||
constructor(interval = 1000) {
|
||||
super();
|
||||
this.running = false;
|
||||
this.interval = interval;
|
||||
this.sleep = msec => new Promise(resolve => setTimeout(resolve, msec));
|
||||
}
|
||||
|
||||
|
|
@ -17,10 +18,6 @@ export class Signaling extends EventTarget {
|
|||
}
|
||||
}
|
||||
|
||||
get interval() {
|
||||
return 1000;
|
||||
}
|
||||
|
||||
url(method, parameter='') {
|
||||
let ret = location.origin + '/signaling';
|
||||
if(method)
|
||||
|
|
@ -53,9 +50,9 @@ export class Signaling extends EventTarget {
|
|||
let lastTimeRequest = Date.now() - 30000;
|
||||
while (this.running) {
|
||||
const res = await this.getAll(lastTimeRequest);
|
||||
lastTimeRequest = Date.parse(res.headers.get('Date'));
|
||||
|
||||
const data = await res.json();
|
||||
lastTimeRequest = data.datetime ? data.datetime : Date.now();
|
||||
|
||||
const messages = data.messages;
|
||||
|
||||
for(const msg of messages) {
|
||||
|
|
@ -76,94 +73,8 @@ export class Signaling extends EventTarget {
|
|||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
await this.sleep(this.interval);
|
||||
}
|
||||
}
|
||||
|
||||
async loopGetConnection() {
|
||||
let currentConnections = new Set();
|
||||
while (this.running) {
|
||||
const res = await this.getConnection();
|
||||
const data = await res.json();
|
||||
const connections = data.connections;
|
||||
Logger.log('get connections:', connections);
|
||||
|
||||
const newSet = new Set();
|
||||
connections.forEach(e => newSet.add(e.connectionId));
|
||||
const deleteConnection = new Set([...currentConnections].filter(e => (!newSet.has(e))));
|
||||
|
||||
deleteConnection.forEach(connection => {
|
||||
this.dispatchEvent(new CustomEvent('disconnect', { detail: { connectionId: connection } }));
|
||||
currentConnections.delete(connection);
|
||||
});
|
||||
|
||||
newSet.forEach(e => currentConnections.add(e));
|
||||
|
||||
await this.sleep(this.interval);
|
||||
}
|
||||
}
|
||||
|
||||
async loopGetOffer() {
|
||||
let lastTimeRequest = Date.now() - 30000;
|
||||
|
||||
while (this.running) {
|
||||
const res = await this.getOffer(lastTimeRequest);
|
||||
lastTimeRequest = Date.parse(res.headers.get('Date'));
|
||||
|
||||
const data = await res.json();
|
||||
const offers = data.offers;
|
||||
Logger.log('get offers:', offers);
|
||||
|
||||
offers.forEach(offer => {
|
||||
this.dispatchEvent(new CustomEvent('offer', { detail: offer }));
|
||||
});
|
||||
|
||||
await this.sleep(this.interval);
|
||||
}
|
||||
}
|
||||
|
||||
async loopGetAnswer() {
|
||||
// receive answer message from 30secs ago
|
||||
let lastTimeRequest = Date.now() - 30000;
|
||||
|
||||
while (this.running) {
|
||||
const res = await this.getAnswer(lastTimeRequest);
|
||||
lastTimeRequest = Date.parse(res.headers.get('Date'));
|
||||
|
||||
const data = await res.json();
|
||||
const answers = data.answers;
|
||||
Logger.log('get answers:', answers);
|
||||
|
||||
answers.forEach(answer => {
|
||||
this.dispatchEvent(new CustomEvent('answer', { detail: answer }));
|
||||
});
|
||||
|
||||
await this.sleep(this.interval);
|
||||
}
|
||||
}
|
||||
|
||||
async loopGetCandidate() {
|
||||
// receive answer message from 30secs ago
|
||||
let lastTimeRequest = Date.now() - 30000;
|
||||
|
||||
while (this.running) {
|
||||
const res = await this.getCandidate(lastTimeRequest);
|
||||
lastTimeRequest = Date.parse(res.headers.get('Date'));
|
||||
|
||||
const data = await res.json();
|
||||
const candidates = data.candidates;
|
||||
Logger.log('get candidates:', candidates);
|
||||
|
||||
if (candidates.length > 0) {
|
||||
const connectionId = candidates[0].connectionId;
|
||||
for (let candidate of candidates[0].candidates) {
|
||||
const dispatch = { connectionId: connectionId, candidate: candidate.candidate, sdpMLineIndex: candidate.sdpMLineIndex, sdpMid: candidate.sdpMid };
|
||||
this.dispatchEvent(new CustomEvent('candidate', { detail: dispatch }));
|
||||
}
|
||||
}
|
||||
|
||||
await this.sleep(this.interval);
|
||||
}
|
||||
}
|
||||
|
|
@ -215,22 +126,6 @@ export class Signaling extends EventTarget {
|
|||
await fetch(this.url('candidate'), { method: 'POST', headers: this.headers(), body: JSON.stringify(data) });
|
||||
}
|
||||
|
||||
async getConnection() {
|
||||
return await fetch(this.url(`connection`), { method: 'GET', headers: this.headers() });
|
||||
}
|
||||
|
||||
async getOffer(fromTime = 0) {
|
||||
return await fetch(this.url(`offer`, `fromtime=${fromTime}`), { method: 'GET', headers: this.headers() });
|
||||
}
|
||||
|
||||
async getAnswer(fromTime = 0) {
|
||||
return await fetch(this.url(`answer`, `fromtime=${fromTime}`), { method: 'GET', headers: this.headers() });
|
||||
}
|
||||
|
||||
async getCandidate(fromTime = 0) {
|
||||
return await fetch(this.url(`candidate`, `fromtime=${fromTime}`), { method: 'GET', headers: this.headers() });
|
||||
}
|
||||
|
||||
async getAll(fromTime = 0) {
|
||||
return await fetch(this.url(``, `fromtime=${fromTime}`), { method: 'GET', headers: this.headers() });
|
||||
}
|
||||
|
|
@ -238,8 +133,9 @@ export class Signaling extends EventTarget {
|
|||
|
||||
export class WebSocketSignaling extends EventTarget {
|
||||
|
||||
constructor() {
|
||||
constructor(interval = 1000) {
|
||||
super();
|
||||
this.interval = interval;
|
||||
this.sleep = msec => new Promise(resolve => setTimeout(resolve, msec));
|
||||
|
||||
let websocketUrl;
|
||||
|
|
@ -290,10 +186,6 @@ export class WebSocketSignaling extends EventTarget {
|
|||
};
|
||||
}
|
||||
|
||||
get interval() {
|
||||
return 100;
|
||||
}
|
||||
|
||||
async start() {
|
||||
while (!this.isWsOpen) {
|
||||
await this.sleep(100);
|
||||
|
|
@ -344,4 +236,4 @@ export class WebSocketSignaling extends EventTarget {
|
|||
Logger.log(sendJson);
|
||||
this.websocket.send(sendJson);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ export const TouchFlags =
|
|||
PrimaryTouch: 1 << 4,
|
||||
Tap: 1 << 5,
|
||||
OrphanedPrimaryTouch: 1 << 6,
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,4 +5,4 @@ export const TouchPhase = {
|
|||
Ended: 3,
|
||||
Canceled: 4,
|
||||
Stationary: 5
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
// mock class
|
||||
|
||||
export class DOMHTMLVideoElement {
|
||||
constructor(rect) {
|
||||
this.rect = rect;
|
||||
}
|
||||
|
||||
getBoundingClientRect() {
|
||||
return this.rect;
|
||||
}
|
||||
}
|
||||
|
|
@ -25,15 +25,15 @@ describe(`MouseState`, () => {
|
|||
let event;
|
||||
beforeEach(() => {
|
||||
event = new MouseEvent('click', { buttons:1, clientX:0, clientY:0});
|
||||
});
|
||||
});
|
||||
test('format', () => {
|
||||
const format = new MouseState(event).format;
|
||||
expect(format).toBe(0x4d4f5553);
|
||||
});
|
||||
});
|
||||
test('buffer', () => {
|
||||
const state = new MouseState(event);
|
||||
expect(state.buffer.byteLength).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe(`with WheelEvent`, () => {
|
||||
let event;
|
||||
|
|
@ -43,11 +43,11 @@ describe(`MouseState`, () => {
|
|||
test('format', () => {
|
||||
const format = new MouseState(event).format;
|
||||
expect(format).toBe(0x4d4f5553);
|
||||
});
|
||||
});
|
||||
test('buffer', () => {
|
||||
const state = new MouseState(event);
|
||||
expect(state.buffer.byteLength).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ describe(`KeyboardState`, () => {
|
|||
test('format', () => {
|
||||
const format = new KeyboardState(event).format;
|
||||
expect(format).toBe(0x4b455953);
|
||||
});
|
||||
});
|
||||
test('buffer', () => {
|
||||
const state = new KeyboardState(event);
|
||||
expect(state.buffer.byteLength).toBeGreaterThan(0);
|
||||
|
|
@ -69,7 +69,7 @@ describe(`KeyboardState`, () => {
|
|||
describe(`TouchscreenState`, () => {
|
||||
let event;
|
||||
beforeEach(() => {
|
||||
event = new TouchEvent("touchstart", {
|
||||
event = new TouchEvent("touchstart", {
|
||||
changedTouches: [{ // InputInit
|
||||
identifier: 0,
|
||||
target: null,
|
||||
|
|
@ -88,7 +88,7 @@ describe(`TouchscreenState`, () => {
|
|||
touchType: "direct"
|
||||
}]
|
||||
});
|
||||
});
|
||||
});
|
||||
test('format', () => {
|
||||
const format = new TouchscreenState(event, null, Date.now()).format;
|
||||
expect(format).toBe(0x54534352);
|
||||
|
|
@ -113,7 +113,7 @@ describe(`GamepadState`, () => {
|
|||
test('format', () => {
|
||||
const format = new GamepadState(event).format;
|
||||
expect(format).toBe(0x47504144);
|
||||
});
|
||||
});
|
||||
test('buffer', () => {
|
||||
const state = new GamepadState(event);
|
||||
expect(state.buffer.byteLength).toBeGreaterThan(0);
|
||||
|
|
@ -134,14 +134,15 @@ describe(`StateEvent`, () => {
|
|||
|
||||
describe(`TextEvent`, () => {
|
||||
test('buffer', () => {
|
||||
const character = 0x41;
|
||||
const textEvent = TextEvent.create(0, character, Date.now());
|
||||
const event = new KeyboardEvent('keydown', { code: 'KeyA', key: "a"});
|
||||
const textEvent = TextEvent.create(0, event, Date.now());
|
||||
expect(new Int32Array(textEvent.buffer.slice(0, 4))[0]).toBe(TextEvent.format);
|
||||
const offset = InputEvent.size;
|
||||
expect(new Uint32Array(textEvent.buffer.slice(offset, offset+4))[0]).toBe(character);
|
||||
// 'a' is 97
|
||||
expect(new Uint32Array(textEvent.buffer.slice(offset, offset+4))[0]).toBe(97);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe(`Mouse`, () => {
|
||||
test('alignedSizeInBytes', () => {
|
||||
let device = new Mouse("Mouse", "Mouse", 1, null, null);
|
||||
|
|
@ -168,4 +169,4 @@ describe(`Gamepad`, () => {
|
|||
let device = new Gamepad("Gamepad", "Gamepad", 1, null, null);
|
||||
expect(device).toBeInstanceOf(Gamepad);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -9,8 +9,9 @@ export function reset(isPrivate) {
|
|||
|
||||
export class MockSignaling extends EventTarget {
|
||||
|
||||
get interval() {
|
||||
return 100;
|
||||
constructor(interval = 1000) {
|
||||
super();
|
||||
this.interval = interval;
|
||||
}
|
||||
|
||||
async start() {
|
||||
|
|
@ -115,7 +116,7 @@ class MockPrivateSignalingManager {
|
|||
constructor() {
|
||||
// structure Map<string:connectionId, Set<MockSignaling>> connectionIds
|
||||
this.connectionIds = new Map();
|
||||
this.delay = () => new Promise(resolve => setTimeout(resolve, 10));
|
||||
this.delay = async () => await sleep(10);
|
||||
}
|
||||
|
||||
async add(signaling) {
|
||||
|
|
|
|||
|
|
@ -1,26 +1,30 @@
|
|||
import {
|
||||
import {
|
||||
LetterBoxType,
|
||||
PointerCorrector
|
||||
} from "../src/pointercorrect.js";
|
||||
|
||||
import {DOMRect} from "./domrect.js";
|
||||
import {DOMHTMLVideoElement} from "./domvideoelement.js";
|
||||
|
||||
describe(`PointerCorrector.map`, () => {
|
||||
test('letterboxType', () => {
|
||||
const rect = new DOMRect(10, 10, 200, 200);
|
||||
let corrector = new PointerCorrector(50, 100, rect);
|
||||
const element = new DOMHTMLVideoElement(rect);
|
||||
let corrector = new PointerCorrector(50, 100, element);
|
||||
expect(corrector.letterBoxType).toBe(LetterBoxType.Vertical);
|
||||
corrector.reset(100, 50, rect);
|
||||
corrector.reset(100, 50, element);
|
||||
expect(corrector.letterBoxType).toBe(LetterBoxType.Horizontal);
|
||||
});
|
||||
test('letterboxSize', () => {
|
||||
const rect = new DOMRect(0, 0, 100, 100);
|
||||
let corrector = new PointerCorrector(50, 100, rect);
|
||||
const element = new DOMHTMLVideoElement(rect);
|
||||
let corrector = new PointerCorrector(50, 100, element);
|
||||
expect(corrector.letterBoxSize).toBe(25);
|
||||
});
|
||||
test('contentRect', () => {
|
||||
const rect = new DOMRect(0, 0, 100, 100);
|
||||
let corrector = new PointerCorrector(50, 100, rect);
|
||||
const element = new DOMHTMLVideoElement(rect);
|
||||
let corrector = new PointerCorrector(50, 100, element);
|
||||
expect(corrector.contentRect.x).toBe(25);
|
||||
expect(corrector.contentRect.y).toBe(0);
|
||||
expect(corrector.contentRect.width).toBe(50);
|
||||
|
|
@ -28,13 +32,14 @@ describe(`PointerCorrector.map`, () => {
|
|||
});
|
||||
test('mapping', () => {
|
||||
const rect = new DOMRect(10, 10, 200, 200);
|
||||
const element = new DOMHTMLVideoElement(rect);
|
||||
const videoWidth = 100;
|
||||
const videoHeight = 100;
|
||||
let corrector = new PointerCorrector(videoWidth, videoHeight, rect);
|
||||
let corrector = new PointerCorrector(videoWidth, videoHeight, element);
|
||||
const position = [10, 10];
|
||||
const newPosition = corrector.map(position);
|
||||
expect(newPosition[0]).toBe(0);
|
||||
expect(newPosition[1]).toBe(100);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -23,25 +23,25 @@ describe.each([
|
|||
beforeAll(async () => {
|
||||
if (mode == "mock") {
|
||||
reset(false);
|
||||
signaling1 = new MockSignaling();
|
||||
signaling2 = new MockSignaling();
|
||||
signaling1 = new MockSignaling(1);
|
||||
signaling2 = new MockSignaling(1);
|
||||
} else {
|
||||
const path = Path.resolve(`../bin~/${serverExeName()}`);
|
||||
let cmd = `${path} -p ${portNumber}`;
|
||||
if (mode == "websocket") {
|
||||
cmd += " -w";
|
||||
if (mode == "http") {
|
||||
cmd += " -t http";
|
||||
}
|
||||
|
||||
await setup({ command: cmd, port: portNumber, usedPortAction: 'error' });
|
||||
|
||||
if (mode == "http") {
|
||||
signaling1 = new Signaling();
|
||||
signaling2 = new Signaling();
|
||||
signaling1 = new Signaling(1);
|
||||
signaling2 = new Signaling(1);
|
||||
}
|
||||
|
||||
if (mode == "websocket") {
|
||||
signaling1 = new WebSocketSignaling();
|
||||
signaling2 = new WebSocketSignaling();
|
||||
signaling1 = new WebSocketSignaling(1);
|
||||
signaling2 = new WebSocketSignaling(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -221,27 +221,27 @@ describe.each([
|
|||
beforeAll(async () => {
|
||||
if (mode == "mock") {
|
||||
reset(true);
|
||||
signaling1 = new MockSignaling();
|
||||
signaling2 = new MockSignaling();
|
||||
signaling1 = new MockSignaling(1);
|
||||
signaling2 = new MockSignaling(1);
|
||||
return;
|
||||
}
|
||||
|
||||
const path = Path.resolve(`../bin~/${serverExeName()}`);
|
||||
let cmd = `${path} -p ${portNumber} -m private`;
|
||||
if (mode == "websocket") {
|
||||
cmd += " -w";
|
||||
if (mode == "http") {
|
||||
cmd += " -t http";
|
||||
}
|
||||
|
||||
await setup({ command: cmd, port: portNumber, usedPortAction: 'error' });
|
||||
|
||||
if (mode == "http") {
|
||||
signaling1 = new Signaling();
|
||||
signaling2 = new Signaling();
|
||||
signaling1 = new Signaling(1);
|
||||
signaling2 = new Signaling(1);
|
||||
}
|
||||
|
||||
if (mode == "websocket") {
|
||||
signaling1 = new WebSocketSignaling();
|
||||
signaling2 = new WebSocketSignaling();
|
||||
signaling1 = new WebSocketSignaling(1);
|
||||
signaling2 = new WebSocketSignaling(1);
|
||||
}
|
||||
|
||||
await signaling1.start();
|
||||
|
|
@ -455,6 +455,7 @@ describe.each([
|
|||
signaling1.addEventListener('offer', (e) => offerRes1 = e.detail);
|
||||
signaling2.addEventListener('offer', (e) => offerRes2 = e.detail);
|
||||
await signaling1.sendOffer(connectionId, testsdp);
|
||||
await waitFor(() => offerRes2 != null);
|
||||
await sleep(signaling1.interval * 2);
|
||||
expect(offerRes1).toBeUndefined();
|
||||
expect(offerRes2).not.toBeUndefined();
|
||||
|
|
@ -464,6 +465,7 @@ describe.each([
|
|||
signaling1.addEventListener('answer', (e) => answerRes1 = e.detail);
|
||||
signaling2.addEventListener('answer', (e) => answerRes2 = e.detail);
|
||||
await signaling2.sendAnswer(connectionId, testsdp);
|
||||
await waitFor(() => answerRes1 != null);
|
||||
await sleep(signaling2.interval * 2);
|
||||
expect(answerRes1).not.toBeUndefined();
|
||||
expect(answerRes1.connectionId).toBe(connectionId);
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
"@types/express": "^4.17.13",
|
||||
"@types/node": "^18.7.15",
|
||||
"@types/ws": "^8.5.3",
|
||||
"cors": "^2.8.5",
|
||||
"debug": "~4.3.4",
|
||||
"express": "~4.18.1",
|
||||
"morgan": "^1.10.0",
|
||||
|
|
@ -23,7 +24,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@jest-mock/express": "^2.0.1",
|
||||
"@types/jest": "^29.0.0",
|
||||
"@types/jest": "^29.0.2",
|
||||
"@types/morgan": "^1.9.3",
|
||||
"@typescript-eslint/eslint-plugin": "^5.36.2",
|
||||
"@typescript-eslint/parser": "^5.36.2",
|
||||
|
|
@ -32,9 +33,9 @@
|
|||
"jest": "^29.0.2",
|
||||
"jest-websocket-mock": "^2.4.0",
|
||||
"mock-socket": "^9.1.5",
|
||||
"newman": "^5.3.2",
|
||||
"newman": "^6.0.0",
|
||||
"pkg": "^5.8.0",
|
||||
"ts-jest": "^28.0.8",
|
||||
"ts-jest": "^29.0.2",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^4.8.2"
|
||||
},
|
||||
|
|
@ -43,7 +44,8 @@
|
|||
},
|
||||
"pkg": {
|
||||
"assets": [
|
||||
"client/public/**/*"
|
||||
"client/public/**/*",
|
||||
"client/src/**/*"
|
||||
],
|
||||
"targets": [
|
||||
"node10"
|
||||
|
|
|
|||
|
|
@ -68,11 +68,11 @@ function checkSessionId(req: Request, res: Response, next): void {
|
|||
res.sendStatus(404);
|
||||
return;
|
||||
}
|
||||
lastRequestedTime[id] = Date.now();
|
||||
lastRequestedTime.set(id, Date.now());
|
||||
next();
|
||||
}
|
||||
|
||||
function _deleteConnection(sessionId:string, connectionId:string) {
|
||||
function _deleteConnection(sessionId:string, connectionId:string, datetime:number) {
|
||||
clients.get(sessionId).delete(connectionId);
|
||||
|
||||
if(isPrivate) {
|
||||
|
|
@ -83,7 +83,7 @@ function _deleteConnection(sessionId:string, connectionId:string) {
|
|||
if (clients.has(otherSessionId)) {
|
||||
clients.get(otherSessionId).delete(connectionId);
|
||||
const array1 = disconnections.get(otherSessionId);
|
||||
array1.push(new Disconnection(connectionId, Date.now()));
|
||||
array1.push(new Disconnection(connectionId, datetime));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -91,7 +91,7 @@ function _deleteConnection(sessionId:string, connectionId:string) {
|
|||
disconnections.forEach((array, id) => {
|
||||
if (id == sessionId)
|
||||
return;
|
||||
array.push(new Disconnection(connectionId, Date.now()));
|
||||
array.push(new Disconnection(connectionId, datetime));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -101,12 +101,14 @@ function _deleteConnection(sessionId:string, connectionId:string) {
|
|||
candidates.get(sessionId).delete(connectionId);
|
||||
|
||||
const array2 = disconnections.get(sessionId);
|
||||
array2.push(new Disconnection(connectionId, Date.now()));
|
||||
array2.push(new Disconnection(connectionId, datetime));
|
||||
}
|
||||
|
||||
function _deleteSession(sessionId: string) {
|
||||
for(const connectionId of Array.from(clients.get(sessionId))) {
|
||||
_deleteConnection(sessionId, connectionId);
|
||||
if(clients.has(sessionId)) {
|
||||
for(const connectionId of Array.from(clients.get(sessionId))) {
|
||||
_deleteConnection(sessionId, connectionId, Date.now());
|
||||
}
|
||||
}
|
||||
offers.delete(sessionId);
|
||||
answers.delete(sessionId);
|
||||
|
|
@ -115,37 +117,32 @@ function _deleteSession(sessionId: string) {
|
|||
disconnections.delete(sessionId);
|
||||
}
|
||||
|
||||
function _checkDeletedSession(sessionId: string): void {
|
||||
const connectionIds = Array.from(clients.get(sessionId));
|
||||
for (const connectionId of connectionIds) {
|
||||
const pair = connectionPair.get(connectionId);
|
||||
if (pair == null) {
|
||||
function _checkForTimedOutSessions(): void {
|
||||
for (const sessionId of Array.from(clients.keys()))
|
||||
{
|
||||
if(!lastRequestedTime.has(sessionId))
|
||||
continue;
|
||||
}
|
||||
const otherSessionId = sessionId === pair[0] ? pair[1] : pair[0];
|
||||
if(!lastRequestedTime.has(otherSessionId))
|
||||
if(lastRequestedTime.get(sessionId) > Date.now() - TimeoutRequestedTime)
|
||||
continue;
|
||||
if(lastRequestedTime[otherSessionId] > Date.now() - TimeoutRequestedTime)
|
||||
continue;
|
||||
_deleteSession(otherSessionId);
|
||||
console.log("deleted");
|
||||
_deleteSession(sessionId);
|
||||
console.log(`deleted sessionId:${sessionId} by timeout.`);
|
||||
}
|
||||
}
|
||||
|
||||
function _getConnection(sessionId: string): string[] {
|
||||
_checkDeletedSession(sessionId);
|
||||
function _getConnection(sessionId: string): string[] {
|
||||
_checkForTimedOutSessions();
|
||||
return Array.from(clients.get(sessionId));
|
||||
}
|
||||
|
||||
function _getDisconnection(sessionId: string, fromTime: number): Disconnection[] {
|
||||
_checkDeletedSession(sessionId);
|
||||
_checkForTimedOutSessions();
|
||||
let arrayDisconnections: Disconnection[] = [];
|
||||
if (disconnections.size != 0 && disconnections.has(sessionId)) {
|
||||
arrayDisconnections = disconnections.get(sessionId);
|
||||
}
|
||||
|
||||
if (fromTime > 0) {
|
||||
arrayDisconnections = arrayDisconnections.filter((v) => v.datetime > fromTime);
|
||||
arrayDisconnections = arrayDisconnections.filter((v) => v.datetime >= fromTime);
|
||||
}
|
||||
return arrayDisconnections;
|
||||
}
|
||||
|
|
@ -165,7 +162,7 @@ function _getOffer(sessionId: string, fromTime: number): [string, Offer][] {
|
|||
}
|
||||
|
||||
if (fromTime > 0) {
|
||||
arrayOffers = arrayOffers.filter((v) => v[1].datetime > fromTime);
|
||||
arrayOffers = arrayOffers.filter((v) => v[1].datetime >= fromTime);
|
||||
}
|
||||
return arrayOffers;
|
||||
}
|
||||
|
|
@ -178,7 +175,7 @@ function _getAnswer(sessionId: string, fromTime: number): [string, Answer][] {
|
|||
}
|
||||
|
||||
if (fromTime > 0) {
|
||||
arrayAnswers = arrayAnswers.filter((v) => v[1].datetime > fromTime);
|
||||
arrayAnswers = arrayAnswers.filter((v) => v[1].datetime >= fromTime);
|
||||
}
|
||||
return arrayAnswers;
|
||||
}
|
||||
|
|
@ -196,7 +193,7 @@ function _getCandidate(sessionId: string, fromTime: number): [string, Candidate]
|
|||
continue;
|
||||
}
|
||||
const arrayCandidates = candidates.get(otherSessionId).get(connectionId)
|
||||
.filter((v) => v.datetime > fromTime);
|
||||
.filter((v) => v.datetime >= fromTime);
|
||||
if (arrayCandidates.length === 0) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -246,17 +243,18 @@ function getAll(req: Request, res: Response): void {
|
|||
const answers: [string, Answer][] = _getAnswer(sessionId, fromTime);
|
||||
const candidates: [string, Candidate][] = _getCandidate(sessionId, fromTime);
|
||||
const disconnections: Disconnection[] = _getDisconnection(sessionId, fromTime);
|
||||
const datetime = lastRequestedTime.get(sessionId);
|
||||
|
||||
let array: any[] = [];
|
||||
|
||||
array = array.concat(connections.map((v) => ({ connectionId: v, type: "connect", datetime: Date.now() })));
|
||||
array = array.concat(connections.map((v) => ({ connectionId: v, type: "connect", datetime: datetime })));
|
||||
array = array.concat(offers.map((v) => ({ connectionId: v[0], sdp: v[1].sdp, polite: v[1].polite, type: "offer", datetime: v[1].datetime })));
|
||||
array = array.concat(answers.map((v) => ({ connectionId: v[0], sdp: v[1].sdp, type: "answer", datetime: v[1].datetime })));
|
||||
array = array.concat(candidates.map((v) => ({ connectionId: v[0], candidate: v[1].candidate, sdpMLineIndex: v[1].sdpMLineIndex, sdpMid: v[1].sdpMid, type: "candidate", datetime: v[1].datetime })));
|
||||
array = array.concat(disconnections.map((v) => ({ connectionId: v.id, type: "disconnect", datetime: v.datetime })));
|
||||
|
||||
array.sort((a, b) => a.datetime - b.datetime);
|
||||
res.json({ messages: array });
|
||||
res.json({ messages: array, datetime: datetime });
|
||||
}
|
||||
|
||||
function createSession(sessionId: string, res: Response): void;
|
||||
|
|
@ -281,6 +279,8 @@ function deleteSession(req: Request, res: Response): void {
|
|||
function createConnection(req: Request, res: Response): void {
|
||||
const sessionId: string = req.header('session-id');
|
||||
const { connectionId } = req.body;
|
||||
const datetime = lastRequestedTime.get(sessionId);
|
||||
|
||||
if (connectionId == null) {
|
||||
res.status(400).send({ error: new Error(`connectionId is required`) });
|
||||
return;
|
||||
|
|
@ -308,14 +308,15 @@ function createConnection(req: Request, res: Response): void {
|
|||
|
||||
const connectionIds = getOrCreateConnectionIds(sessionId);
|
||||
connectionIds.add(connectionId);
|
||||
res.json({ connectionId: connectionId, polite: polite, type: "connect", datetime: Date.now() });
|
||||
res.json({ connectionId: connectionId, polite: polite, type: "connect", datetime: datetime });
|
||||
}
|
||||
|
||||
function deleteConnection(req: Request, res: Response): void {
|
||||
const sessionId: string = req.header('session-id');
|
||||
const { connectionId } = req.body;
|
||||
const datetime = lastRequestedTime.get(sessionId);
|
||||
|
||||
_deleteConnection(sessionId, connectionId);
|
||||
_deleteConnection(sessionId, connectionId, datetime);
|
||||
|
||||
res.json({ connectionId: connectionId });
|
||||
}
|
||||
|
|
@ -323,6 +324,7 @@ function deleteConnection(req: Request, res: Response): void {
|
|||
function postOffer(req: Request, res: Response): void {
|
||||
const sessionId: string = req.header('session-id');
|
||||
const { connectionId } = req.body;
|
||||
const datetime = lastRequestedTime.get(sessionId);
|
||||
let keySessionId = null;
|
||||
let polite = false;
|
||||
|
||||
|
|
@ -333,17 +335,21 @@ function postOffer(req: Request, res: Response): void {
|
|||
if (keySessionId != null) {
|
||||
polite = true;
|
||||
const map = offers.get(keySessionId);
|
||||
map.set(connectionId, new Offer(req.body.sdp, Date.now(), polite));
|
||||
map.set(connectionId, new Offer(req.body.sdp, datetime, polite));
|
||||
}
|
||||
}
|
||||
res.sendStatus(200);
|
||||
return;
|
||||
}
|
||||
|
||||
connectionPair.set(connectionId, [sessionId, null]);
|
||||
if(!connectionPair.has(connectionId))
|
||||
{
|
||||
connectionPair.set(connectionId, [sessionId, null]);
|
||||
}
|
||||
|
||||
keySessionId = sessionId;
|
||||
const map = offers.get(keySessionId);
|
||||
map.set(connectionId, new Offer(req.body.sdp, Date.now(), polite));
|
||||
map.set(connectionId, new Offer(req.body.sdp, datetime, polite));
|
||||
|
||||
res.sendStatus(200);
|
||||
}
|
||||
|
|
@ -351,6 +357,7 @@ function postOffer(req: Request, res: Response): void {
|
|||
function postAnswer(req: Request, res: Response): void {
|
||||
const sessionId: string = req.header('session-id');
|
||||
const { connectionId } = req.body;
|
||||
const datetime = lastRequestedTime.get(sessionId);
|
||||
const connectionIds = getOrCreateConnectionIds(sessionId);
|
||||
connectionIds.add(connectionId);
|
||||
|
||||
|
|
@ -373,7 +380,7 @@ function postAnswer(req: Request, res: Response): void {
|
|||
}
|
||||
|
||||
const map = answers.get(otherSessionId);
|
||||
map.set(connectionId, new Answer(req.body.sdp, Date.now()));
|
||||
map.set(connectionId, new Answer(req.body.sdp, datetime));
|
||||
|
||||
// update datetime for candidates
|
||||
const mapCandidates = candidates.get(otherSessionId);
|
||||
|
|
@ -381,7 +388,7 @@ function postAnswer(req: Request, res: Response): void {
|
|||
const arrayCandidates = mapCandidates.get(connectionId);
|
||||
if (arrayCandidates) {
|
||||
for (const candidate of arrayCandidates) {
|
||||
candidate.datetime = Date.now();
|
||||
candidate.datetime = datetime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -391,13 +398,14 @@ function postAnswer(req: Request, res: Response): void {
|
|||
function postCandidate(req: Request, res: Response): void {
|
||||
const sessionId: string = req.header('session-id');
|
||||
const { connectionId } = req.body;
|
||||
const datetime = lastRequestedTime.get(sessionId);
|
||||
|
||||
const map = candidates.get(sessionId);
|
||||
if (!map.has(connectionId)) {
|
||||
map.set(connectionId, []);
|
||||
}
|
||||
const arr = map.get(connectionId);
|
||||
const candidate = new Candidate(req.body.candidate, req.body.sdpMLineIndex, req.body.sdpMid, Date.now());
|
||||
const candidate = new Candidate(req.body.candidate, req.body.sdpMLineIndex, req.body.sdpMid, datetime);
|
||||
arr.push(candidate);
|
||||
res.sendStatus(200);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ export default interface Options {
|
|||
port?: number;
|
||||
keyfile?: string;
|
||||
certfile?: string;
|
||||
websocket?: boolean;
|
||||
type?: string;
|
||||
mode?: string;
|
||||
logging?: string;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,13 +16,13 @@ export class RenderStreaming {
|
|||
if (Array.isArray(argv)) {
|
||||
program
|
||||
.usage('[options] <apps...>')
|
||||
.option('-p, --port <n>', 'Port to start the server on', process.env.PORT || `80`)
|
||||
.option('-s, --secure', 'Enable HTTPS (you need server.key and server.cert)', process.env.SECURE || false)
|
||||
.option('-k, --keyfile <path>', 'https key file (default server.key)', process.env.KEYFILE || 'server.key')
|
||||
.option('-c, --certfile <path>', 'https cert file (default server.cert)', process.env.CERTFILE || 'server.cert')
|
||||
.option('-w, --websocket', 'Enable Websocket Signaling', process.env.WEBSOCKET || false)
|
||||
.option('-m, --mode <type>', 'Choose Communication mode public or private (default public)', process.env.MODE || 'public')
|
||||
.option('-l, --logging <type>', 'Choose http logging type combined, dev, short, tiny or none.(default dev)', process.env.LOGGING || 'dev')
|
||||
.option('-p, --port <n>', 'Port to start the server on.', process.env.PORT || `80`)
|
||||
.option('-s, --secure', 'Enable HTTPS (you need server.key and server.cert).', process.env.SECURE || false)
|
||||
.option('-k, --keyfile <path>', 'https key file.', process.env.KEYFILE || 'server.key')
|
||||
.option('-c, --certfile <path>', 'https cert file.', process.env.CERTFILE || 'server.cert')
|
||||
.option('-t, --type <type>', 'Type of signaling protocol, Choose websocket or http.', process.env.TYPE || 'websocket')
|
||||
.option('-m, --mode <type>', 'Choose Communication mode public or private.', process.env.MODE || 'public')
|
||||
.option('-l, --logging <type>', 'Choose http logging type combined, dev, short, tiny or none.', process.env.LOGGING || 'dev')
|
||||
.parse(argv);
|
||||
const option = program.opts();
|
||||
return {
|
||||
|
|
@ -30,7 +30,7 @@ export class RenderStreaming {
|
|||
secure: option.secure == undefined ? false : option.secure,
|
||||
keyfile: option.keyfile,
|
||||
certfile: option.certfile,
|
||||
websocket: option.websocket == undefined ? false : option.websocket,
|
||||
type: option.type == undefined ? 'websocket' : option.type,
|
||||
mode: option.mode,
|
||||
logging: option.logging,
|
||||
};
|
||||
|
|
@ -69,9 +69,17 @@ export class RenderStreaming {
|
|||
}
|
||||
});
|
||||
}
|
||||
if (this.options.type == 'http') {
|
||||
console.log(`Use http polling for signaling server.`);
|
||||
}
|
||||
else if(this.options.type != 'websocket') {
|
||||
console.log(`signaling type should be set "websocket" or "http". ${this.options.type} is not supported.`);
|
||||
console.log(`Changing signaling type to websocket.`);
|
||||
this.options.type = 'websocket';
|
||||
}
|
||||
if (this.options.type == 'websocket') {
|
||||
console.log(`Use websocket for signaling server ws://${this.getIPAddress()[0]}`);
|
||||
|
||||
if (this.options.websocket) {
|
||||
console.log(`start websocket signaling server ws://${this.getIPAddress()[0]}`);
|
||||
//Start Websocket Signaling server
|
||||
new WSSignaling(this.server, this.options.mode);
|
||||
}
|
||||
|
|
@ -94,4 +102,4 @@ export class RenderStreaming {
|
|||
}
|
||||
}
|
||||
|
||||
RenderStreaming.run(process.argv);
|
||||
RenderStreaming.run(process.argv);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ import { log, LogLevel } from './log';
|
|||
import Options from './class/options';
|
||||
import { reset as resetHandler }from './class/httphandler';
|
||||
|
||||
const cors = require('cors');
|
||||
|
||||
export const createServer = (config: Options): express.Application => {
|
||||
const app: express.Application = express();
|
||||
resetHandler(config.mode);
|
||||
|
|
@ -15,9 +17,10 @@ export const createServer = (config: Options): express.Application => {
|
|||
app.use(morgan(config.logging));
|
||||
}
|
||||
// const signal = require('./signaling');
|
||||
app.use(cors({origin: '*'}));
|
||||
app.use(express.urlencoded({ extended: true }));
|
||||
app.use(express.json());
|
||||
app.get('/config', (req, res) => res.json({ useWebSocket: config.websocket, startupMode: config.mode, logging: config.logging }));
|
||||
app.get('/config', (req, res) => res.json({ useWebSocket: config.type == 'websocket', startupMode: config.mode, logging: config.logging }));
|
||||
app.use('/signaling', signaling);
|
||||
app.use(express.static(path.join(__dirname, '../client/public')));
|
||||
app.use('/module', express.static(path.join(__dirname, '../client/src')));
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
import { getMockReq, getMockRes } from '@jest-mock/express';
|
||||
import * as httpHandler from '../src/class/httphandler';
|
||||
|
||||
const RetriesToForceTimeout = 11; // Waits a second each time, timeout is 10 sec for httphandler.
|
||||
|
||||
describe('http signaling test in public mode', () => {
|
||||
const sessionId = "abcd1234";
|
||||
const sessionId2 = "abcd5678";
|
||||
const sessionId3 = "abcd9101112";
|
||||
const connectionId = "12345";
|
||||
const connectionId2 = "67890";
|
||||
const testsdp = "test sdp";
|
||||
|
|
@ -11,6 +14,7 @@ describe('http signaling test in public mode', () => {
|
|||
const { res, next, mockClear } = getMockRes();
|
||||
const req = getMockReq({ header: jest.fn(() => sessionId) });
|
||||
const req2 = getMockReq({ header: jest.fn(() => sessionId2) });
|
||||
const req3 = getMockReq({ header: jest.fn(() => sessionId3) });
|
||||
|
||||
beforeAll(() => {
|
||||
httpHandler.reset("public");
|
||||
|
|
@ -18,6 +22,8 @@ describe('http signaling test in public mode', () => {
|
|||
|
||||
beforeEach(() => {
|
||||
mockClear();
|
||||
httpHandler.checkSessionId(req, res, next);
|
||||
httpHandler.checkSessionId(req2, res, next);
|
||||
});
|
||||
|
||||
test('throw check has session', async () => {
|
||||
|
|
@ -59,7 +65,7 @@ describe('http signaling test in public mode', () => {
|
|||
test('get all from session1', async () => {
|
||||
await httpHandler.getAll(req, res);
|
||||
const connect = { connectionId: connectionId, datetime: expect.anything(), type: "connect" };
|
||||
expect(res.json).toHaveBeenCalledWith({ messages: expect.arrayContaining([connect]) });
|
||||
expect(res.json).toHaveBeenCalledWith({ messages: expect.arrayContaining([connect]), datetime: expect.anything() });
|
||||
});
|
||||
|
||||
test('post offer from session1', async () => {
|
||||
|
|
@ -123,7 +129,7 @@ describe('http signaling test in public mode', () => {
|
|||
test('disconnection get from session1', async () => {
|
||||
await httpHandler.getAll(req, res);
|
||||
const disconnect = { connectionId: connectionId, datetime: expect.anything(), type: "disconnect" };
|
||||
expect(res.json).toHaveBeenCalledWith({ messages: expect.arrayContaining([disconnect]) });
|
||||
expect(res.json).toHaveBeenCalledWith({ messages: expect.arrayContaining([disconnect]), datetime: expect.anything() });
|
||||
});
|
||||
|
||||
test('delete connection from session1', async () => {
|
||||
|
|
@ -152,7 +158,7 @@ describe('http signaling test in public mode', () => {
|
|||
await httpHandler.createSession(sessionId2, res);
|
||||
|
||||
await httpHandler.getAll(req, res);
|
||||
expect(res.json).toHaveBeenLastCalledWith({ messages: [] });
|
||||
expect(res.json).toHaveBeenLastCalledWith({ messages: [], datetime: expect.anything() });
|
||||
|
||||
const connectBody = { connectionId: connectionId };
|
||||
req.body = connectBody;
|
||||
|
|
@ -164,9 +170,9 @@ describe('http signaling test in public mode', () => {
|
|||
|
||||
const offer = { connectionId: connectionId, sdp: testsdp, datetime: expect.anything(), type: "offer", polite: false };
|
||||
await httpHandler.getAll(req, res);
|
||||
expect(res.json).toHaveBeenLastCalledWith({ messages: expect.not.arrayContaining([offer]) });
|
||||
expect(res.json).toHaveBeenLastCalledWith({ messages: expect.not.arrayContaining([offer]), datetime: expect.anything() });
|
||||
await httpHandler.getAll(req2, res);
|
||||
expect(res.json).toHaveBeenLastCalledWith({ messages: expect.arrayContaining([offer]) });
|
||||
expect(res.json).toHaveBeenLastCalledWith({ messages: expect.arrayContaining([offer]), datetime: expect.anything() });
|
||||
|
||||
const deleteBody = { connectionId: connectionId };
|
||||
req2.body = deleteBody;
|
||||
|
|
@ -180,10 +186,127 @@ describe('http signaling test in public mode', () => {
|
|||
|
||||
const disconnect = { connectionId: connectionId, type: "disconnect", datetime: expect.anything() };
|
||||
await httpHandler.getAll(req2, res);
|
||||
expect(res.json).toHaveBeenLastCalledWith({ messages: expect.arrayContaining([disconnect]) });
|
||||
expect(res.json).toHaveBeenLastCalledWith({ messages: expect.arrayContaining([disconnect]), datetime: expect.anything() });
|
||||
|
||||
await httpHandler.deleteSession(req2, res);
|
||||
});
|
||||
|
||||
test('Timed out session2 deleted after session1 resends offer', async () => {
|
||||
httpHandler.reset("public");
|
||||
|
||||
await httpHandler.createSession(sessionId, res);
|
||||
await httpHandler.createSession(sessionId2, res);
|
||||
|
||||
req.url = "";
|
||||
req2.url = "";
|
||||
await httpHandler.checkSessionId(req, res, next);
|
||||
await httpHandler.checkSessionId(req2, res, next);
|
||||
|
||||
await httpHandler.getAll(req, res);
|
||||
expect(res.json).toHaveBeenLastCalledWith({ messages: [], datetime: expect.anything() });
|
||||
|
||||
const connectBody = { connectionId: connectionId };
|
||||
req.body = connectBody;
|
||||
await httpHandler.createConnection(req, res);
|
||||
|
||||
const offerBody = { connectionId: connectionId, sdp: testsdp, datetime: expect.anything(), type: "offer" };
|
||||
req.body = offerBody;
|
||||
await httpHandler.postOffer(req, res);
|
||||
|
||||
const offer = { connectionId: connectionId, sdp: testsdp, datetime: expect.anything(), type: "offer", polite: false };
|
||||
await httpHandler.getAll(req, res);
|
||||
expect(res.json).toHaveBeenLastCalledWith({ messages: expect.not.arrayContaining([offer]), datetime: expect.anything() });
|
||||
await httpHandler.getAll(req2, res);
|
||||
expect(res.json).toHaveBeenLastCalledWith({ messages: expect.arrayContaining([offer]), datetime: expect.anything() });
|
||||
|
||||
const answerBody = { connectionId: connectionId, sdp: testsdp };
|
||||
req2.body = answerBody;
|
||||
await httpHandler.postAnswer(req2, res);
|
||||
|
||||
// resend offer after answer to simulate PeerCandidate entering into failed state
|
||||
req.body = offerBody;
|
||||
await httpHandler.postOffer(req, res);
|
||||
|
||||
// Wait a second and then checkSession for only session1 to force timeout of session2.
|
||||
for (let i = 0; i < RetriesToForceTimeout + 1; ++i)
|
||||
{
|
||||
await httpHandler.checkSessionId(req, res, next);
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
}
|
||||
|
||||
// Get all for session1 to trigger cleaning up associated session that timed out.
|
||||
await httpHandler.getAll(req, res);
|
||||
|
||||
// Check that we do have session1 still
|
||||
await httpHandler.checkSessionId(req, res, next);
|
||||
expect(res.sendStatus).toHaveBeenLastCalledWith(200);
|
||||
|
||||
// Check that we no longer have session2
|
||||
await httpHandler.checkSessionId(req2, res, next);
|
||||
expect(res.sendStatus).toHaveBeenLastCalledWith(404);
|
||||
|
||||
await httpHandler.deleteSession(req, res);
|
||||
}, 16000);
|
||||
|
||||
test('Timed out sessions are deleted when other sessions check', async () => {
|
||||
httpHandler.reset("public");
|
||||
|
||||
await httpHandler.createSession(sessionId, res);
|
||||
await httpHandler.createSession(sessionId2, res);
|
||||
await httpHandler.createSession(sessionId3, res);
|
||||
|
||||
req.url = "";
|
||||
req2.url = "";
|
||||
req3.url = "";
|
||||
await httpHandler.checkSessionId(req, res, next);
|
||||
await httpHandler.checkSessionId(req2, res, next);
|
||||
await httpHandler.checkSessionId(req3, res, next);
|
||||
|
||||
await httpHandler.getAll(req, res);
|
||||
expect(res.json).toHaveBeenLastCalledWith({ messages: [], datetime: expect.anything() });
|
||||
|
||||
const connectBody = { connectionId: connectionId };
|
||||
req.body = connectBody;
|
||||
await httpHandler.createConnection(req, res);
|
||||
|
||||
const offerBody = { connectionId: connectionId, sdp: testsdp, datetime: expect.anything(), type: "offer" };
|
||||
req.body = offerBody;
|
||||
await httpHandler.postOffer(req, res);
|
||||
|
||||
const offer = { connectionId: connectionId, sdp: testsdp, datetime: expect.anything(), type: "offer", polite: false };
|
||||
await httpHandler.getAll(req, res);
|
||||
expect(res.json).toHaveBeenLastCalledWith({ messages: expect.not.arrayContaining([offer]), datetime: expect.anything() });
|
||||
await httpHandler.getAll(req2, res);
|
||||
expect(res.json).toHaveBeenLastCalledWith({ messages: expect.arrayContaining([offer]), datetime: expect.anything() });
|
||||
|
||||
const answerBody = { connectionId: connectionId, sdp: testsdp };
|
||||
req2.body = answerBody;
|
||||
await httpHandler.postAnswer(req2, res);
|
||||
|
||||
// Wait a second and then checkSession for only session3 to force timeout of session1 & session2.
|
||||
for (let i = 0; i < RetriesToForceTimeout + 1; ++i)
|
||||
{
|
||||
await httpHandler.checkSessionId(req3, res, next);
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
}
|
||||
|
||||
// Get all for session3 to trigger cleaning up sessions that timed out.
|
||||
await httpHandler.getAll(req3, res);
|
||||
|
||||
// Check that we do have session3 still
|
||||
await httpHandler.checkSessionId(req3, res, next);
|
||||
expect(res.sendStatus).toHaveBeenLastCalledWith(200);
|
||||
|
||||
// Check that we do have session1 still
|
||||
await httpHandler.checkSessionId(req, res, next);
|
||||
expect(res.sendStatus).toHaveBeenLastCalledWith(404);
|
||||
|
||||
// Check that we no longer have session2
|
||||
await httpHandler.checkSessionId(req2, res, next);
|
||||
expect(res.sendStatus).toHaveBeenLastCalledWith(404);
|
||||
|
||||
await httpHandler.deleteSession(req3, res);
|
||||
}, 16000);
|
||||
});
|
||||
|
||||
describe('http signaling test in private mode', () => {
|
||||
|
|
@ -202,6 +325,9 @@ describe('http signaling test in private mode', () => {
|
|||
|
||||
beforeEach(() => {
|
||||
mockClear();
|
||||
|
||||
httpHandler.checkSessionId(req, res, next);
|
||||
httpHandler.checkSessionId(req2, res, next);
|
||||
});
|
||||
|
||||
test('throw check has session', async () => {
|
||||
|
|
@ -346,7 +472,7 @@ describe('http signaling test in private mode', () => {
|
|||
await httpHandler.createSession(sessionId2, res);
|
||||
|
||||
await httpHandler.getAll(req, res);
|
||||
expect(res.json).toHaveBeenLastCalledWith({ messages: [] });
|
||||
expect(res.json).toHaveBeenLastCalledWith({ messages: [], datetime: expect.anything() });
|
||||
|
||||
const connectBody = { connectionId: connectionId };
|
||||
req.body = connectBody;
|
||||
|
|
@ -360,9 +486,9 @@ describe('http signaling test in private mode', () => {
|
|||
|
||||
const offer = { connectionId: connectionId, sdp: testsdp, datetime: expect.anything(), type: "offer", polite: true };
|
||||
await httpHandler.getAll(req, res);
|
||||
expect(res.json).toHaveBeenLastCalledWith({ messages: expect.not.arrayContaining([offer]) });
|
||||
expect(res.json).toHaveBeenLastCalledWith({ messages: expect.not.arrayContaining([offer]), datetime: expect.anything() });
|
||||
await httpHandler.getAll(req2, res);
|
||||
expect(res.json).toHaveBeenLastCalledWith({ messages: expect.arrayContaining([offer]) });
|
||||
expect(res.json).toHaveBeenLastCalledWith({ messages: expect.arrayContaining([offer]), datetime: expect.anything() });
|
||||
|
||||
const deleteBody = { connectionId: connectionId };
|
||||
req2.body = deleteBody;
|
||||
|
|
@ -376,7 +502,7 @@ describe('http signaling test in private mode', () => {
|
|||
|
||||
const disconnect = { connectionId: connectionId, type: "disconnect", datetime: expect.anything() };
|
||||
await httpHandler.getAll(req2, res);
|
||||
expect(res.json).toHaveBeenLastCalledWith({ messages: expect.arrayContaining([disconnect]) });
|
||||
expect(res.json).toHaveBeenLastCalledWith({ messages: expect.arrayContaining([disconnect]), datetime: expect.anything() });
|
||||
|
||||
await httpHandler.deleteSession(req2, res);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -860,6 +860,7 @@
|
|||
"pm.test(\"The response has a valid JSON body\", function () {",
|
||||
" pm.response.to.be.json;",
|
||||
" pm.response.to.have.jsonBody(\"messages\");",
|
||||
" pm.response.to.have.jsonBody(\"datetime\");",
|
||||
" var jsonData = pm.response.json();",
|
||||
" console.log(jsonData);",
|
||||
" pm.expect(jsonData.messages.length).to.be.above(0);",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,75 @@ All notable changes to com.unity.renderstreaming package will be documented in t
|
|||
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased] - yyyy-mm-dd
|
||||
## [3.1.0-exp.9] - 2024-12-13
|
||||
|
||||
### Changed
|
||||
- deps: use com.unity.webrtc@3.0.0-pre.8
|
||||
- doc: improve the API documentation of VideoCodecInfo
|
||||
- doc: improve the API documentation of AudioCodecInfo
|
||||
- doc: improve the API documentation of VideoStreamSender
|
||||
- doc: improve the API documentation of VideoStreamReceiver
|
||||
- doc: improve the API documentation of InputSender
|
||||
- doc: improve the API documentation of InputReceiver
|
||||
- doc: improve the API documentation of AudioStreamSender
|
||||
- doc: improve the API documentation of AudioStreamReceiver
|
||||
- doc: improve the API documentation of SignalingManager
|
||||
|
||||
## [3.1.0-exp.8] - 2023-11-30
|
||||
|
||||
### Changed
|
||||
|
||||
- Upgrade the version of WebRTC package `3.0.0-pre.7`.
|
||||
|
||||
## [3.1.0-exp.7] - 2023-08-09
|
||||
|
||||
### Added
|
||||
|
||||
- Added configurable logger to enable users to customize logging for their environment.
|
||||
|
||||
### Changed
|
||||
|
||||
- Upgrade the version of WebRTC package `3.0.0-pre.6`.
|
||||
- Add `AudioStreamSender.loopback` property.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed error on HTTP signaling when using short polling interval.
|
||||
- Fixed `SignalingManager` so that ICE server configurations aren't effected.
|
||||
- Added a workaround to fix an issue where `InputField` wasn't worked when entering characters from browsers or a `Receiver` scene of package sample.
|
||||
|
||||
### Removed
|
||||
|
||||
- Removed Furioos Integration.
|
||||
|
||||
## [3.1.0-exp.6] - 2023-02-24
|
||||
|
||||
### Added
|
||||
|
||||
- Support Automatic Streaming.
|
||||
- Support Render Streaming Wizard.
|
||||
- Support Command line arguments.
|
||||
- Add Render Streaming Settings in the Project Settings window.
|
||||
|
||||
### Changed
|
||||
|
||||
- Rename classes.
|
||||
- `RenderStreaming` > `SignalingManager`
|
||||
- Websocket is in default for signaling protocol instead of HTTP polling.
|
||||
- Changed a unit of the HTTP polling interval, second to millisecond.
|
||||
|
||||
## [3.1.0-exp.5] - 2023-01-16
|
||||
|
||||
### Changed
|
||||
|
||||
- Upgrade the version of Input System package `1.4.4`.
|
||||
- Upgrade the version of WebRTC package `3.0.0-pre.4`.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix incorrect mouse position in full-screen web player sample.
|
||||
|
||||
## [3.1.0-exp.4] - 2022-10-06
|
||||
|
||||
### Added
|
||||
|
||||
|
|
@ -14,7 +82,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
### Changed
|
||||
|
||||
- Upgraded the version of Input System package `1.4.1`.
|
||||
- Upgraded the version of WebRTC package `2.4.0-exp.10`.
|
||||
- Upgraded the version of WebRTC package `2.4.0-exp.11`.
|
||||
- Merge features of three classes to `VideoStreamSender`.
|
||||
- `MicrophoneStreamSender`
|
||||
- `AudioStreamReceiver`
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
* [About Unity Render Streaming](index.md)
|
||||
* [Overview](overview.md)
|
||||
* [Tutorial](tutorial.md)
|
||||
* [Developing a streaming application](dev-streaming-app-intro.md)
|
||||
* [Installing The Package](installation.md)
|
||||
* [Launching The Web Application](launch-webapp.md)
|
||||
* [Creating The Scene](create-scene.md)
|
||||
* [Setting Up Device Input](control-camera.md)
|
||||
* [Render Streaming Settings](settings.md)
|
||||
* [Render Streaming Wizard](wizard.md)
|
||||
* [Web Application](webapp.md)
|
||||
* [Configure Self-Signed Credentials for https](https.md)
|
||||
* [Setting for TURN Server](turnserver.md)
|
||||
|
|
@ -15,8 +16,7 @@
|
|||
* [Video Streaming Component](video-streaming.md)
|
||||
* [Audio Streaming Component](audio-streaming.md)
|
||||
* [Data Streaming Component](data-streaming.md)
|
||||
* [Using with Input System](use-inputsystem.md)
|
||||
* [Deploy to Furioos](deploy-to-furioos.md)
|
||||
* [Command-line option](commandline-option.md)
|
||||
* [Samples](samples.md)
|
||||
* [Receiver](sample-receiver.md)
|
||||
* [Broadcast](sample-broadcast.md)
|
||||
|
|
@ -26,5 +26,4 @@
|
|||
* [Gyroscope](sample-gyroscope.md)
|
||||
* [Web Browser Input](sample-browserinput.md)
|
||||
* [Multiplay](sample-multiplay.md)
|
||||
* [Project Template](template.md)
|
||||
* [FAQ](faq.md)
|
||||
|
|
|
|||
|
|
@ -15,9 +15,10 @@ This component streams the audio rendering results from [`AudioListener`](https:
|
|||
| **Audio Source Type** | Choose the type of source for your audio streaming. <br/> - *Audio Listener* <br/> - *Audio Source* <br/> - *Microphone* | *Audio Listener* |
|
||||
| *Audio Listener* | [`Audio Listener`](https://docs.unity3d.com/ScriptReference/AudioSource.html) instance for sending audio | |
|
||||
| *Audio Source* | [`Audio Source`](https://docs.unity3d.com/ScriptReference/AudioSource.html) instance for sending audio | |
|
||||
| *Microphone Device Index* | The index of the video input device to be used. See [Microphone.devices](https://docs.unity3d.com/ScriptReference/Microphone-devices.html). | 0 |
|
||||
| *Microphone Device Index* | The index of the microphone input device to be used. See [Microphone.devices](https://docs.unity3d.com/ScriptReference/Microphone-devices.html). | 0 |
|
||||
| *Auto Request User Authorization* | Whether request permission to use microphone. You don't need to enable it if you call [Application.RequestUserAuthorization](https://docs.unity3d.com/ScriptReference/Application.RequestUserAuthorization.html) yourself. | Enabled |
|
||||
| **Audio Codec** | *Default* option means trying to use all available codecs for negotiating other peers. | Default |
|
||||
| *Loopback* | The sending audio is also played on sender side. | Disabled |
|
||||
| **Bitrate (kbits/sec)** | The bitrate of the audio streaming. | |
|
||||
| *Min* | The minimum value of the bitrate. | 0 |
|
||||
| *Max* | The maximum value of the bitrate. | 1000 |
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
# Command line arguments
|
||||
|
||||
Unity Render Streaming supports configuration changes via command line arguments. you can change settings to match the deployment environments. Command line arguments work with Windows, macOS, and Linux runtime applications. Mobile platforms aren't supported.
|
||||
|
||||
> [!WARNING]
|
||||
> **-batchmode** and **-nographics** options don't work with Unity Render Streaming.
|
||||
|
||||
Command line arguments are evaluated when initializing the [**SignalingManager**](streaming-management.md) component. When command line arguments are evaluated in the **SignalingManager** component, it overrides the settings specified in the [Settings Window](settings.md). If you wish to ignore the command line options, specify **Evaluate command line arguments** off in the SignalingManager inspector. If a command line arguments contain invalid values, the contents of the configuration window are evaluated, instead of the arguments of the command line.
|
||||
|
||||
Use a command line with the following arguments to start your standalone app.
|
||||
|
||||
| Argument | Description |
|
||||
| --- | --- |
|
||||
| `signalingType <value>` | Specify the signaling type. **websocket** or **http**. |
|
||||
| `signalingUrl <value>` | Specify the URL of signaling server. |
|
||||
| `iceServerUrl <value>` | Set the URL of STUN/TURN server. |
|
||||
| `iceServerUsername <value>` | Specify the user name of the TURN server. |
|
||||
| `iceServerCredential <value>` | Specify the password of the TURN server. |
|
||||
| `iceServerCredentialType <value>` | Specify the credential type for the TURN server. **password** or **oauth**. |
|
||||
| `pollingInterval <value>` | Specify the polling interval in milliseconds to the signaling server. This value is used when using **http** for the signaling type. |
|
||||
| `importJson <path>` | Specify the path of the JSON file. |
|
||||
|
||||
## Import JSON
|
||||
|
||||
You can change the configuration via the JSON file when using **-importJson** option in command line. The JSON file must be written in the following format:
|
||||
|
||||
```javascript
|
||||
{
|
||||
"signalingType": "websocket",
|
||||
"signalingUrl": "ws://192.168.11.11",
|
||||
"iceServers": [{
|
||||
"urls": [
|
||||
"stun:stun.l.google.com:19302"
|
||||
],
|
||||
"username": "user",
|
||||
"credential": "pass",
|
||||
"credentialType": "password"
|
||||
}],
|
||||
"pollingInterval": "5000"
|
||||
}
|
||||
```
|
||||
|
||||
## Command line examples
|
||||
|
||||
Change the signaling type to **http**:
|
||||
|
||||
```
|
||||
RenderStreaming.exe -signalingType http
|
||||
```
|
||||
|
||||
Change the URL of the signaling server:
|
||||
|
||||
```
|
||||
RenderStreaming.exe -signalingUrl http://192.168.10.1
|
||||
```
|
||||
|
||||
Specify multiple URLs of STAN servers:
|
||||
|
||||
```
|
||||
RenderStreaming.exe -iceServerUrl stun:stun.l.google.com:19302 -iceServerUrl stun:stun.l.google.com:19303
|
||||
```
|
||||
|
||||
Specify the URL, username, and password of the TURN server:
|
||||
|
||||
```
|
||||
RenderStreaming.exe -iceServerUrl turn:192.168.10.10:3478?transport=udp -iceServerUsername username -iceServerCredentialType password -iceServerCredential pass
|
||||
```
|
||||
|
||||
Specify the path of the JSON file:
|
||||
|
||||
```
|
||||
RenderStreaming.exe -importJson config.json
|
||||
```
|
||||
|
|
@ -4,7 +4,7 @@ To control the camera on the remote PC, we need to link the input events on web
|
|||
|
||||
## Check settings of Input System
|
||||
|
||||
First, please check [the settings](use-inputsystem.md) for using Input System.
|
||||
First, please check the [Wizard window](wizard.md) about the Input System settings.
|
||||
|
||||
## Adding components for input processing
|
||||
|
||||
|
|
@ -84,8 +84,8 @@ Once you have copied the script and saved the file, assign `PlayerController.Loo
|
|||
|
||||
## Checking on browsers
|
||||
|
||||
The mouse operation in the browser should be reflected in the rotation of the camera. If the camera is not moved, please check [the settings](use-inputsystem.md).
|
||||
The mouse operation in the browser should be reflected in the rotation of the camera. If the camera is not moved, please check the settings on the [Wizard](wizard.md) window.
|
||||
|
||||
## Next step
|
||||
|
||||
We were able to incorporate the input processing using the Input Actions feature. If you would like to learn more about the features of Unity Render Streaming, please see the [Sample page](samples.md). Also, check out [Customizing your web application](customize-webapp.md) for information on how to modify the web user interface.
|
||||
We were able to incorporate the input processing using the Input Actions feature. If you would like to learn more about the features of Unity Render Streaming, please see the [Sample page](samples.md). Also, check out [Customizing your web application](customize-webapp.md) for information on how to modify the web user interface.
|
||||
|
|
|
|||
|
|
@ -2,25 +2,31 @@
|
|||
|
||||
This tutorial explains how to edit an empty scene in Unity Editor and display the image rendered from the camera to the browser.
|
||||
|
||||
## Changing Project Settings
|
||||
|
||||
The procedure described in this page assumes that the [**Automatic Streaming**](settings.md##general-settings) feature is not used. Please turn the flag off following steps.
|
||||
|
||||
1: Open the **Project Settings** window.
|
||||
|
||||
2: Select **Render Streaming** tab.
|
||||
|
||||
3: Select **Create New Settings Asset**.
|
||||
|
||||
4: Save the asset with any name.
|
||||
|
||||
5: Disable **Automatic Streaming**.
|
||||
|
||||

|
||||
|
||||
## Setting component
|
||||
|
||||
If Unity version is 2020 or later, Create a new empty scene. Select **File > New Scene** from the menu to open the dialog and select **Basic (Built-in)**.
|
||||
|
||||
> [!NOTE]
|
||||
> This dialog is not opened if you are using Unity 2019.
|
||||
|
||||

|
||||
|
||||
Select the **Main Camera** object in the Hierarchy window, and add the **Render Streaming** component in the Inspector window.
|
||||
Select the **Main Camera** object in the Hierarchy window, and add the **Signaling Manager** component in the Inspector window.
|
||||
|
||||

|
||||
|
||||
Update properties in the inspector.
|
||||
|
||||
- **Signaling Type** : `WebSocketSignaling`
|
||||
- **Signaling URL** : `ws://localhost`
|
||||
|
||||

|
||||

|
||||
|
||||
Next, we will add the **Broadcast** component to the **Main Camera** object. this component deliver the stream to multiple peers.
|
||||
|
||||
|
|
@ -34,7 +40,7 @@ Add a [**Video Stream Sender**](video-streaming.html#videostreamsenderapiunityre
|
|||
|
||||

|
||||
|
||||
Assign the [**Video Stream Sender**](video-streaming.html#videostreamsenderapiunityrenderstreamingvideostreamsenderhtml-component) component to the **Broadcast** component property.
|
||||
Assign the [**Video Stream Sender**](video-streaming.html#videostreamsenderapiunityrenderstreamingvideostreamsenderhtml-component) component to the **Broadcast** component property. And set camera
|
||||
|
||||

|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Data streaming is using [`RTCDataChannel`](https://docs.unity3d.com/Packages/com.unity.webrtc@2.4/manual/datachannel.html) of the WebRTC package internally.
|
||||
|
||||
Using the data streaming feature, we provide a component to send messages of [Input System](https://docs.unity3d.com/Packages/com.unity.inputsystem@latest). For more details, please check the section on [Using with Input System](use-inputsystem.md).
|
||||
Using the data streaming feature, Unity Render Streaming provides a component to send messages of [Input System](https://docs.unity3d.com/Packages/com.unity.inputsystem@latest).
|
||||
|
||||
## [`InputSender`](../api/Unity.RenderStreaming.InputSender.html) component reference
|
||||
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
# Deploy to Furioos
|
||||
|
||||
As you may already know, **Unity Render Streaming** has a Furioos-compatible signaling option. This means that you can build a dedicated version of your application, host it on **Furioos**, and share it with thousands of customers who will enjoy all the features of **Unity Render Streaming**. But you will **not** have to deal with any of the difficulties of setting up a private server, a machine in the cloud or manage the scalability of your solution.
|
||||
|
||||
To do so, the requirement is to select `FurioosSignaling` in the `Signaling type` parameter of the [RenderStreaming](streaming-management.md#render-streaming) component.
|
||||
This allow your application to connect to Furioos services when running on the managed virtual machines.
|
||||
|
||||

|
||||
|
||||
Then just build a **standalone Windows version** of your application, and zip it! Don't try to build iOS, Android, linux or whatever version of your app, **Furioos only support Windows applications**. Also, be sure to zip the whole exported folder with all files and sub-folders, not just the ".exe" file.
|
||||
|
||||

|
||||
|
||||
Finally just upload it on your account at https://portal.furioos.com/ .
|
||||
If you need futher help to upload your application on **Furioos**, please follow [this tutorial](https://support.furioos.com/article/adding-an-application-on-furioos/).
|
||||
|
||||
You can check the stream type on https://portal.furioos.com/ by clicking to the "more options" button in the toolbar.
|
||||
|
||||

|
||||
|
|
@ -2,14 +2,6 @@
|
|||
|
||||
This section will walk you through the steps to create a simple streaming application from an empty Unity project.
|
||||
|
||||
## Install The Package
|
||||
|
||||
Install the package to start working. Please refer to the [Installing the package](installation.md) page to get started.
|
||||
|
||||
## Start the web application
|
||||
|
||||
After installing the package, please refer to the [Launching the Web Application](launch-webapp.md) page.
|
||||
|
||||
## Creating The Scene
|
||||
|
||||
To open the Unity editor and create a scene for streaming, see [Creating The Scene](create-scene.md).
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 503 KiB |
|
After Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 534 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 136 KiB |
|
After Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 98 KiB |
|
After Width: | Height: | Size: 253 KiB |
|
After Width: | Height: | Size: 337 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 1.7 MiB |
|
After Width: | Height: | Size: 896 KiB |
|
Before Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 564 KiB |
|
After Width: | Height: | Size: 154 KiB |
|
Before Width: | Height: | Size: 157 KiB After Width: | Height: | Size: 285 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 217 KiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 386 KiB |
|
After Width: | Height: | Size: 976 KiB |
|
After Width: | Height: | Size: 418 KiB |
|
After Width: | Height: | Size: 164 KiB |
|
|
@ -16,14 +16,14 @@ This package provides the main features below.
|
|||
|
||||
We can broadcast video rendered on Unity to browsers via network. For example, It can show the video rendered with HDRP on the browser on the iPad. In addition, broadcasting from multiple cameras is supported.
|
||||
|
||||

|
||||

|
||||
|
||||
### Audio streaming
|
||||
This package enables streaming sounds generated on Unity. And it can cast to multi-browsers simultaneously.
|
||||
|
||||
### Remote control
|
||||
|
||||
It is possible to send input messages to Unity from the browser, and sending inputs from multiple browsers is supported. Mouse, keyboard, touch, and gamepad are supported as input devices on the browser. For more information, please see the [Using with Input System](use-inputsystem.md) page.
|
||||
It's possible to send input messages to Unity from the browser, and sending inputs from multiple browsers is supported. Mouse, keyboard, touch, and gamepad are supported as input devices on the browser.
|
||||
|
||||
## Requirements
|
||||
|
||||
|
|
@ -31,15 +31,19 @@ This version of Render Streaming is compatible with the following versions of th
|
|||
|
||||
- **Unity 2020.3**
|
||||
- **Unity 2021.3**
|
||||
- **Unity 2022.1**
|
||||
- **Unity 2022.3**
|
||||
- **Unity 2023.1**
|
||||
|
||||
### Platform
|
||||
|
||||
- **Windows**
|
||||
- **Windows** (x64 only)
|
||||
- **Linux**
|
||||
- **macOS** (**Apple Slicon** is not supported yet)
|
||||
- **macOS** (**Intel** and **Apple Slicon**)
|
||||
- **iOS**
|
||||
- **Android** (**ARMv7** is not supported)
|
||||
- **Android** (**ARM64** only. **ARMv7** is not supported)
|
||||
|
||||
> [!NOTE]
|
||||
> This package depends on [the WebRTC package](https://docs.unity3d.com/Packages/com.unity.webrtc@3.0). If you build for mobile platform (iOS/Android), please see [the package documentation](https://docs.unity3d.com/Packages/com.unity.webrtc@3.0/manual/requirements.html#additional-notes) to know the requirements for building.
|
||||
|
||||
### Browser support
|
||||
|
||||
|
|
@ -61,14 +65,3 @@ Unity Render Streaming supports almost all browsers that can use WebRTC.
|
|||
## Samples
|
||||
|
||||
Please check [this page](samples.md).
|
||||
|
||||
## Project template
|
||||
|
||||
Please check [this page](template.md).
|
||||
|
||||
## Furioos compatibility
|
||||
|
||||
**Unity Render Streaming** is also supported natively by **Furioos** platform https://www.furioos.com/ .
|
||||
That means that you can easily build a Unity application, upload it on **Furioos** and enjoy all the features of **Unity Render Streaming** without worrying about the deployment and scalability issues of your project.
|
||||
|
||||
Please see [Furioos Tutorial](deploy-to-furioos.md) section to find out how it works.
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
# Installing The Package
|
||||
|
||||
Select **Window > Package Manager** in the menu bar.
|
||||
|
||||

|
||||
|
||||
Check Package Manager window, Click `+` button and select `Add package from git URL...`.
|
||||
|
||||

|
||||
|
||||
Input the string below to the input field.
|
||||
|
||||
```
|
||||
com.unity.renderstreaming@3.1.0-exp.4
|
||||
```
|
||||
|
||||
The list of version string is [here](https://github.com/Unity-Technologies/UnityRenderStreaming/tags). In most cases, the latest version is recommended to use.
|
||||
|
||||
Click `Add` button, and will start install the package.
|
||||
|
||||
If an input system dialog box appears, click `Yes`
|
||||
|
||||

|
||||
|
||||
## Next Step
|
||||
|
||||
After installing the package in the Unity Editor, you can launch the web application for signaling. Please see the next page [Launching The Web Application](launch-webapp.md).
|
||||