From ecc0322298aff7d6996554eba021647be5fe7a41 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 10 Dec 2025 15:01:23 +0000 Subject: [PATCH 1/8] Initial plan From b4d95332e44d431fb42b56c16904d99034fa716d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 10 Dec 2025 15:07:46 +0000 Subject: [PATCH 2/8] Add audio support to WebRTC video player with mute/unmute controls Co-authored-by: bgoncal <5808343+bgoncal@users.noreply.github.com> --- .../Resources/en.lproj/Localizable.strings | 2 +- Sources/App/WebView/WebRTC/WebRTCClient.swift | 45 +++++++++++++++++-- .../WebRTC/WebRTCVideoPlayerView.swift | 8 ++-- .../WebRTCVideoPlayerViewControls.swift | 20 ++++++++- .../WebRTC/WebRTCViewPlayerViewModel.swift | 12 +++++ 5 files changed, 77 insertions(+), 10 deletions(-) diff --git a/Sources/App/Resources/en.lproj/Localizable.strings b/Sources/App/Resources/en.lproj/Localizable.strings index f03a39640e..e598cbb585 100644 --- a/Sources/App/Resources/en.lproj/Localizable.strings +++ b/Sources/App/Resources/en.lproj/Localizable.strings @@ -1,4 +1,4 @@ -"WebRTC_player.experimental.disclaimer" = "Note: Native WebRTC video player is currently an experimental feature, audio may not work and microphone permission and usage may be requested even though not in use. Please use the web player interface for advanced options and reliable playback."; +"WebRTC_player.experimental.disclaimer" = "Note: Native WebRTC video player is currently an experimental feature. Please use the web player interface for advanced options and reliable playback."; "about.acknowledgements.title" = "Acknowledgements"; "about.beta.title" = "Join Beta"; "about.chat.title" = "Chat"; diff --git a/Sources/App/WebView/WebRTC/WebRTCClient.swift b/Sources/App/WebView/WebRTC/WebRTCClient.swift index a096a41bdb..5c99bec254 100644 --- a/Sources/App/WebView/WebRTC/WebRTCClient.swift +++ b/Sources/App/WebView/WebRTC/WebRTCClient.swift @@ -34,6 +34,7 @@ final class WebRTCClient: NSObject { ] private var videoCapturer: RTCVideoCapturer? private var remoteVideoTrack: RTCVideoTrack? + private var remoteAudioTrack: RTCAudioTrack? private var remoteDataChannel: RTCDataChannel? @available(*, unavailable) @@ -70,10 +71,7 @@ final class WebRTCClient: NSObject { self.peerConnection = peerConnection super.init() createMediaTracks() - - // This is currently disable since the library does not offer a way to disable just the microphone usage. - // TODO: Find a workaround so audio can be receveid without using microphone in parallel - RTCAudioSession.sharedInstance().useManualAudio = true + configureAudioSession() self.peerConnection.delegate = self } @@ -128,12 +126,44 @@ final class WebRTCClient: NSObject { remoteVideoTrack?.add(renderer) } + func muteAudio() { + remoteAudioTrack?.isEnabled = false + } + + func unmuteAudio() { + remoteAudioTrack?.isEnabled = true + } + + func isAudioMuted() -> Bool { + guard let remoteAudioTrack else { return true } + return !remoteAudioTrack.isEnabled + } + + private func configureAudioSession() { + let audioSession = RTCAudioSession.sharedInstance() + audioSession.lockForConfiguration() + do { + // Configure for playback only (receive audio without microphone) + try audioSession.setCategory(AVAudioSession.Category.playback.rawValue) + try audioSession.setMode(AVAudioSession.Mode.spokenAudio.rawValue) + try audioSession.setActive(true) + } catch { + Current.Log.error("Failed to configure audio session: \(error.localizedDescription)") + } + audioSession.unlockForConfiguration() + } + private func createMediaTracks() { let streamId = "stream" let videoTrack = createVideoTrack() peerConnection.add(videoTrack, streamIds: [streamId]) remoteVideoTrack = peerConnection.transceivers.first { $0.mediaType == .video }?.receiver .track as? RTCVideoTrack + + let audioTrack = createAudioTrack() + peerConnection.add(audioTrack, streamIds: [streamId]) + remoteAudioTrack = peerConnection.transceivers.first { $0.mediaType == .audio }?.receiver + .track as? RTCAudioTrack } private func createVideoTrack() -> RTCVideoTrack { @@ -148,6 +178,13 @@ final class WebRTCClient: NSObject { let videoTrack = WebRTCClient.factory.videoTrack(with: videoSource, trackId: "video0") return videoTrack } + + private func createAudioTrack() -> RTCAudioTrack { + let audioConstrains = RTCMediaConstraints(mandatoryConstraints: nil, optionalConstraints: nil) + let audioSource = WebRTCClient.factory.audioSource(with: audioConstrains) + let audioTrack = WebRTCClient.factory.audioTrack(with: audioSource, trackId: "audio0") + return audioTrack + } } // MARK: - RTCPeerConnectionDelegate diff --git a/Sources/App/WebView/WebRTC/WebRTCVideoPlayerView.swift b/Sources/App/WebView/WebRTC/WebRTCVideoPlayerView.swift index fbe77784bd..1b8eb614bf 100644 --- a/Sources/App/WebView/WebRTC/WebRTCVideoPlayerView.swift +++ b/Sources/App/WebView/WebRTC/WebRTCVideoPlayerView.swift @@ -161,9 +161,11 @@ struct WebRTCVideoPlayerView: View { } private var controls: some View { - WebRTCVideoPlayerViewControls { - dismiss() - } + WebRTCVideoPlayerViewControls( + close: { dismiss() }, + isMuted: viewModel.isMuted, + toggleMute: { viewModel.toggleMute() } + ) .transition(.opacity) .animation(.easeInOut, value: viewModel.controlsVisible) .opacity(viewModel.controlsVisible || !isVideoPlaying ? 1.0 : 0.0) diff --git a/Sources/App/WebView/WebRTC/WebRTCVideoPlayerViewControls.swift b/Sources/App/WebView/WebRTC/WebRTCVideoPlayerViewControls.swift index 53c3bd587b..d30193b209 100644 --- a/Sources/App/WebView/WebRTC/WebRTCVideoPlayerViewControls.swift +++ b/Sources/App/WebView/WebRTC/WebRTCVideoPlayerViewControls.swift @@ -1,10 +1,12 @@ +import SFSafeSymbols import Shared import SwiftUI struct WebRTCVideoPlayerViewControls: View { let close: () -> Void + let isMuted: Bool + let toggleMute: () -> Void - // TODO: Include more player controls var body: some View { ZStack { VStack { @@ -16,6 +18,18 @@ struct WebRTCVideoPlayerViewControls: View { .padding(16) } Spacer() + HStack { + Button(action: toggleMute) { + Image(systemSymbol: isMuted ? .speakerSlashFill : .speakerWaveFill) + .font(.system(size: 24)) + .foregroundStyle(.white) + .padding(12) + .background(Color.black.opacity(0.5)) + .clipShape(Circle()) + } + Spacer() + } + .padding(.horizontal) Text(L10n.WebRTCPlayer.Experimental.disclaimer) .font(DesignSystem.Font.footnote.weight(.light)) .foregroundStyle(.white) @@ -37,6 +51,8 @@ struct WebRTCVideoPlayerViewControls: View { #Preview { WebRTCVideoPlayerViewControls( - close: {} + close: {}, + isMuted: false, + toggleMute: {} ) } diff --git a/Sources/App/WebView/WebRTC/WebRTCViewPlayerViewModel.swift b/Sources/App/WebView/WebRTC/WebRTCViewPlayerViewModel.swift index d5d13b5bbf..1605c456f1 100644 --- a/Sources/App/WebView/WebRTC/WebRTCViewPlayerViewModel.swift +++ b/Sources/App/WebView/WebRTC/WebRTCViewPlayerViewModel.swift @@ -29,6 +29,7 @@ final class WebRTCViewPlayerViewModel: ObservableObject { @Published var failureReason: String? @Published var showLoader: Bool = true @Published var controlsVisible: Bool = true + @Published var isMuted: Bool = false var hideControlsWorkItem: DispatchWorkItem? @@ -49,6 +50,17 @@ final class WebRTCViewPlayerViewModel: ObservableObject { DispatchQueue.main.asyncAfter(deadline: .now() + 3, execute: workItem) } + func toggleMute() { + guard let webRTCClient else { return } + if isMuted { + webRTCClient.unmuteAudio() + isMuted = false + } else { + webRTCClient.muteAudio() + isMuted = true + } + } + // MARK: - WebRTC func start() { From d4c4230baedb73603540e3681986072dca35c76d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 10 Dec 2025 15:09:05 +0000 Subject: [PATCH 3/8] Fix code review issues: add AVFoundation import and fix typo Co-authored-by: bgoncal <5808343+bgoncal@users.noreply.github.com> --- Sources/App/WebView/WebRTC/WebRTCClient.swift | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Sources/App/WebView/WebRTC/WebRTCClient.swift b/Sources/App/WebView/WebRTC/WebRTCClient.swift index 5c99bec254..853c5c5831 100644 --- a/Sources/App/WebView/WebRTC/WebRTCClient.swift +++ b/Sources/App/WebView/WebRTC/WebRTCClient.swift @@ -1,3 +1,4 @@ +import AVFoundation import Foundation import Shared import WebRTC @@ -180,8 +181,8 @@ final class WebRTCClient: NSObject { } private func createAudioTrack() -> RTCAudioTrack { - let audioConstrains = RTCMediaConstraints(mandatoryConstraints: nil, optionalConstraints: nil) - let audioSource = WebRTCClient.factory.audioSource(with: audioConstrains) + let audioConstraints = RTCMediaConstraints(mandatoryConstraints: nil, optionalConstraints: nil) + let audioSource = WebRTCClient.factory.audioSource(with: audioConstraints) let audioTrack = WebRTCClient.factory.audioTrack(with: audioSource, trackId: "audio0") return audioTrack } From 05ec92d2d84f0111d0d1e1311882ca793a034625 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 10 Dec 2025 15:11:27 +0000 Subject: [PATCH 4/8] Improve audio track handling and mute state management Co-authored-by: bgoncal <5808343+bgoncal@users.noreply.github.com> --- Sources/App/WebView/WebRTC/WebRTCClient.swift | 20 +++++++++---------- .../WebRTC/WebRTCViewPlayerViewModel.swift | 5 ++--- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/Sources/App/WebView/WebRTC/WebRTCClient.swift b/Sources/App/WebView/WebRTC/WebRTCClient.swift index 853c5c5831..30c0fd37df 100644 --- a/Sources/App/WebView/WebRTC/WebRTCClient.swift +++ b/Sources/App/WebView/WebRTC/WebRTCClient.swift @@ -116,7 +116,12 @@ final class WebRTCClient: NSObject { } func set(remoteSdp: RTCSessionDescription, completion: @escaping (Error?) -> Void) { - peerConnection.setRemoteDescription(remoteSdp, completionHandler: completion) + peerConnection.setRemoteDescription(remoteSdp) { [weak self] error in + if error == nil { + self?.setRemoteAudioTrack() + } + completion(error) + } } func set(remoteCandidate: RTCIceCandidate, completion: @escaping (Error?) -> Void) { @@ -160,11 +165,6 @@ final class WebRTCClient: NSObject { peerConnection.add(videoTrack, streamIds: [streamId]) remoteVideoTrack = peerConnection.transceivers.first { $0.mediaType == .video }?.receiver .track as? RTCVideoTrack - - let audioTrack = createAudioTrack() - peerConnection.add(audioTrack, streamIds: [streamId]) - remoteAudioTrack = peerConnection.transceivers.first { $0.mediaType == .audio }?.receiver - .track as? RTCAudioTrack } private func createVideoTrack() -> RTCVideoTrack { @@ -180,11 +180,9 @@ final class WebRTCClient: NSObject { return videoTrack } - private func createAudioTrack() -> RTCAudioTrack { - let audioConstraints = RTCMediaConstraints(mandatoryConstraints: nil, optionalConstraints: nil) - let audioSource = WebRTCClient.factory.audioSource(with: audioConstraints) - let audioTrack = WebRTCClient.factory.audioTrack(with: audioSource, trackId: "audio0") - return audioTrack + private func setRemoteAudioTrack() { + remoteAudioTrack = peerConnection.transceivers.first { $0.mediaType == .audio }?.receiver + .track as? RTCAudioTrack } } diff --git a/Sources/App/WebView/WebRTC/WebRTCViewPlayerViewModel.swift b/Sources/App/WebView/WebRTC/WebRTCViewPlayerViewModel.swift index 1605c456f1..7e1d68cf23 100644 --- a/Sources/App/WebView/WebRTC/WebRTCViewPlayerViewModel.swift +++ b/Sources/App/WebView/WebRTC/WebRTCViewPlayerViewModel.swift @@ -52,13 +52,12 @@ final class WebRTCViewPlayerViewModel: ObservableObject { func toggleMute() { guard let webRTCClient else { return } - if isMuted { + if webRTCClient.isAudioMuted() { webRTCClient.unmuteAudio() - isMuted = false } else { webRTCClient.muteAudio() - isMuted = true } + isMuted = webRTCClient.isAudioMuted() } // MARK: - WebRTC From bce394855d65164fc4d903aef3944489a7f30688 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 10 Dec 2025 15:13:05 +0000 Subject: [PATCH 5/8] Improve error handling and state management based on code review Co-authored-by: bgoncal <5808343+bgoncal@users.noreply.github.com> --- Sources/App/WebView/WebRTC/WebRTCClient.swift | 12 +++++++++--- .../WebView/WebRTC/WebRTCViewPlayerViewModel.swift | 5 +++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/Sources/App/WebView/WebRTC/WebRTCClient.swift b/Sources/App/WebView/WebRTC/WebRTCClient.swift index 30c0fd37df..3b1a18a1ce 100644 --- a/Sources/App/WebView/WebRTC/WebRTCClient.swift +++ b/Sources/App/WebView/WebRTC/WebRTCClient.swift @@ -148,6 +148,9 @@ final class WebRTCClient: NSObject { private func configureAudioSession() { let audioSession = RTCAudioSession.sharedInstance() audioSession.lockForConfiguration() + defer { + audioSession.unlockForConfiguration() + } do { // Configure for playback only (receive audio without microphone) try audioSession.setCategory(AVAudioSession.Category.playback.rawValue) @@ -156,7 +159,6 @@ final class WebRTCClient: NSObject { } catch { Current.Log.error("Failed to configure audio session: \(error.localizedDescription)") } - audioSession.unlockForConfiguration() } private func createMediaTracks() { @@ -181,8 +183,12 @@ final class WebRTCClient: NSObject { } private func setRemoteAudioTrack() { - remoteAudioTrack = peerConnection.transceivers.first { $0.mediaType == .audio }?.receiver - .track as? RTCAudioTrack + guard let audioTransceiver = peerConnection.transceivers.first(where: { $0.mediaType == .audio }), + let audioTrack = audioTransceiver.receiver.track as? RTCAudioTrack else { + Current.Log.warning("No remote audio track found") + return + } + remoteAudioTrack = audioTrack } } diff --git a/Sources/App/WebView/WebRTC/WebRTCViewPlayerViewModel.swift b/Sources/App/WebView/WebRTC/WebRTCViewPlayerViewModel.swift index 7e1d68cf23..ea45bf3f4a 100644 --- a/Sources/App/WebView/WebRTC/WebRTCViewPlayerViewModel.swift +++ b/Sources/App/WebView/WebRTC/WebRTCViewPlayerViewModel.swift @@ -52,12 +52,13 @@ final class WebRTCViewPlayerViewModel: ObservableObject { func toggleMute() { guard let webRTCClient else { return } - if webRTCClient.isAudioMuted() { + let currentlyMuted = webRTCClient.isAudioMuted() + if currentlyMuted { webRTCClient.unmuteAudio() } else { webRTCClient.muteAudio() } - isMuted = webRTCClient.isAudioMuted() + isMuted = !currentlyMuted } // MARK: - WebRTC From 1abf56bad03aefa034edaa7b9d1551b6cd07f40a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 10 Dec 2025 15:14:50 +0000 Subject: [PATCH 6/8] Add better error logging and defensive checks for audio track handling Co-authored-by: bgoncal <5808343+bgoncal@users.noreply.github.com> --- Sources/App/WebView/WebRTC/WebRTCClient.swift | 14 ++++++++++---- .../WebView/WebRTC/WebRTCViewPlayerViewModel.swift | 6 +++--- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Sources/App/WebView/WebRTC/WebRTCClient.swift b/Sources/App/WebView/WebRTC/WebRTCClient.swift index 3b1a18a1ce..f19a4900f0 100644 --- a/Sources/App/WebView/WebRTC/WebRTCClient.swift +++ b/Sources/App/WebView/WebRTC/WebRTCClient.swift @@ -117,7 +117,9 @@ final class WebRTCClient: NSObject { func set(remoteSdp: RTCSessionDescription, completion: @escaping (Error?) -> Void) { peerConnection.setRemoteDescription(remoteSdp) { [weak self] error in - if error == nil { + if let error { + Current.Log.error("Failed to set remote description: \(error.localizedDescription)") + } else { self?.setRemoteAudioTrack() } completion(error) @@ -183,12 +185,16 @@ final class WebRTCClient: NSObject { } private func setRemoteAudioTrack() { - guard let audioTransceiver = peerConnection.transceivers.first(where: { $0.mediaType == .audio }), - let audioTrack = audioTransceiver.receiver.track as? RTCAudioTrack else { - Current.Log.warning("No remote audio track found") + guard let audioTransceiver = peerConnection.transceivers.first(where: { $0.mediaType == .audio }) else { + Current.Log.warning("No audio transceiver found") + return + } + guard let audioTrack = audioTransceiver.receiver.track as? RTCAudioTrack else { + Current.Log.warning("Remote track is not an RTCAudioTrack") return } remoteAudioTrack = audioTrack + Current.Log.info("Remote audio track set successfully") } } diff --git a/Sources/App/WebView/WebRTC/WebRTCViewPlayerViewModel.swift b/Sources/App/WebView/WebRTC/WebRTCViewPlayerViewModel.swift index ea45bf3f4a..854541d1f0 100644 --- a/Sources/App/WebView/WebRTC/WebRTCViewPlayerViewModel.swift +++ b/Sources/App/WebView/WebRTC/WebRTCViewPlayerViewModel.swift @@ -52,13 +52,13 @@ final class WebRTCViewPlayerViewModel: ObservableObject { func toggleMute() { guard let webRTCClient else { return } - let currentlyMuted = webRTCClient.isAudioMuted() - if currentlyMuted { + if webRTCClient.isAudioMuted() { webRTCClient.unmuteAudio() } else { webRTCClient.muteAudio() } - isMuted = !currentlyMuted + // Always get the final state from the client to ensure consistency + isMuted = webRTCClient.isAudioMuted() } // MARK: - WebRTC From 409917d8b56b2aaac8cd2d20e069397b23eaf36c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20Pantale=C3=A3o?= <5808343+bgoncal@users.noreply.github.com> Date: Wed, 10 Dec 2025 16:47:24 +0100 Subject: [PATCH 7/8] Refactor WebRTC controls and update UI effects Refactored WebRTCVideoPlayerViewControls to group top buttons and improve mute button styling, including conditional glass effect for iOS 26+. Updated ModalCloseButton to use glass effect when available. Simplified AVAudioSession category/mode usage in WebRTCClient. Shortened the experimental disclaimer string. --- Sources/App/WebView/WebRTC/WebRTCClient.swift | 4 +- .../WebRTCVideoPlayerViewControls.swift | 42 ++++++++++++------- .../Components/ModalCloseButton.swift | 9 ++++ .../Shared/Resources/Swiftgen/Strings.swift | 2 +- 4 files changed, 38 insertions(+), 19 deletions(-) diff --git a/Sources/App/WebView/WebRTC/WebRTCClient.swift b/Sources/App/WebView/WebRTC/WebRTCClient.swift index f19a4900f0..e396cc61f2 100644 --- a/Sources/App/WebView/WebRTC/WebRTCClient.swift +++ b/Sources/App/WebView/WebRTC/WebRTCClient.swift @@ -155,8 +155,8 @@ final class WebRTCClient: NSObject { } do { // Configure for playback only (receive audio without microphone) - try audioSession.setCategory(AVAudioSession.Category.playback.rawValue) - try audioSession.setMode(AVAudioSession.Mode.spokenAudio.rawValue) + try audioSession.setCategory(.playback) + try audioSession.setMode(.spokenAudio) try audioSession.setActive(true) } catch { Current.Log.error("Failed to configure audio session: \(error.localizedDescription)") diff --git a/Sources/App/WebView/WebRTC/WebRTCVideoPlayerViewControls.swift b/Sources/App/WebView/WebRTC/WebRTCVideoPlayerViewControls.swift index d30193b209..e278e10e62 100644 --- a/Sources/App/WebView/WebRTC/WebRTCVideoPlayerViewControls.swift +++ b/Sources/App/WebView/WebRTC/WebRTCVideoPlayerViewControls.swift @@ -12,24 +12,9 @@ struct WebRTCVideoPlayerViewControls: View { VStack { HStack { Spacer() - ModalCloseButton(tint: .white) { - close() - } - .padding(16) + topButtons } Spacer() - HStack { - Button(action: toggleMute) { - Image(systemSymbol: isMuted ? .speakerSlashFill : .speakerWaveFill) - .font(.system(size: 24)) - .foregroundStyle(.white) - .padding(12) - .background(Color.black.opacity(0.5)) - .clipShape(Circle()) - } - Spacer() - } - .padding(.horizontal) Text(L10n.WebRTCPlayer.Experimental.disclaimer) .font(DesignSystem.Font.footnote.weight(.light)) .foregroundStyle(.white) @@ -47,6 +32,31 @@ struct WebRTCVideoPlayerViewControls: View { .opacity(0.5) ) } + + @ViewBuilder + private var topButtons: some View { + Button(action: toggleMute) { + Image(systemSymbol: isMuted ? .speakerSlashFill : .speakerWave3) + .resizable() + .frame(width: 16, height: 16) + .foregroundStyle(.white) + .padding(DesignSystem.Spaces.oneAndHalf) + .modify { view in + if #available(iOS 26.0, *) { + view.glassEffect(.clear.interactive(), in: .circle) + } else { + view + .background(Color.black.opacity(0.5)) + .clipShape(Circle()) + } + } + } + .buttonStyle(.plain) + ModalCloseButton(tint: .white) { + close() + } + .padding(16) + } } #Preview { diff --git a/Sources/Shared/DesignSystem/Components/ModalCloseButton.swift b/Sources/Shared/DesignSystem/Components/ModalCloseButton.swift index f820cbd515..ba4278fa5b 100644 --- a/Sources/Shared/DesignSystem/Components/ModalCloseButton.swift +++ b/Sources/Shared/DesignSystem/Components/ModalCloseButton.swift @@ -22,6 +22,15 @@ public struct ModalCloseButton: View { Image(systemSymbol: .xmark) .resizable() .frame(width: 16, height: 16) + .modify { view in + if #available(iOS 26.0, *) { + view + .padding(DesignSystem.Spaces.oneAndHalf) + .glassEffect(.clear.interactive(), in: .circle) + } else { + view + } + } }) .buttonStyle(.plain) .foregroundStyle(tint) diff --git a/Sources/Shared/Resources/Swiftgen/Strings.swift b/Sources/Shared/Resources/Swiftgen/Strings.swift index b98f1daa6e..d10b8a33b6 100644 --- a/Sources/Shared/Resources/Swiftgen/Strings.swift +++ b/Sources/Shared/Resources/Swiftgen/Strings.swift @@ -69,7 +69,7 @@ public enum L10n { public enum WebRTCPlayer { public enum Experimental { - /// Note: Native WebRTC video player is currently an experimental feature, audio may not work and microphone permission and usage may be requested even though not in use. Please use the web player interface for advanced options and reliable playback. + /// Note: Native WebRTC video player is currently an experimental feature. Please use the web player interface for advanced options and reliable playback. public static var disclaimer: String { return L10n.tr("Localizable", "WebRTC_player.experimental.disclaimer") } } } From d2f0567d20b8d81a74fbcb31157363b2a72169dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20Pantale=C3=A3o=20Gon=C3=A7alves?= <5808343+bgoncal@users.noreply.github.com> Date: Wed, 10 Dec 2025 17:01:03 +0100 Subject: [PATCH 8/8] Update Sources/App/WebView/WebRTC/WebRTCViewPlayerViewModel.swift Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- Sources/App/WebView/WebRTC/WebRTCViewPlayerViewModel.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/App/WebView/WebRTC/WebRTCViewPlayerViewModel.swift b/Sources/App/WebView/WebRTC/WebRTCViewPlayerViewModel.swift index 854541d1f0..55516c8f0d 100644 --- a/Sources/App/WebView/WebRTC/WebRTCViewPlayerViewModel.swift +++ b/Sources/App/WebView/WebRTC/WebRTCViewPlayerViewModel.swift @@ -29,7 +29,7 @@ final class WebRTCViewPlayerViewModel: ObservableObject { @Published var failureReason: String? @Published var showLoader: Bool = true @Published var controlsVisible: Bool = true - @Published var isMuted: Bool = false + @Published var isMuted: Bool = true var hideControlsWorkItem: DispatchWorkItem?