Skip to content

Commit

Permalink
feat(Media): use different audio session mode for audio and video cal…
Browse files Browse the repository at this point in the history
…ls (#59)

* feat(Media): change default audio config options

* Fix the sample app

* Rename contains to canSendOrReceive

* Update tj-actions/changed-files

* Update license headers
  • Loading branch information
vadymmarkov authored Jan 19, 2024
1 parent 3c4db84 commit 30b99fa
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 27 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/license.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:

- name: Get changed files
id: files
uses: tj-actions/changed-files@v35
uses: tj-actions/changed-files@v42

- name: Check license headers
run: |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2022-2023 Pexip AS
// Copyright 2022-2024 Pexip AS
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -164,7 +164,7 @@ final class ConferenceViewModel: ObservableObject {

#if os(iOS)
Task { [weak audioSession] in
await audioSession?.activate(for: .call)
await audioSession?.activate(for: .videoCall())
}
#endif
}
Expand Down
49 changes: 34 additions & 15 deletions Sources/PexipMedia/AudioConfiguration.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2023 Pexip AS
// Copyright 2023-2024 Pexip AS
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -44,24 +44,43 @@ public extension AudioConfiguration {
options: []
)

static let call = AudioConfiguration(
category: .playAndRecord,
mode: .voiceChat,
options: [
static func audioCall(
mixWithOthers: Bool = false
) -> AudioConfiguration {
call(
withMode: .voiceChat,
mixWithOthers: mixWithOthers
)
}

static func videoCall(
mixWithOthers: Bool = false
) -> AudioConfiguration {
call(
withMode: .videoChat,
mixWithOthers: mixWithOthers
)
}

private static func call(
withMode mode: AVAudioSession.Mode,
mixWithOthers: Bool
) -> AudioConfiguration {
var options: AVAudioSession.CategoryOptions = [
.allowBluetooth,
.allowBluetoothA2DP
]
)

static let screenCapture = AudioConfiguration(
category: .playAndRecord,
mode: .voiceChat,
options: [
.allowBluetooth,
.allowBluetoothA2DP,
.mixWithOthers
]
)
if mixWithOthers {
options.insert(.mixWithOthers)
}

return AudioConfiguration(
category: .playAndRecord,
mode: mode,
options: options
)
}
}

#endif
7 changes: 6 additions & 1 deletion Sources/PexipMedia/MediaConnectionConfig.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2022-2023 Pexip AS
// Copyright 2022-2024 Pexip AS
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -45,6 +45,11 @@ public struct MediaConnectionConfig {
/// Sets whether presentation will be mixed with main video feed.
public let presentationInMain: Bool

#if os(iOS)
/// Sets whether audio session is managed outside of the SDK.
public var externalAudioManagement = false
#endif

/**
Creates a new instance of ``MediaConnectionConfig``.

Expand Down
10 changes: 9 additions & 1 deletion Sources/PexipRTC/Internal/PeerConnection/PeerConnection.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2023 Pexip AS
// Copyright 2023-2024 Pexip AS
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -222,6 +222,14 @@ actor PeerConnection {
logger?.debug("Data channel - new data channel created.")
}

func canSendOrReceive(_ content: MediaContent) -> Bool {
if let transceiver = transceivers[content] {
return transceiver.canSend || transceiver.canReceive
} else {
return false
}
}

// MARK: - Events

private func subscribeToEvents() {
Expand Down
6 changes: 5 additions & 1 deletion Sources/PexipRTC/Internal/PeerConnection/Transceiver.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2023 Pexip AS
// Copyright 2023-2024 Pexip AS
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -41,6 +41,10 @@ final class Transceiver {
transceiver.direction == .recvOnly || transceiver.direction == .sendRecv
}

var canSend: Bool {
transceiver.direction == .sendOnly || transceiver.direction == .sendRecv
}

func setDirection(_ direction: RTCRtpTransceiverDirection) throws {
guard transceiver.direction != direction else {
return
Expand Down
27 changes: 21 additions & 6 deletions Sources/PexipRTC/Internal/WebRTCMediaConnection.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2022-2023 Pexip AS
// Copyright 2022-2024 Pexip AS
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -106,7 +106,9 @@ actor WebRTCMediaConnection: MediaConnection, DataSender {
}

#if os(iOS)
await audioSession?.activate(for: .call)
if let audioConfig = await audioConfig(mixWithOthers: false) {
await audioSession?.activate(for: audioConfig)
}
#endif

started = true
Expand All @@ -130,7 +132,9 @@ actor WebRTCMediaConnection: MediaConnection, DataSender {
outgoingIceCandidates.removeAll()

#if os(iOS)
await audioSession?.deactivate()
if !config.externalAudioManagement {
await audioSession?.deactivate()
}
#endif
}

Expand Down Expand Up @@ -171,9 +175,9 @@ actor WebRTCMediaConnection: MediaConnection, DataSender {
try await self?.signalingChannel.releaseFloor()
}
#if os(iOS)
await self?.audioSession?.activate(
for: isCapturing ? .screenCapture : .call
)
if let audioConfig = await self?.audioConfig(mixWithOthers: isCapturing) {
await self?.audioSession?.activate(for: audioConfig)
}
#endif
} catch {
self?.logger?.error("Error on takeFloow/releaseFloor: \(error)")
Expand Down Expand Up @@ -440,5 +444,16 @@ actor WebRTCMediaConnection: MediaConnection, DataSender {
break
}
}

#if os(iOS)
private func audioConfig(mixWithOthers: Bool) async -> AudioConfiguration? {
guard !config.externalAudioManagement else {
return nil
}
return await peerConnection.canSendOrReceive(.mainVideo)
? .videoCall(mixWithOthers: mixWithOthers)
: .audioCall(mixWithOthers: mixWithOthers)
}
#endif
}
// swiftlint:enable type_body_length file_length

0 comments on commit 30b99fa

Please sign in to comment.