Skip to content

Commit

Permalink
[Fix]AudioSession management via CallSettings
Browse files Browse the repository at this point in the history
  • Loading branch information
ipavlidakis committed Oct 29, 2024
1 parent 00e3785 commit b674af5
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 3 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- You can now set the time a user can remain in the call - after their connection disrupted - while waiting for their network connection to recover [#573](https://github.com/GetStream/stream-video-swift/pull/573)
- You can now provide the preferred Video stream codec to use [#583](https://github.com/GetStream/stream-video-swift/pull/583)

### 🐞 Fixed
- Toggling the speaker during a call wasn't always working. [#585](https://github.com/GetStream/stream-video-swift/pull/585)

# [1.13.0](https://github.com/GetStream/stream-video-swift/releases/tag/1.13.0)
_October 08, 2024_

Expand Down
2 changes: 1 addition & 1 deletion Sources/StreamVideo/WebRTC/AudioSession.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ actor AudioSession {
rtcAudioSession.lockForConfiguration()
defer { rtcAudioSession.unlockForConfiguration() }
rtcAudioSession.useManualAudio = true
rtcAudioSession.isAudioEnabled = true
rtcAudioSession.isAudioEnabled = audioOn

do {
log.debug(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,18 @@ final class LocalAudioMediaAdapter: LocalMediaAdapting {
) async throws {
guard let localTrack else { return }
let isMuted = !settings.audioOn
// Check if the localTrack is muted
let isLocalMuted = localTrack.isEnabled == false
guard isMuted != isLocalMuted || sender == nil else {
// Check if the speaker is on, for the current AudioSession
let isLocalSpeakerOn = await audioSession.isSpeakerOn
// Check if the current AudioSession isActive
let isLocalAudioSessionActive = await audioSession.isActive
guard
sender == nil
|| isMuted != isLocalMuted
|| settings.speakerOn != isLocalSpeakerOn
|| settings.audioOutputOn != isLocalAudioSessionActive
else {
return
}

Expand All @@ -205,7 +215,7 @@ final class LocalAudioMediaAdapter: LocalMediaAdapting {
)

await audioSession.configure(
audioOn: settings.audioOn,
audioOn: settings.audioOutputOn,
speakerOn: settings.speakerOn
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,26 @@ final class LocalAudioMediaAdapter_Tests: XCTestCase {
XCTAssertFalse(isActive)

Check failure on line 178 in StreamVideoTests/WebRTC/v2/PeerConnection/MediaAdapters/LocalMediaAdapters/LocalAudioMediaAdapter_Tests.swift

View workflow job for this annotation

GitHub Actions / Test LLC (Debug)

test_didUpdateCallSettings_isEnabledTrueCallSettingsFalse_callSettingsUpdatedAudioSession, XCTAssertFalse failed

Check failure on line 178 in StreamVideoTests/WebRTC/v2/PeerConnection/MediaAdapters/LocalMediaAdapters/LocalAudioMediaAdapter_Tests.swift

View workflow job for this annotation

GitHub Actions / Test LLC (Debug)

test_didUpdateCallSettings_isEnabledTrueCallSettingsFalse_callSettingsUpdatedAudioSession, XCTAssertFalse failed

Check failure on line 178 in StreamVideoTests/WebRTC/v2/PeerConnection/MediaAdapters/LocalMediaAdapters/LocalAudioMediaAdapter_Tests.swift

View workflow job for this annotation

GitHub Actions / Test LLC (Debug)

test_didUpdateCallSettings_isEnabledTrueCallSettingsFalse_callSettingsUpdatedAudioSession, XCTAssertFalse failed

Check failure on line 178 in StreamVideoTests/WebRTC/v2/PeerConnection/MediaAdapters/LocalMediaAdapters/LocalAudioMediaAdapter_Tests.swift

View workflow job for this annotation

GitHub Actions / Test LLC (Debug)

test_didUpdateCallSettings_isEnabledTrueCallSettingsFalse_callSettingsUpdatedAudioSession, XCTAssertFalse failed
}

func test_didUpdateCallSettings_isEnabledTrueCallSettingsTrueSpeakerOnTrue_callSettingsUpdatedAudioSession() async throws {
mockPeerConnection.stub(
for: .addTransceiver,
with: try makeTransceiver(of: .audio)
)

try await subject.setUp(
with: .init(audioOn: true),
ownCapabilities: [.sendAudio]
)
subject.localTrack?.isEnabled = true

try await subject.didUpdateCallSettings(.init(audioOn: true, speakerOn: true))

let isActive = await audioSession.isActive
let isSpeakerOn = await audioSession.isSpeakerOn
XCTAssertTrue(isActive)
XCTAssertTrue(isSpeakerOn)
}

func test_didUpdateCallSettings_isEnabledFalseCallSettingsTrue_startsRecording() async throws {
try await subject.setUp(
with: .init(audioOn: true),
Expand All @@ -191,6 +211,32 @@ final class LocalAudioMediaAdapter_Tests: XCTestCase {
}
}

func test_didUpdateCallSettings_disablingAudioSessionWhileSpeakerIsOnAndUnmuted_callSettingsUpdatedAudioSession() async throws {
mockPeerConnection.stub(
for: .addTransceiver,
with: try makeTransceiver(of: .audio)
)
try await subject.setUp(
with: .init(audioOn: true),
ownCapabilities: [.sendAudio]
)
subject.localTrack?.isEnabled = true
try await subject.didUpdateCallSettings(.init(audioOn: true, speakerOn: true))
await assertEqualAsync(await audioSession.isActive, true)
await assertEqualAsync(await audioSession.isSpeakerOn, true)

try await subject.didUpdateCallSettings(
.init(
audioOn: true,
speakerOn: true,
audioOutputOn: false
)
)

await assertEqualAsync(await audioSession.isActive, false)
await assertEqualAsync(await audioSession.isSpeakerOn, true)
}

// MARK: - publish

func test_publish_disabledLocalTrack_enablesAndAddsTrackAndTransceiver() async throws {
Expand Down Expand Up @@ -283,6 +329,17 @@ final class LocalAudioMediaAdapter_Tests: XCTestCase {
}
}

private func assertEqualAsync<T: Equatable>(
_ expression: @autoclosure () async throws -> T,
_ expected: @autoclosure () async throws -> T,
file: StaticString = #file,
line: UInt = #line
) async rethrows {
let value = try await expression()
let expectedValue = try await expected()
XCTAssertEqual(value, expectedValue, file: file, line: line)
}

private func makeTransceiver(
of type: TrackType,
direction: RTCRtpTransceiverDirection = .sendOnly,
Expand Down

0 comments on commit b674af5

Please sign in to comment.