diff --git a/.github/renovate.json b/.github/renovate.json new file mode 100644 index 0000000..1a409f3 --- /dev/null +++ b/.github/renovate.json @@ -0,0 +1,13 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:base", + ":timezone(Asia/Tokyo)", + ":combinePatchMinorReleases", + ":prHourlyLimitNone", + ":prConcurrentLimit10", + "group:recommended", + "group:allNonMajor", + "schedule:weekly" + ] +} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ce0c4b4..913432d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,10 +17,10 @@ jobs: - windows_x86_64 runs-on: windows-2019 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Cache id: cache - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: _install key: ${{ matrix.name }}-v3-${{ hashFiles('VERSIONS') }} @@ -33,8 +33,10 @@ jobs: Copy-Item _build\windows_x86_64\release\sora_unity_sdk\Release\SoraUnitySdk.dll ${{ matrix.name }} # ソースコード(生成した分も含む)も一緒に入れておく Copy-Item -Recurse Sora ${{ matrix.name }}\Sora + # Lyra のモデルデータも一緒に入れておく + Copy-Item -Recurse _install\windows_x86_64\release\lyra\share\model_coeffs ${{ matrix.name }}\model_coeffs - name: Upload ${{ matrix.name }} Artifact - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ${{ matrix.name }} path: ${{ matrix.name }} @@ -47,10 +49,10 @@ jobs: - ios runs-on: macos-12 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Cache id: cache - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: _install key: ${{ matrix.name }}-v7-${{ hashFiles('VERSIONS') }} @@ -65,7 +67,7 @@ jobs: cp -r _build/macos_arm64/release/sora_unity_sdk/SoraUnitySdk.bundle/ macos_arm64/SoraUnitySdk.bundle/ - name: Upload macOS arm64 Artifact if: matrix.name == 'macos_arm64' - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: macos_arm64 path: macos_arm64/ @@ -76,11 +78,13 @@ jobs: mkdir ios/ cp _install/ios/release/webrtc/lib/libwebrtc.a ios/ cp _install/ios/release/boost/lib/libboost_json.a ios/ + cp _install/ios/release/boost/lib/libboost_filesystem.a ios/ cp _install/ios/release/sora/lib/libsora.a ios/ + cp _install/ios/release/lyra/lib/liblyra.a ios/ cp _build/ios/release/sora_unity_sdk/libSoraUnitySdk.a ios/ - name: Upload iOS Artifact if: matrix.name == 'ios' - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ios path: ios/ @@ -93,10 +97,10 @@ jobs: - ubuntu-20.04_x86_64 runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Cache id: cache - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: _install key: ${{ matrix.name }}-v1-${{ hashFiles('VERSIONS') }} @@ -116,7 +120,7 @@ jobs: cp _build/android/release/sora_unity_sdk/libSoraUnitySdk.so android/ - name: Upload Android Artifact if: matrix.name == 'android' - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: android path: android/ @@ -128,7 +132,7 @@ jobs: cp _build/ubuntu-20.04_x86_64/release/sora_unity_sdk/libSoraUnitySdk.so ubuntu-20.04_x86_64/ - name: Upload Ubuntu x86_64 Artifact if: matrix.name == 'ubuntu-20.04_x86_64' - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ubuntu-20.04_x86_64 path: ubuntu-20.04_x86_64/ @@ -139,9 +143,9 @@ jobs: - build-macos - build-ubuntu steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Download artifacts - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v3 - name: Packaging run: | set -ex @@ -150,8 +154,10 @@ jobs: mkdir -p SoraUnitySdk/Plugins/SoraUnitySdk/ios mkdir -p SoraUnitySdk/Plugins/SoraUnitySdk/android/arm64-v8a mkdir -p SoraUnitySdk/Plugins/SoraUnitySdk/linux/x86_64 + mkdir -p SoraUnitySdk/StreamingAssets/SoraUnitySdk cp windows_x86_64/SoraUnitySdk.dll SoraUnitySdk/Plugins/SoraUnitySdk/windows/x86_64/ cp -r windows_x86_64/Sora/ SoraUnitySdk/SoraUnitySdk/ + cp -r windows_x86_64/model_coeffs SoraUnitySdk/StreamingAssets/SoraUnitySdk/model_coeffs cp -r macos_arm64/SoraUnitySdk.bundle SoraUnitySdk/Plugins/SoraUnitySdk/macos/arm64/SoraUnitySdk.bundle cp android/libSoraUnitySdk.so SoraUnitySdk/Plugins/SoraUnitySdk/android/arm64-v8a/ cp android/webrtc.jar SoraUnitySdk/Plugins/SoraUnitySdk/android/ @@ -159,13 +165,15 @@ jobs: cp ios/libwebrtc.a SoraUnitySdk/Plugins/SoraUnitySdk/ios/ cp ios/libboost_json.a SoraUnitySdk/Plugins/SoraUnitySdk/ios/ cp ios/libsora.a SoraUnitySdk/Plugins/SoraUnitySdk/ios/ + cp ios/libboost_filesystem.a SoraUnitySdk/Plugins/SoraUnitySdk/ios/ + cp ios/liblyra.a SoraUnitySdk/Plugins/SoraUnitySdk/ios/ cp ubuntu-20.04_x86_64/libSoraUnitySdk.so SoraUnitySdk/Plugins/SoraUnitySdk/linux/x86_64/ cp LICENSE SoraUnitySdk/SoraUnitySdk/ cp NOTICE.md SoraUnitySdk/SoraUnitySdk/ - name: Upload SoraUnitySdk - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: SoraUnitySdk path: SoraUnitySdk @@ -176,9 +184,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Download SoraUnitySdk - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v3 with: name: SoraUnitySdk path: SoraUnitySdk diff --git a/CHANGES.md b/CHANGES.md index 1736298..206be79 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,6 +11,31 @@ ## develop +## 2023.1.0 (2023-04-13) + +- [UPDATE] Sora C++ SDK を `2023.4.0` に上げる + - @melpon @miosakuma +- [UPDATE] libwebrtc を `m111.5563.4.4` に上げる + - @melpon +- [UPDATE] Boost を `1.81.0` に上げる + - @melpon +- [UPDATE] CMake を `3.25.1` に上げる + - @melpon +- [UPDATE] actions/checkout@v2 と actions/cache@v2 を @v3 に上げる + - @melpon +- [UPDATE] actions/upload-artifact@v2 と actions/download-artifact@v2 を @v3 に上げる + - @melpon +- [ADD] `Sora.Config` に `AudioStreamingLanguageCode` を追加 + - @melpon +- [ADD] `Sora.Config` に `SignalingNotifyMetadata` を追加 + - @melpon +- [ADD] offer 設定時のコールバック関数 `OnSetOffer` を追加 + - @melpon +- [ADD] オーディオコーデックに Lyra を追加 + - @melpon +- [ADD] `Sora.Config` に `check_lyra_version` を追加 + - @torikizi + ## 2022.6.2 (2023-03-25) - [FIX] IPHONE_DEPLOYMENT_TARGET を 13 に上げる diff --git a/CMakeLists.txt b/CMakeLists.txt index 90283b0..ebbe020 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,8 @@ set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE NEVER) -find_package(Boost REQUIRED COMPONENTS json) +find_package(Boost REQUIRED COMPONENTS json filesystem) +find_package(Lyra REQUIRED) find_package(WebRTC REQUIRED) find_package(Sora REQUIRED) find_package(Threads REQUIRED) diff --git a/README.md b/README.md index b003740..ebfe720 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Sora Unity SDK -[![libwebrtc](https://img.shields.io/badge/libwebrtc-105.5195-blue.svg)](https://chromium.googlesource.com/external/webrtc/+/branch-heads/5195) +[![libwebrtc](https://img.shields.io/badge/libwebrtc-111.5563-blue.svg)](https://chromium.googlesource.com/external/webrtc/+/branch-heads/5563) [![GitHub tag](https://img.shields.io/github/tag/shiguredo/sora-unity-sdk.svg)](https://github.com/shiguredo/sora-unity-sdk) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![Actions Status](https://github.com/shiguredo/sora-unity-sdk/workflows/build/badge.svg)](https://github.com/shiguredo/sora-unity-sdk/actions) @@ -38,14 +38,14 @@ Please read https://github.com/shiguredo/oss/blob/master/README.en.md before use ## システム条件 -- WebRTC SFU Sora 2022.1.3 以降 +- WebRTC SFU Sora 2022.2.0 以降 ## 対応プラットフォーム - Windows 10 1809 x86_64 以降 -- macOS 12.4 M1 以降 +- macOS 13.3 M1 以降 - Android 7 以降 -- iOS 12 以降 +- iOS 13 以降 - Ubuntu 20.04 ## 対応機能 @@ -94,6 +94,7 @@ Please read https://github.com/shiguredo/oss/blob/master/README.en.md before use - Windows 版 - H.264 のハードウェアエンコードへの対応 - H.264 のハードウェアデコードへの対応 +- ミュート機能 ## Sora Unity SDK for MS Hololens2 @@ -114,6 +115,8 @@ Please read https://github.com/shiguredo/oss/blob/master/README.en.md before use - 企業名非公開 - Microsoft HoloLens 2 対応 - [NTTコノキュー](https://www.nttqonoq.com/) 様 +- ミュート機能 + - [NTTコノキュー](https://www.nttqonoq.com/) 様 ## 有償での優先実装が可能な機能一覧 @@ -125,7 +128,6 @@ Please read https://github.com/shiguredo/oss/blob/master/README.en.md before use ### 機能 -- ミュート機能 - デバイスをつかまないようにする機能 - 音声のみ送受信機能 - サイマルキャスト rid 指定対応 @@ -145,8 +147,8 @@ Please read https://github.com/shiguredo/oss/blob/master/README.en.md before use Apache License 2.0 ``` -Copyright 2019-2022, Wandbox LLC (Original Author) -Copyright 2019-2022, Shiguredo Inc. +Copyright 2019-2023, Wandbox LLC (Original Author) +Copyright 2019-2023, Shiguredo Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -160,5 +162,3 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ``` - - diff --git a/Sora/Sora.cs b/Sora/Sora.cs index 0617d81..73eb95e 100644 --- a/Sora/Sora.cs +++ b/Sora/Sora.cs @@ -31,6 +31,7 @@ public enum VideoCodecType public enum AudioCodecType { OPUS, + LYRA, } // SimulcastRid のためのパラメータ public enum SimulcastRidType @@ -70,6 +71,7 @@ public class Config public string ClientId = ""; public string BundleId = ""; public string Metadata = ""; + public string SignalingNotifyMetadata = ""; public Role Role = Sora.Role.Sendonly; public bool? Multistream; public bool? Spotlight; @@ -94,7 +96,12 @@ public class Config public string AudioRecordingDevice = ""; public string AudioPlayoutDevice = ""; public AudioCodecType AudioCodecType = AudioCodecType.OPUS; + // AudioCodecType.LYRA の場合は必須 + public int AudioCodecLyraBitrate = 0; + public bool? AudioCodecLyraUsedtx; + public bool CheckLyraVersion = false; public int AudioBitRate = 0; + public string AudioStreamingLanguageCode = ""; // DataChannelSignaling を有効にするかどうか public bool EnableDataChannelSignaling = false; @@ -126,6 +133,7 @@ public class Config IntPtr p; GCHandle onAddTrackHandle; GCHandle onRemoveTrackHandle; + GCHandle onSetOfferHandle; GCHandle onNotifyHandle; GCHandle onPushHandle; GCHandle onMessageHandle; @@ -154,6 +162,11 @@ public void Dispose() onRemoveTrackHandle.Free(); } + if (onSetOfferHandle.IsAllocated) + { + onSetOfferHandle.Free(); + } + if (onNotifyHandle.IsAllocated) { onNotifyHandle.Free(); @@ -229,6 +242,7 @@ public void Connect(Config config) cc.client_id = config.ClientId; cc.bundle_id = config.BundleId; cc.metadata = config.Metadata; + cc.signaling_notify_metadata = config.SignalingNotifyMetadata; cc.role = role; cc.enable_multistream = config.Multistream != null; cc.multistream = config.Multistream == null ? false : config.Multistream.Value; @@ -256,7 +270,12 @@ public void Connect(Config config) cc.audio_recording_device = config.AudioRecordingDevice; cc.audio_playout_device = config.AudioPlayoutDevice; cc.audio_codec_type = config.AudioCodecType.ToString(); + cc.audio_codec_lyra_bitrate = config.AudioCodecLyraBitrate; + cc.enable_audio_codec_lyra_usedtx = config.AudioCodecLyraUsedtx != null; + cc.audio_codec_lyra_usedtx = config.AudioCodecLyraUsedtx == null ? false : config.AudioCodecLyraUsedtx.Value; + cc.check_lyra_version = config.CheckLyraVersion; cc.audio_bit_rate = config.AudioBitRate; + cc.audio_streaming_language_code = config.AudioStreamingLanguageCode; cc.enable_data_channel_signaling = config.EnableDataChannelSignaling; cc.data_channel_signaling = config.DataChannelSignaling; cc.data_channel_signaling_timeout = config.DataChannelSignalingTimeout; @@ -363,6 +382,29 @@ public Action OnRemoveTrack } } + private delegate void SetOfferCallbackDelegate(string json, IntPtr userdata); + + [AOT.MonoPInvokeCallback(typeof(SetOfferCallbackDelegate))] + static private void SetOfferCallback(string json, IntPtr userdata) + { + var callback = GCHandle.FromIntPtr(userdata).Target as Action; + callback(json); + } + + public Action OnSetOffer + { + set + { + if (onSetOfferHandle.IsAllocated) + { + onSetOfferHandle.Free(); + } + + onSetOfferHandle = GCHandle.Alloc(value); + sora_set_on_set_offer(p, SetOfferCallback, GCHandle.ToIntPtr(onSetOfferHandle)); + } + } + private delegate void NotifyCallbackDelegate(string json, IntPtr userdata); [AOT.MonoPInvokeCallback(typeof(NotifyCallbackDelegate))] @@ -652,6 +694,11 @@ public static bool IsH264Supported() return sora_is_h264_supported() != 0; } + public static void Setenv(string name, string value) + { + sora_setenv(name, value); + } + public bool AudioEnabled { get { return sora_get_audio_enabled(p) != 0; } @@ -677,6 +724,8 @@ public bool VideoEnabled [DllImport(DllName)] private static extern void sora_set_on_remove_track(IntPtr p, TrackCallbackDelegate on_remove_track, IntPtr userdata); [DllImport(DllName)] + private static extern void sora_set_on_set_offer(IntPtr p, SetOfferCallbackDelegate on_set_offer, IntPtr userdata); + [DllImport(DllName)] private static extern void sora_set_on_notify(IntPtr p, NotifyCallbackDelegate on_notify, IntPtr userdata); [DllImport(DllName)] private static extern void sora_set_on_push(IntPtr p, PushCallbackDelegate on_push, IntPtr userdata); @@ -719,6 +768,8 @@ public bool VideoEnabled [DllImport(DllName)] private static extern int sora_is_h264_supported(); [DllImport(DllName)] + private static extern void sora_setenv(string name, string value); + [DllImport(DllName)] private static extern int sora_get_audio_enabled(IntPtr p); [DllImport(DllName)] private static extern void sora_set_audio_enabled(IntPtr p, int enabled); diff --git a/VERSION b/VERSION index ac9ec30..61ce345 100644 --- a/VERSION +++ b/VERSION @@ -1,8 +1,9 @@ -SORA_UNITY_SDK_VERSION=2022.6.2 -SORA_CPP_SDK_VERSION=2022.12.4 -WEBRTC_BUILD_VERSION=m105.5195.0.0 -BOOST_VERSION=1.80.0 -CMAKE_VERSION=3.23.1 +SORA_UNITY_SDK_VERSION=2023.1.0 +SORA_CPP_SDK_VERSION=2023.4.0 +WEBRTC_BUILD_VERSION=m111.5563.4.4 +BOOST_VERSION=1.81.0 +LYRA_VERSION=1.3.0 +CMAKE_VERSION=3.25.1 PROTOBUF_VERSION=21.1 PROTOC_GEN_JSONIF_VERSION=0.6.0 ANDROID_NDK_VERSION=r25b diff --git a/proto/sora_conf_internal.proto b/proto/sora_conf_internal.proto index 4fb3b84..dc57e64 100644 --- a/proto/sora_conf_internal.proto +++ b/proto/sora_conf_internal.proto @@ -56,18 +56,24 @@ message ConnectConfig { string audio_recording_device = 29; string audio_playout_device = 30; string audio_codec_type = 31; - int32 audio_bit_rate = 32; - bool enable_data_channel_signaling = 33; - bool data_channel_signaling = 34; - int32 data_channel_signaling_timeout = 35; - bool enable_ignore_disconnect_websocket = 36; - bool ignore_disconnect_websocket = 37; - int32 disconnect_wait_timeout = 38; - repeated DataChannel data_channels = 39; - bool insecure = 40; - string bundle_id = 41; - string proxy_url = 42; - string proxy_username = 43; - string proxy_password = 44; - string proxy_agent = 45; + int32 audio_codec_lyra_bitrate = 32; + bool enable_audio_codec_lyra_usedtx = 320; + bool audio_codec_lyra_usedtx = 321; + bool check_lyra_version = 33; + int32 audio_bit_rate = 34; + bool enable_data_channel_signaling = 35; + bool data_channel_signaling = 36; + int32 data_channel_signaling_timeout = 37; + bool enable_ignore_disconnect_websocket = 38; + bool ignore_disconnect_websocket = 39; + int32 disconnect_wait_timeout = 40; + repeated DataChannel data_channels = 41; + bool insecure = 42; + string bundle_id = 43; + string proxy_url = 44; + string proxy_username = 45; + string proxy_password = 46; + string proxy_agent = 47; + string audio_streaming_language_code = 48; + string signaling_notify_metadata = 49; } \ No newline at end of file diff --git a/run.py b/run.py index 977e004..46166bb 100644 --- a/run.py +++ b/run.py @@ -408,6 +408,18 @@ def install_boost(version, source_dir, install_dir, sora_version, platform: str) extract(archive, output_dir=install_dir, output_dirname='boost') +@versioned +def install_lyra(version, source_dir, install_dir, sora_version, platform: str): + win = platform.startswith("windows_") + filename = f'lyra-{version}_sora-cpp-sdk-{sora_version}_{platform}.{"zip" if win else "tar.gz"}' + rm_rf(os.path.join(source_dir, filename)) + archive = download( + f'https://github.com/shiguredo/sora-cpp-sdk/releases/download/{sora_version}/{filename}', + output_dir=source_dir) + rm_rf(os.path.join(install_dir, 'lyra')) + extract(archive, output_dir=install_dir, output_dirname='lyra') + + def cmake_path(path: str) -> str: return path.replace('\\', '/') @@ -551,6 +563,17 @@ def install_deps(platform: str, build_platform: str, source_dir, build_dir, inst } install_boost(**install_boost_args) + # Lyra + install_lyra_args = { + 'version': version['LYRA_VERSION'], + 'version_file': os.path.join(install_dir, 'lyra.version'), + 'source_dir': source_dir, + 'install_dir': install_dir, + 'sora_version': version['SORA_CPP_SDK_VERSION'], + 'platform': platform, + } + install_lyra(**install_lyra_args) + # CMake install_cmake_args = { 'version': version['CMAKE_VERSION'], @@ -719,6 +742,7 @@ def main(): cmake_args.append(f'-DSORA_UNITY_SDK_VERSION={sora_unity_sdk_version}') cmake_args.append(f'-DSORA_UNITY_SDK_COMMIT={sora_unity_sdk_commit}') cmake_args.append(f"-DBOOST_ROOT={cmake_path(os.path.join(install_dir, 'boost'))}") + cmake_args.append(f"-DLYRA_DIR={cmake_path(os.path.join(install_dir, 'lyra'))}") cmake_args.append('-DWEBRTC_LIBRARY_NAME=webrtc') cmake_args.append(f"-DWEBRTC_INCLUDE_DIR={cmake_path(webrtc_info.webrtc_include_dir)}") cmake_args.append(f"-DWEBRTC_LIBRARY_DIR={cmake_path(webrtc_info.webrtc_library_dir)}") diff --git a/src/sora.cpp b/src/sora.cpp index 0ae827e..34a83ae 100644 --- a/src/sora.cpp +++ b/src/sora.cpp @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include #include #include @@ -104,6 +106,9 @@ void Sora::SetOnRemoveTrack( std::function on_remove_track) { on_remove_track_ = on_remove_track; } +void Sora::SetOnSetOffer(std::function on_set_offer) { + on_set_offer_ = std::move(on_set_offer); +} void Sora::SetOnNotify(std::function on_notify) { on_notify_ = std::move(on_notify); } @@ -211,16 +216,14 @@ void Sora::DoConnect(const sora_conf::internal::ConnectConfig& cc, dependencies.task_queue_factory.get()); // worker 上の env - auto worker_env = worker_thread_->Invoke( - RTC_FROM_HERE, [] { return sora::GetJNIEnv(); }); + auto worker_env = + worker_thread_->BlockingCall([] { return sora::GetJNIEnv(); }); // worker 上の context #if defined(SORA_UNITY_SDK_ANDROID) - void* worker_context = - worker_thread_->Invoke(RTC_FROM_HERE, [worker_env] { - return ::sora_unity_sdk::GetAndroidApplicationContext( - (JNIEnv*)worker_env) - .Release(); - }); + void* worker_context = worker_thread_->BlockingCall([worker_env] { + return ::sora_unity_sdk::GetAndroidApplicationContext((JNIEnv*)worker_env) + .Release(); + }); #else void* worker_context = nullptr; #endif @@ -236,15 +239,15 @@ void Sora::DoConnect(const sora_conf::internal::ConnectConfig& cc, media_dependencies.adm = unity_adm_; #if defined(SORA_UNITY_SDK_ANDROID) - worker_thread_->Invoke(RTC_FROM_HERE, [worker_env, worker_context] { + worker_thread_->BlockingCall([worker_env, worker_context] { ((JNIEnv*)worker_env)->DeleteLocalRef((jobject)worker_context); }); #endif media_dependencies.audio_encoder_factory = - webrtc::CreateBuiltinAudioEncoderFactory(); + sora::CreateBuiltinAudioEncoderFactory(); media_dependencies.audio_decoder_factory = - webrtc::CreateBuiltinAudioDecoderFactory(); + sora::CreateBuiltinAudioDecoderFactory(); void* env = sora::GetJNIEnv(); void* android_context = GetAndroidApplicationContext(env); @@ -384,6 +387,11 @@ void Sora::DoConnect(const sora_conf::internal::ConnectConfig& cc, config.video_codec_type = cc.video_codec_type; config.video_bit_rate = cc.video_bit_rate; config.audio_codec_type = cc.audio_codec_type; + config.audio_codec_lyra_bitrate = cc.audio_codec_lyra_bitrate; + if (cc.enable_audio_codec_lyra_usedtx) { + config.audio_codec_lyra_usedtx = cc.audio_codec_lyra_usedtx; + } + config.check_lyra_version = cc.check_lyra_version; config.audio_bit_rate = cc.audio_bit_rate; if (cc.enable_data_channel_signaling) { config.data_channel_signaling = cc.data_channel_signaling; @@ -423,13 +431,26 @@ void Sora::DoConnect(const sora_conf::internal::ConnectConfig& cc, config.metadata = md; } } + if (!cc.signaling_notify_metadata.empty()) { + boost::json::error_code ec; + auto md = boost::json::parse(cc.signaling_notify_metadata, ec); + if (ec) { + RTC_LOG(LS_WARNING) << "Invalid JSON: signaling_notify_metadata=" + << cc.signaling_notify_metadata; + } else { + config.signaling_notify_metadata = md; + } + } config.insecure = cc.insecure; config.proxy_url = cc.proxy_url; config.proxy_username = cc.proxy_username; config.proxy_password = cc.proxy_password; config.proxy_agent = cc.proxy_agent; - config.network_manager = connection_context_->default_network_manager(); - config.socket_factory = connection_context_->default_socket_factory(); + config.audio_streaming_language_code = cc.audio_streaming_language_code; + config.network_manager = signaling_thread_->BlockingCall( + [this]() { return connection_context_->default_network_manager(); }); + config.socket_factory = signaling_thread_->BlockingCall( + [this]() { return connection_context_->default_socket_factory(); }); signaling_ = sora::SoraSignaling::Create(std::move(config)); signaling_->Connect(); @@ -505,27 +526,25 @@ rtc::scoped_refptr Sora::CreateADM( rtc::scoped_refptr adm; if (dummy_audio) { - adm = worker_thread->Invoke>( - RTC_FROM_HERE, [&] { - return webrtc::AudioDeviceModule::Create( - webrtc::AudioDeviceModule::kDummyAudio, task_queue_factory); - }); + adm = worker_thread->BlockingCall([&] { + return webrtc::AudioDeviceModule::Create( + webrtc::AudioDeviceModule::kDummyAudio, task_queue_factory); + }); } else { sora::AudioDeviceModuleConfig config; config.audio_layer = webrtc::AudioDeviceModule::kPlatformDefaultAudio; config.task_queue_factory = task_queue_factory; config.jni_env = jni_env; config.application_context = android_context; - adm = worker_thread->Invoke>( - RTC_FROM_HERE, [&] { return sora::CreateAudioDeviceModule(config); }); + adm = worker_thread->BlockingCall( + [&] { return sora::CreateAudioDeviceModule(config); }); } - return worker_thread->Invoke>( - RTC_FROM_HERE, [&] { - return UnityAudioDevice::Create(adm, !unity_audio_input, - !unity_audio_output, on_handle_audio, - task_queue_factory); - }); + return worker_thread->BlockingCall([&] { + return UnityAudioDevice::Create(adm, !unity_audio_input, + !unity_audio_output, on_handle_audio, + task_queue_factory); + }); } bool Sora::InitADM(rtc::scoped_refptr adm, @@ -705,6 +724,11 @@ sora_conf::ErrorCode Sora::ToErrorCode(sora::SoraSignalingErrorCode ec) { } void Sora::OnSetOffer(std::string offer) { + PushEvent([this, offer]() { + if (on_set_offer_) { + on_set_offer_(offer); + } + }); std::string stream_id = rtc::CreateRandomString(16); if (audio_track_ != nullptr) { webrtc::RTCErrorOr> diff --git a/src/sora.h b/src/sora.h index acfd5b6..84c2ae8 100644 --- a/src/sora.h +++ b/src/sora.h @@ -42,6 +42,7 @@ class Sora : public std::enable_shared_from_this, void SetOnAddTrack(std::function on_add_track); void SetOnRemoveTrack( std::function on_remove_track); + void SetOnSetOffer(std::function on_set_offer); void SetOnNotify(std::function on_notify); void SetOnPush(std::function on_push); void SetOnMessage(std::function on_message); @@ -141,6 +142,7 @@ class Sora : public std::enable_shared_from_this, rtc::scoped_refptr video_track_; std::function on_add_track_; std::function on_remove_track_; + std::function on_set_offer_; std::function on_notify_; std::function on_push_; std::function on_message_; diff --git a/src/unity.cpp b/src/unity.cpp index 6ceed5c..3e6b72c 100644 --- a/src/unity.cpp +++ b/src/unity.cpp @@ -65,6 +65,15 @@ void sora_set_on_remove_track(void* p, }); } +void sora_set_on_set_offer(void* p, + set_offer_cb_t on_set_offer, + void* userdata) { + auto wsora = (SoraWrapper*)p; + wsora->sora->SetOnSetOffer([on_set_offer, userdata](std::string json) { + on_set_offer(json.c_str(), userdata); + }); +} + void sora_set_on_notify(void* p, notify_cb_t on_notify, void* userdata) { auto wsora = (SoraWrapper*)p; wsora->sora->SetOnNotify([on_notify, userdata](std::string json) { @@ -212,6 +221,14 @@ unity_bool_t sora_is_h264_supported() { #endif } +void sora_setenv(const char* name, const char* value) { +#if defined(SORA_UNITY_SDK_WINDOWS) + _putenv_s(name, value); +#else + setenv(name, value, 1); +#endif +} + unity_bool_t sora_get_audio_enabled(void* p) { auto wsora = (SoraWrapper*)p; return wsora->sora->GetAudioEnabled(); diff --git a/src/unity.h b/src/unity.h index a851701..3007cf2 100644 --- a/src/unity.h +++ b/src/unity.h @@ -15,6 +15,7 @@ typedef int32_t unity_bool_t; typedef void (*track_cb_t)(ptrid_t track_id, const char* connection_id, void* userdata); +typedef void (*set_offer_cb_t)(const char* json, void* userdata); typedef void (*notify_cb_t)(const char* json, void* userdata); typedef void (*push_cb_t)(const char* json, void* userdata); typedef void (*stats_cb_t)(const char* json, void* userdata); @@ -35,6 +36,9 @@ UNITY_INTERFACE_EXPORT void sora_set_on_add_track(void* p, UNITY_INTERFACE_EXPORT void sora_set_on_remove_track(void* p, track_cb_t on_remove_track, void* userdata); +UNITY_INTERFACE_EXPORT void sora_set_on_set_offer(void* p, + set_offer_cb_t on_set_offer, + void* userdata); UNITY_INTERFACE_EXPORT void sora_set_on_notify(void* p, notify_cb_t on_notify, void* userdata); @@ -93,11 +97,14 @@ sora_device_enum_audio_recording(device_enum_cb_t f, void* userdata); UNITY_INTERFACE_EXPORT unity_bool_t sora_device_enum_audio_playout(device_enum_cb_t f, void* userdata); UNITY_INTERFACE_EXPORT unity_bool_t sora_is_h264_supported(); +UNITY_INTERFACE_EXPORT void sora_setenv(const char* name, const char* value); UNITY_INTERFACE_EXPORT unity_bool_t sora_get_audio_enabled(void* p); -UNITY_INTERFACE_EXPORT void sora_set_audio_enabled(void* p, unity_bool_t enabled); +UNITY_INTERFACE_EXPORT void sora_set_audio_enabled(void* p, + unity_bool_t enabled); UNITY_INTERFACE_EXPORT unity_bool_t sora_get_video_enabled(void* p); -UNITY_INTERFACE_EXPORT void sora_set_video_enabled(void* p, unity_bool_t enabled); +UNITY_INTERFACE_EXPORT void sora_set_video_enabled(void* p, + unity_bool_t enabled); #ifdef __cplusplus }