From 93cde05256b0544f16a5760f84458425736ef787 Mon Sep 17 00:00:00 2001 From: Antoni Buszta Date: Mon, 25 Sep 2023 14:06:30 +0200 Subject: [PATCH 1/2] DIOS-2378 Fix OBS WebRTC not reaching TURN server --- plugins/obs-outputs/WebRTCStream.cpp | 143 +++++++++++------- plugins/obs-outputs/WebRTCStream.h | 6 + .../MillicastWebsocketClientImpl.cpp | 42 ++++- .../websocket-client/WebsocketClient.h | 7 +- 4 files changed, 137 insertions(+), 61 deletions(-) diff --git a/plugins/obs-outputs/WebRTCStream.cpp b/plugins/obs-outputs/WebRTCStream.cpp index a584fbf39..36de39d28 100644 --- a/plugins/obs-outputs/WebRTCStream.cpp +++ b/plugins/obs-outputs/WebRTCStream.cpp @@ -36,6 +36,17 @@ #define warn(format, ...) blog(LOG_WARNING, format, ##__VA_ARGS__) #define error(format, ...) blog(LOG_ERROR, format, ##__VA_ARGS__) +namespace +{ + +void RestoreDefaultIceServers(webrtc::PeerConnectionInterface::RTCConfiguration& config) { + webrtc::PeerConnectionInterface::IceServer ice_server; + ice_server.urls = {"stun:stun.l.google.com:19302"}; + config.servers.push_back(ice_server); +} + +} + class StatsCallback : public webrtc::RTCStatsCollectorCallback { public: rtc::scoped_refptr report() @@ -127,6 +138,9 @@ WebRTCStream::WebRTCStream(obs_output_t *output) // Initialize audio/video synchronisation audio_started_ = false; last_delivered_audio_ts_ = 0; + + // Save default STUN server + RestoreDefaultIceServers(rtc_config); } WebRTCStream::~WebRTCStream() @@ -433,16 +447,65 @@ bool WebRTCStream::start(WebRTCStream::Type type) thread.detach(); } - webrtc::PeerConnectionInterface::RTCConfiguration config; - webrtc::PeerConnectionInterface::IceServer server; - server.urls = {"stun:stun.l.google.com:19302"}; - config.servers.push_back(server); - // config.bundle_policy = webrtc::PeerConnectionInterface::kBundlePolicyMaxBundle; - // config.disable_ipv6 = true; - // config.rtcp_mux_policy = webrtc::PeerConnectionInterface::kRtcpMuxPolicyRequire; - config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan; - // config.set_cpu_adaptation(false); - // config.set_suspend_below_min_bitrate(false); + client = createWebsocketClient(type); + if (!client) { + warn("Error creating Websocket client"); + // Close Peer Connection + close(false); + // Disconnect, this will call stop on main thread + // #298 Close must be carried out on a separate thread in order to avoid deadlock + auto thread = std::thread([=]() { + obs_output_set_last_error( + output, + "There was a problem creating the websocket connection. Are you behind a firewall?"); + obs_output_signal_stop(output, + OBS_OUTPUT_CONNECT_FAILED); + }); + thread.detach(); + return false; + } + + // Extra logging + + if (type == WebRTCStream::Type::Millicast) { + // #323: Do not log publishing token + // info("Stream Name: %s\nPublishing Token: %s\n", + // username.c_str(), password.c_str()); + info("Stream Name: %s\n", username.c_str()); + url = publishApiUrl; + } + + rtc_config = {}; + + info("CONNECTING TO %s", url.c_str()); + // Connect to the signalling server + if (!client->connect(url, room, username, password, this)) { + warn("Error connecting to server"); + // Shutdown websocket connection and close Peer Connection + close(false); + // Disconnect, this will call stop on main thread + // #298 Close must be carried out on a separate thread in order to avoid deadlock + auto thread = std::thread([=]() { + obs_output_set_last_error( + output, + "There was a problem connecting to your room."); + obs_output_signal_stop(output, + OBS_OUTPUT_CONNECT_FAILED); + }); + thread.detach(); + return false; + } + + if (rtc_config.servers.empty()) { + RestoreDefaultIceServers(rtc_config); + } + + // rtc_config.bundle_policy = webrtc::PeerConnectionInterface::kBundlePolicyMaxBundle; + // rtc_config.disable_ipv6 = true; + // rtc_config.rtcp_mux_policy = webrtc::PeerConnectionInterface::kRtcpMuxPolicyRequire; + rtc_config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan; + // rtc_config.set_cpu_adaptation(false); + // rtc_config.set_suspend_below_min_bitrate(false); webrtc::PeerConnectionDependencies dependencies(this); @@ -462,7 +525,7 @@ bool WebRTCStream::start(WebRTCStream::Type type) network_field_trials); } - pc = factory->CreatePeerConnection(config, std::move(dependencies)); + pc = factory->CreatePeerConnection(rtc_config, std::move(dependencies)); if (!pc.get()) { error("Error creating Peer Connection"); @@ -553,52 +616,6 @@ bool WebRTCStream::start(WebRTCStream::Type type) pc->AddTransceiver(video_track, video_init); } - client = createWebsocketClient(type); - if (!client) { - warn("Error creating Websocket client"); - // Close Peer Connection - close(false); - // Disconnect, this will call stop on main thread - // #298 Close must be carried out on a separate thread in order to avoid deadlock - auto thread = std::thread([=]() { - obs_output_set_last_error( - output, - "There was a problem creating the websocket connection. Are you behind a firewall?"); - obs_output_signal_stop(output, - OBS_OUTPUT_CONNECT_FAILED); - }); - thread.detach(); - return false; - } - - // Extra logging - - if (type == WebRTCStream::Type::Millicast) { - // #323: Do not log publishing token - // info("Stream Name: %s\nPublishing Token: %s\n", - // username.c_str(), password.c_str()); - info("Stream Name: %s\n", username.c_str()); - url = publishApiUrl; - } - info("CONNECTING TO %s", url.c_str()); - - // Connect to the signalling server - if (!client->connect(url, room, username, password, this)) { - warn("Error connecting to server"); - // Shutdown websocket connection and close Peer Connection - close(false); - // Disconnect, this will call stop on main thread - // #298 Close must be carried out on a separate thread in order to avoid deadlock - auto thread = std::thread([=]() { - obs_output_set_last_error( - output, - "There was a problem connecting to your room."); - obs_output_signal_stop(output, - OBS_OUTPUT_CONNECT_FAILED); - }); - thread.detach(); - return false; - } return true; } @@ -782,6 +799,18 @@ void WebRTCStream::onRemoteIceCandidate(const std::string &sdpData) } } +void WebRTCStream::onIceServer( + const std::vector &urls, + const std::string &username, + const std::string &password) +{ + webrtc::PeerConnectionInterface::IceServer ice_server; + ice_server.urls = urls; + ice_server.username = username; + ice_server.password = password; + rtc_config.servers.push_back(ice_server); +} + void WebRTCStream::onOpened(const std::string &sdp) { info("ANSWER:\n\n%s\n", sdp.c_str()); diff --git a/plugins/obs-outputs/WebRTCStream.h b/plugins/obs-outputs/WebRTCStream.h index 1817cd07d..8a20c5433 100644 --- a/plugins/obs-outputs/WebRTCStream.h +++ b/plugins/obs-outputs/WebRTCStream.h @@ -83,6 +83,9 @@ class WebRTCStream : public rtc::RefCountedObject { void onOpened(const std::string &sdp) override; void onOpenedError(int code) override; void onRemoteIceCandidate(const std::string &sdpData) override; + void onIceServer(const std::vector &urls, + const std::string &username, + const std::string &password) override; // // PeerConnectionObserver implementation. @@ -300,6 +303,9 @@ class WebRTCStream : public rtc::RefCountedObject { // Websocket client WebsocketClient *client; + + // RTC configuration + webrtc::PeerConnectionInterface::RTCConfiguration rtc_config; }; #endif diff --git a/plugins/obs-outputs/websocket-client/MillicastWebsocketClientImpl.cpp b/plugins/obs-outputs/websocket-client/MillicastWebsocketClientImpl.cpp index 71ceefc21..37f30b876 100644 --- a/plugins/obs-outputs/websocket-client/MillicastWebsocketClientImpl.cpp +++ b/plugins/obs-outputs/websocket-client/MillicastWebsocketClientImpl.cpp @@ -3384,9 +3384,24 @@ static std::string curl_cainfo_blob( "-----END CERTIFICATE-----\n"); #endif +namespace { + using json = nlohmann::json; typedef websocketpp::config::asio_client::message_type::ptr message_ptr; +template +bool find_json_value(const nlohmann::json& data, const std::string& key, T& result) +{ + auto it = data.find(key); + if(it != data.end() && !it->is_null()) { + result = it->get(); + return true; + } + return false; +} + +} + MillicastWebsocketClientImpl::MillicastWebsocketClientImpl() { // Set logging to be pretty verbose (everything except message payloads) @@ -3433,8 +3448,31 @@ bool MillicastWebsocketClientImpl::connect(const std::string &publish_api_url, std::string jwt; if (r.code == 200) { auto wssData = json::parse(r.body); - url = wssData["data"]["urls"][0].get(); - jwt = wssData["data"]["jwt"].get(); + auto data = wssData["data"]; + url = data["urls"][0].get(); + jwt = data["jwt"].get(); + + std::vector ice_servers; + if (find_json_value(data, "iceServers", ice_servers)) { + for (auto &value : ice_servers) { + std::vector urls_json; + std::vector urls; + if (find_json_value(value, "urls", urls_json)) { + std::transform( + urls_json.begin(), urls_json.end(), std::back_inserter(urls), + [](const json &v) -> std::string { return v.get(); }); + } + + std::string username; + find_json_value(value, "username", username); + + std::string password; + find_json_value(value, "credential", password); + + listener->onIceServer(urls, username, password); + } + } + // #323: Do not log publishing token // info("WSS url: %s", url.c_str()); // info("JWT (token): %s", jwt.c_str()); diff --git a/plugins/obs-outputs/websocket-client/WebsocketClient.h b/plugins/obs-outputs/websocket-client/WebsocketClient.h index 27ef68f43..9fdb3cfc7 100644 --- a/plugins/obs-outputs/websocket-client/WebsocketClient.h +++ b/plugins/obs-outputs/websocket-client/WebsocketClient.h @@ -18,6 +18,7 @@ #endif #include +#include enum Type { Millicast = 0, CustomWebrtc = 1 }; @@ -32,8 +33,10 @@ class WEBSOCKETCLIENT_API WebsocketClient { virtual void onLoggedError(int code) = 0; virtual void onOpened(const std::string &sdp) = 0; virtual void onOpenedError(int code) = 0; - virtual void - onRemoteIceCandidate(const std::string &sdpData) = 0; + virtual void onRemoteIceCandidate(const std::string &sdpData) = 0; + virtual void onIceServer(const std::vector &urls, + const std::string &username, + const std::string &password) = 0; }; public: From 2f8d29ce7e889bb0956e445911af607542d0904b Mon Sep 17 00:00:00 2001 From: Marek Sobolak Date: Fri, 6 Oct 2023 15:09:58 +0200 Subject: [PATCH 2/2] DIOS-2498 Fix access token generation --- .github/actions/download_libwebrtc/action.yml | 3 +- .../actions/download_libwebrtc/win/action.yml | 3 +- .github/workflows/macOSarm64.yml | 235 ------------------ .github/workflows/main.yml | 71 +++--- 4 files changed, 41 insertions(+), 271 deletions(-) delete mode 100644 .github/workflows/macOSarm64.yml diff --git a/.github/actions/download_libwebrtc/action.yml b/.github/actions/download_libwebrtc/action.yml index 4e3d6ca81..397067d7c 100644 --- a/.github/actions/download_libwebrtc/action.yml +++ b/.github/actions/download_libwebrtc/action.yml @@ -2,7 +2,7 @@ name: 'Download libWebRTC' description: 'Download libWebRTC' inputs: access_token: - description: 'GH App Installation access token - base64' + description: 'GH App Installation access token' required: true release_tag: description: 'LibWebRTC release tag.' @@ -17,7 +17,6 @@ runs: - run: | echo "Looking for libwebrtc using the pattern: ${LIBWEBRTC_ASSETS_PATTERN}" echo "LibWebRTC release tag: ${LIBWEBRTC_RELEASE_TAG}" - export GH_ACCESS_TOKEN_1H_EXPIRATION=$(echo ${GH_ACCESS_TOKEN_1H_EXPIRATION} | base64 -d) export LIBWEBRTC_RELEASE_URL=$(curl -L -H "Accept: application/vnd.github+json" -H "Authorization: Bearer ${GH_ACCESS_TOKEN_1H_EXPIRATION}" -H "X-GitHub-Api-Version: 2022-11-28" https://api.github.com/repos/CoSMoSoftware/libwebrtc-cmake/releases/tags/${LIBWEBRTC_RELEASE_TAG} | jq .url | tr -d '"') echo "LIBWEBRTC_RELEASE_URL: ${LIBWEBRTC_RELEASE_URL}" curl -L -H "Accept: application/vnd.github+json" -H "Authorization: Bearer ${GH_ACCESS_TOKEN_1H_EXPIRATION}" -H "X-GitHub-Api-Version: 2022-11-28" ${LIBWEBRTC_RELEASE_URL}/assets > assets.json diff --git a/.github/actions/download_libwebrtc/win/action.yml b/.github/actions/download_libwebrtc/win/action.yml index eed715c77..9dd9c0c5a 100644 --- a/.github/actions/download_libwebrtc/win/action.yml +++ b/.github/actions/download_libwebrtc/win/action.yml @@ -2,7 +2,7 @@ name: 'Download libWebRTC' description: 'Download libWebRTC' inputs: access_token: - description: 'GH App Installation access token - base64' + description: 'GH App Installation access token' required: true release_tag: description: 'LibWebRTC release tag.' @@ -17,7 +17,6 @@ runs: - run: | Write-Host "Looking for libwebrtc using the pattern: $env:LIBWEBRTC_ASSETS_PATTERN" Write-Host "LibWebRTC release tag: $env:LIBWEBRTC_RELEASE_TAG" - $env:GH_ACCESS_TOKEN_1H_EXPIRATION = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($env:GH_ACCESS_TOKEN_1H_EXPIRATION)).Trim() $env:LIBWEBRTC_RELEASE_URL = cmd.exe /c curl -L -H "Accept: application/vnd.github+json" -H "Authorization: Bearer $env:GH_ACCESS_TOKEN_1H_EXPIRATION" -H "X-GitHub-Api-Version: 2022-11-28" "https://api.github.com/repos/CoSMoSoftware/libwebrtc-cmake/releases/tags/$env:LIBWEBRTC_RELEASE_TAG" | jq -r .url Write-Host $env:LIBWEBRTC_RELEASE_URL diff --git a/.github/workflows/macOSarm64.yml b/.github/workflows/macOSarm64.yml deleted file mode 100644 index a77def878..000000000 --- a/.github/workflows/macOSarm64.yml +++ /dev/null @@ -1,235 +0,0 @@ -name: 'BUILD-MACOS-ARM64' - -on: - push: - paths-ignore: ['**.md'] - branches: - - master - - 'release/**' - - "m**" - tags: ['m*'] - pull_request: - paths-ignore: ['**.md'] - branches: [master] - -env: - CACHE_REVISION: '006' - CEF_BUILD_VERSION_MAC: '5060' - CEF_HASH_MAC_X86_64: '88b950aa0bfc001061c35e7f1f3fefba856a6afb35e38b2b7b42ddd8dd239182' - CEF_HASH_MAC_ARM64: '98679b92eea6ea9959ac5aa54f46ca60681d8a86c768c35f496dbdd409bf0642' - CEF_BUILD_VERSION_LINUX: '5060' - CEF_BUILD_VERSION_WIN: '5060' - QT_VERSION_MAC: '6.3.1' - QT_HASH_MAC_X86_64: 'a83f72a11023b03b6cb2dc365f0a66ad9df31163bbb4fe2df32d601856a9fad3' - QT_HASH_MAC_ARM64: '2f30af90c049670a5660656adbb440668aa1b0567f75a5f29e1def9108928403' - QT_HASH_MAC_UNIVERSAL: '252e6684f43ab9c6f262c73af739e2296ce391b998da2c4ee04c254aaa07db18' - QT_VERSION_WIN: '6.3.1' - DEPS_VERSION_MAC: '2022-08-02' - DEPS_HASH_MAC_X86_64: '7637e52305e6fc53014b5aabd583f1a4490b1d97450420e977cae9a336a29525' - DEPS_HASH_MAC_ARM64: '755e0fa69b17a3ae444e1befa9d91d77e3cafe628fbd1c6333686091826595cd' - DEPS_VERSION_WIN: '2022-08-02' - VLC_VERSION_MAC: '3.0.8' - VLC_HASH_MAC: 'e0149ef4a20a19b9ecd87309c2d27787ee3f47dfd47c6639644bc1f6fd95bdf6' - VLC_VERSION_WIN: '3.0.0-git' - TWITCH_CLIENTID: ${{ secrets.TWITCH_CLIENT_ID }} - TWITCH_HASH: ${{ secrets.TWITCH_HASH }} - RESTREAM_CLIENTID: ${{ secrets.RESTREAM_CLIENTID }} - RESTREAM_HASH: ${{ secrets.RESTREAM_HASH }} - YOUTUBE_CLIENTID: ${{ secrets.YOUTUBE_CLIENTID }} - YOUTUBE_CLIENTID_HASH: ${{ secrets.YOUTUBE_CLIENTID_HASH }} - YOUTUBE_SECRET: ${{ secrets.YOUTUBE_SECRET }} - YOUTUBE_SECRET_HASH: ${{ secrets.YOUTUBE_SECRET_HASH }} - OBS_VERSION: "1.5.1-28.1.2-m112" - LIBWEBRTC_RELEASE_TAG: "m112-release" - LIBWEBRTC_VERSION: "112.0" - WORKSPACE_ROOT: "obs-studio" - -jobs: - macos_build: - name: 'MACOS-ARM64' - runs-on: ['self-hosted', 'macOS', 'ARM64'] - strategy: - matrix: - arch: ['arm64'] - env: - MACOSX_DEPLOYMENT_TARGET_X86_64: '10.15' - MACOSX_DEPLOYMENT_TARGET_ARM64: '11.0' - SPARKLE_VERSION: '1.26.0' - SPARKLE_HASH: '8312cbf7528297a49f1b97692c33cb8d33254c396dc51be394e9484e4b6833a0' - BLOCKED_FORMULAS: 'speexdsp curl php composer' - CODESIGN_IDENT: '-' - HAVE_CODESIGN_IDENTITY: ${{ secrets.MACOS_SIGNING_IDENTITY != '' && secrets.MACOS_SIGNING_CERT != '' }} - defaults: - run: - shell: bash - working-directory: ${{ env.WORKSPACE_ROOT }} - steps: - - name: 'Checkout' - uses: actions/checkout@v3 - with: - submodules: 'recursive' - path: ${{ env.WORKSPACE_ROOT }} - fetch-depth: 0 - - - name: 'Check for Github Labels' - run: | - if test -n "$(curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" -s "${{ github.event.pull_request.url }}" | jq -e '.labels[] | select(.name == "Seeking Testers")')"; then - echo "SEEKING_TESTERS=1" >> $GITHUB_ENV - else - echo "SEEKING_TESTERS=0" >> $GITHUB_ENV - fi - - echo "CACHE_DATE=$(date +"%Y-%m-%d")" >> $GITHUB_ENV - - - name: 'Restore ccache from cache' - id: ccache-cache - uses: actions/cache@v3 - env: - CACHE_NAME: 'ccache-cache' - with: - path: ${{ github.workspace }}/.ccache - key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ matrix.arch }}-${{ env.CACHE_DATE }} - - - name: 'Restore Chromium Embedded Framework from cache' - id: cef-cache - uses: actions/cache@v3 - env: - CACHE_NAME: 'cef-cache' - with: - path: ${{ github.workspace }}/obs-build-dependencies/cef_binary_${{ env.CEF_BUILD_VERSION_MAC }}_macos_${{ matrix.arch }} - key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ env.CEF_BUILD_VERSION_MAC }}-${{ matrix.arch }}-${{ env.CACHE_REVISION }} - - - name: 'Restore VLC dependency from cache' - id: vlc-cache - uses: actions/cache@v3 - env: - CACHE_NAME: 'vlc-cache' - with: - path: ${{ github.workspace }}/obs-build-dependencies/vlc-${{ env.VLC_VERSION_MAC }} - key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ env.VLC_VERSION_MAC }}-${{ env.CACHE_REVISION }} - - - name: 'Restore Sparkle dependency from cache' - id: sparkle-cache - uses: actions/cache@v3 - env: - CACHE_NAME: 'sparkle-cache' - with: - path: ${{ github.workspace }}/obs-build-dependencies/obs-deps/lib/Sparkle.framework - key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ env.SPARKLE_VERSION }}-${{ env.CACHE_REVISION }} - - - name: 'Setup build environment' - id: setup - run: | - REMOVE_FORMULAS="" - for FORMULA in ${{ env.BLOCKED_FORMULAS }}; do - if [ -d "/usr/local/opt/${FORMULA}" ]; then - REMOVE_FORMULAS="${REMOVE_FORMULAS}${FORMULA} " - fi - done - - if [ -n "${REMOVE_FORMULAS}" ]; then - brew uninstall ${REMOVE_FORMULAS} - fi - - echo "commitHash=$(git rev-parse --short=9 HEAD)" >> $GITHUB_OUTPUT - - - name: Download libwebrtc - env: - LIBWEBRTC_RELEASE_TAG: ${{ env.LIBWEBRTC_RELEASE_TAG }} - LIBWEBRTC_ASSETS_PATTERN: "^libWebRTC-${{ env.LIBWEBRTC_VERSION }}-.*64-Release-H264-OpenSSL_1_1_1.*.dmg.*" - GH_APP_RELEASECREATOR_TOKEN_PYTHON_SCRIPT: ${{ secrets.GH_APP_RELEASECREATOR_TOKEN_PYTHON_SCRIPT }} - GH_APP_RELEASECREATOR_PRIV_KEY: ${{ secrets.GH_APP_RELEASECREATOR_PRIV_KEY }} - GH_APP_ID: ${{ secrets.GH_APP_ID }} - GH_APP_INSTALLATION_ID: ${{ secrets.GH_APP_INSTALLATION_ID }} - run: | - python3 -m pip install jwt requests - echo ${GH_APP_RELEASECREATOR_TOKEN_PYTHON_SCRIPT} | base64 -d > ./generate_gh_app_installation_token.py - echo ${GH_APP_RELEASECREATOR_PRIV_KEY} | base64 -d > ./gh_app_priv_key.pem - export PEM_FILE=./gh_app_priv_key.pem - export GH_ACCESS_TOKEN_1H_EXPIRATION=$( python3 ./generate_gh_app_installation_token.py ) - rm ./gh_app_priv_key.pem ./generate_gh_app_installation_token.py - echo "GH_ACCESS_TOKEN_1H_EXPIRATION=${GH_ACCESS_TOKEN_1H_EXPIRATION}" >> $GITHUB_OUTPUT - echo "GH_ACCESS_TOKEN_1H_EXPIRATION is ready!" - - echo "Looking for libwebrtc using the pattern: ${LIBWEBRTC_ASSETS_PATTERN}" - echo "LibWebRTC release tag: ${LIBWEBRTC_RELEASE_TAG}" - export LIBWEBRTC_RELEASE_URL=$(curl -L -H "Accept: application/vnd.github+json" -H "Authorization: Bearer ${GH_ACCESS_TOKEN_1H_EXPIRATION}" -H "X-GitHub-Api-Version: 2022-11-28" https://api.github.com/repos/CoSMoSoftware/libwebrtc-cmake/releases/tags/${LIBWEBRTC_RELEASE_TAG} | jq .url | tr -d '"') - echo "LIBWEBRTC_RELEASE_URL: ${LIBWEBRTC_RELEASE_URL}" - curl -L -H "Accept: application/vnd.github+json" -H "Authorization: Bearer ${GH_ACCESS_TOKEN_1H_EXPIRATION}" -H "X-GitHub-Api-Version: 2022-11-28" ${LIBWEBRTC_RELEASE_URL}/assets > assets.json - for asset_pair in $(cat assets.json | jq '.[] | (.id|tostring) + "|" + .name' | tr -d '"') - do - asset_pair=( ${asset_pair//|/ } ) - if [[ $(echo ${asset_pair[1]} | grep -e ${LIBWEBRTC_ASSETS_PATTERN}) ]]; then - echo "Downloading ${asset_pair[1]} from GitHub - GH_ASSET_ID: ${asset_pair[0]}..." - curl -L -H "Accept: application/octet-stream" -H "Authorization: Bearer ${GH_ACCESS_TOKEN_1H_EXPIRATION}" -H "X-GitHub-Api-Version: 2022-11-28" https://api.github.com/repos/CoSMoSoftware/libwebrtc-cmake/releases/assets/${asset_pair[0]} > ${asset_pair[1]} - fi - done - rm assets.json - - - name: 'Install dependencies' - env: - RESTORED_VLC: ${{ steps.vlc-cache.outputs.cache-hit }} - RESTORED_SPARKLE: ${{ steps.sparkle-cache.outputs.cache-hit }} - RESTORED_CEF: ${{ steps.cef-cache.outputs.cache-hit }} - run: CI/macos/01_install_dependencies.sh --architecture "${{ matrix.arch }}" - - - name: 'Unlock keychain' - run: | - security -v unlock-keychain -p ${MACOS_KEYCHAIN_PASSWORD} ${MACOS_KEYCHAIN_PATH} - env: - MACOS_KEYCHAIN_PASSWORD: ${{ secrets.MACOS_KEYCHAIN_PASSWORD }} - MACOS_KEYCHAIN_PATH: /Users/dolbyvoice/Library/Keychains/cosmosoftware.keychain-db - - # Geneate OBS without obs-ndi plugin - - name: 'Build OBS - no NDI' - run: CI/macos/02_build_obs.sh --codesign --architecture "${{ matrix.arch }}" - env: - CODESIGN_IDENT: ${{ secrets.CODESIGN_IDENT }} - CODESIGN_TEAM_ID: ${{ secrets.CODESIGN_TEAM_ID }} - CODESIGN_IDENT_USER: ${{ secrets.CODESIGN_IDENT_USER }} - NOTARIZE_APP_SPECIFIC_PASSWORD: ${{ secrets.NOTARIZE_APP_SPECIFIC_PASSWORD }} - - - name: 'Create build artifact' - run: | - CI/macos/03_package_obs.sh --codesign --architecture "${{ matrix.arch }}" - ARTIFACT_NAME=$(basename $(find build/. -name "obs-webrtc*.dmg")) - echo "FILE_NAME=${ARTIFACT_NAME}" >> $GITHUB_ENV - echo "ARTIFACT READY: ${ARTIFACT_NAME}" - env: - CODESIGN_IDENT: ${{ secrets.CODESIGN_IDENT }} - CODESIGN_TEAM_ID: ${{ secrets.CODESIGN_TEAM_ID }} - CODESIGN_IDENT_USER: ${{ secrets.CODESIGN_IDENT_USER }} - NOTARIZE_APP_SPECIFIC_PASSWORD: ${{ secrets.NOTARIZE_APP_SPECIFIC_PASSWORD }} - - - name: 'Upload build Artifact' - uses: actions/upload-artifact@v3 - with: - name: 'obs-studio-macos-${{ matrix.arch }}-${{ steps.setup.outputs.commitHash }}' - path: '${{ github.workspace }}/obs-studio/build/${{ env.FILE_NAME }}' - - # Geneate OBS with obs-ndi plugin - - name: 'Build OBS - with NDI' - run: CI/macos/02_build_obs.sh --codesign --architecture "${{ matrix.arch }}" --ndi - env: - CODESIGN_IDENT: ${{ secrets.CODESIGN_IDENT }} - CODESIGN_TEAM_ID: ${{ secrets.CODESIGN_TEAM_ID }} - CODESIGN_IDENT_USER: ${{ secrets.CODESIGN_IDENT_USER }} - NOTARIZE_APP_SPECIFIC_PASSWORD: ${{ secrets.NOTARIZE_APP_SPECIFIC_PASSWORD }} - - - name: 'Create build artifact' - run: | - CI/macos/03_package_obs.sh --codesign --architecture "${{ matrix.arch }}" --ndi - ARTIFACT_NAME=$(basename $(find build/. -name "obs-webrtc-ndi*.dmg")) - echo "FILE_NAME=${ARTIFACT_NAME}" >> $GITHUB_ENV - echo "ARTIFACT READY: ${ARTIFACT_NAME}" - env: - CODESIGN_IDENT: ${{ secrets.CODESIGN_IDENT }} - CODESIGN_TEAM_ID: ${{ secrets.CODESIGN_TEAM_ID }} - CODESIGN_IDENT_USER: ${{ secrets.CODESIGN_IDENT_USER }} - NOTARIZE_APP_SPECIFIC_PASSWORD: ${{ secrets.NOTARIZE_APP_SPECIFIC_PASSWORD }} - - - name: 'Upload build Artifact' - uses: actions/upload-artifact@v3 - with: - name: 'obs-studio-macos-${{ matrix.arch }}-${{ steps.setup.outputs.commitHash }}-ndi' - path: '${{ github.workspace }}/obs-studio/build/${{ env.FILE_NAME }}' diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7ce1e8408..141384cab 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -7,6 +7,7 @@ on: pull_request: paths-ignore: ['**.md'] branches: ['m**'] + workflow_dispatch: env: CACHE_REVISION: '006' @@ -41,27 +42,9 @@ env: VENDOR: "Millicast" jobs: - preprocessing: - name: "Preprocessing" - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v3 - - name: Generate access token - id: gh_access_token - uses: ./.github/actions/gh_access_token - with: - gh_app_priv_key: ${{ secrets.GH_APP_RELEASECREATOR_PRIV_KEY }} - gh_app_id: ${{ secrets.GH_APP_ID }} - gh_app_installation_id: ${{ secrets.GH_APP_INSTALLATION_ID }} - outputs: - gh_access_token: ${{ steps.gh_access_token.outputs.token }} - macos_build_x86_64: name: 'MacOS-x86_64' runs-on: [macos-12] - needs: preprocessing - if: success() env: MACOSX_DEPLOYMENT_TARGET_X86_64: '10.15' SPARKLE_VERSION: '1.26.0' @@ -74,14 +57,21 @@ jobs: shell: bash steps: - name: 'Checkout' - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: 'recursive' fetch-depth: 0 + - name: 'Generate access token' + id: accessToken + uses: dolby-io-internal/gh-access@v0.0.3-macos-linux + with: + gh_app_priv_key: ${{ secrets.GH_APP_RELEASECREATOR_PRIV_KEY }} + gh_app_id: ${{ secrets.GH_APP_ID }} + gh_app_installation_id: ${{ secrets.GH_APP_INSTALLATION_ID }} - name: 'Download libWebRTC' uses: ./.github/actions/download_libwebrtc with: - access_token: ${{ needs.preprocessing.outputs.gh_access_token }} + access_token: ${{ steps.accessToken.outputs.token }} release_tag: ${{ env.LIBWEBRTC_RELEASE_TAG }} asset_pattern: "^libWebRTC-${{ env.LIBWEBRTC_VERSION }}-x64-Release-H264-OpenSSL_1_1_1.*.dmg.*" @@ -226,8 +216,6 @@ jobs: macos_build_arm64: name: 'MacOS-arm64' runs-on: ['self-hosted', 'macOS', 'ARM64'] - needs: preprocessing - if: success() env: MACOSX_DEPLOYMENT_TARGET_ARM64: '11.0' SPARKLE_VERSION: '1.26.0' @@ -240,14 +228,21 @@ jobs: shell: bash steps: - name: 'Checkout' - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: 'recursive' fetch-depth: 0 + - name: 'Generate access token' + id: accessToken + uses: dolby-io-internal/gh-access@v0.0.3-macos-linux + with: + gh_app_priv_key: ${{ secrets.GH_APP_RELEASECREATOR_PRIV_KEY }} + gh_app_id: ${{ secrets.GH_APP_ID }} + gh_app_installation_id: ${{ secrets.GH_APP_INSTALLATION_ID }} - name: 'Download libWebRTC' uses: ./.github/actions/download_libwebrtc with: - access_token: ${{ needs.preprocessing.outputs.gh_access_token }} + access_token: ${{ steps.accessToken.outputs.token }} release_tag: ${{ env.LIBWEBRTC_RELEASE_TAG }} asset_pattern: "^libWebRTC-${{ env.LIBWEBRTC_VERSION }}-arm64-Release-H264-OpenSSL_1_1_1.*.dmg.*" @@ -386,21 +381,28 @@ jobs: matrix: ubuntu: ['ubuntu-20.04', 'ubuntu-22.04'] runs-on: ${{ matrix.ubuntu }} - needs: preprocessing - if: always() defaults: run: shell: bash steps: - name: 'Checkout' - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: 'recursive' fetch-depth: 0 + - name: 'Install python dependencies' + run: python3 -m pip install pyopenssl --upgrade + - name: 'Generate access token' + id: accessToken + uses: dolby-io-internal/gh-access@v0.0.3-macos-linux + with: + gh_app_priv_key: ${{ secrets.GH_APP_RELEASECREATOR_PRIV_KEY }} + gh_app_id: ${{ secrets.GH_APP_ID }} + gh_app_installation_id: ${{ secrets.GH_APP_INSTALLATION_ID }} - name: 'Download libWebRTC' uses: ./.github/actions/download_libwebrtc with: - access_token: ${{ needs.preprocessing.outputs.gh_access_token }} + access_token: ${{ steps.accessToken.outputs.token }} release_tag: ${{ env.LIBWEBRTC_RELEASE_TAG }} asset_pattern: "^libWebRTC-${{ env.LIBWEBRTC_VERSION }}-.*64-Release-.*.sh.*" @@ -471,8 +473,6 @@ jobs: windows_build: name: 'Windows_x64' runs-on: [windows-2022] - needs: preprocessing - if: always() env: CMAKE_GENERATOR: 'Visual Studio 17 2022' CMAKE_SYSTEM_VERSION: '10.0.18363.657' @@ -480,14 +480,21 @@ jobs: TARGET_ARCH: 'x64' steps: - name: 'Checkout' - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: 'recursive' fetch-depth: 0 + - name: 'Generate access token' + id: accessToken + uses: dolby-io-internal/gh-access@v0.0.3-windows + with: + gh_app_priv_key: ${{ secrets.GH_APP_RELEASECREATOR_PRIV_KEY }} + gh_app_id: ${{ secrets.GH_APP_ID }} + gh_app_installation_id: ${{ secrets.GH_APP_INSTALLATION_ID }} - name: 'Download libWebRTC' uses: ./.github/actions/download_libwebrtc/win with: - access_token: ${{ needs.preprocessing.outputs.gh_access_token }} + access_token: ${{ steps.accessToken.outputs.token }} release_tag: ${{ env.LIBWEBRTC_RELEASE_TAG }} asset_pattern: "^libWebRTC-${{ env.LIBWEBRTC_VERSION }}-x64-Mt-Release-.*.exe.*"