Skip to content

Commit

Permalink
Fix audio renderer crash (#493)
Browse files Browse the repository at this point in the history
  • Loading branch information
hiroshihorie authored Sep 24, 2024
1 parent 2bc3d6b commit f812fec
Show file tree
Hide file tree
Showing 6 changed files with 14 additions and 49 deletions.
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ let package = Package(
],
dependencies: [
// LK-Prefixed Dynamic WebRTC XCFramework
.package(url: "https://github.com/livekit/webrtc-xcframework.git", exact: "125.6422.07"),
.package(url: "https://github.com/livekit/webrtc-xcframework.git", exact: "125.6422.08"),
.package(url: "https://github.com/apple/swift-protobuf.git", from: "1.26.0"),
.package(url: "https://github.com/apple/swift-log.git", from: "1.5.4"),
// Only used for DocC generation
Expand Down
2 changes: 1 addition & 1 deletion [email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ let package = Package(
],
dependencies: [
// LK-Prefixed Dynamic WebRTC XCFramework
.package(url: "https://github.com/livekit/webrtc-xcframework.git", exact: "125.6422.07"),
.package(url: "https://github.com/livekit/webrtc-xcframework.git", exact: "125.6422.08"),
.package(url: "https://github.com/apple/swift-protobuf.git", from: "1.26.0"),
.package(url: "https://github.com/apple/swift-log.git", from: "1.5.4"),
// Only used for DocC generation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class AudioCustomProcessingDelegateAdapter: NSObject, LKRTCAudioCustomProcessing

// Convert to pcmBuffer and notify only if an audioRenderer is added.
if audioRenderers.isDelegatesNotEmpty, let pcmBuffer = lkAudioBuffer.toAVAudioPCMBuffer() {
audioRenderers.notify { $0.render?(pcmBuffer: pcmBuffer) }
audioRenderers.notify { $0.render(pcmBuffer: pcmBuffer) }
}
}

Expand Down
18 changes: 7 additions & 11 deletions Sources/LiveKit/Protocols/AudioRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,34 +25,30 @@ internal import LiveKitWebRTC

@objc
public protocol AudioRenderer {
/// CMSampleBuffer for this track.
@objc optional
func render(sampleBuffer: CMSampleBuffer)

@objc optional
@objc
func render(pcmBuffer: AVAudioPCMBuffer)
}

class AudioRendererAdapter: NSObject, LKRTCAudioRenderer {
private weak var target: AudioRenderer?
private let targetHashValue: Int

init(target: AudioRenderer) {
self.target = target
targetHashValue = ObjectIdentifier(target).hashValue
}

func render(sampleBuffer: CMSampleBuffer) {
target?.render?(sampleBuffer: sampleBuffer)
func render(pcmBuffer: AVAudioPCMBuffer) {
target?.render(pcmBuffer: pcmBuffer)
}

// Proxy the equality operators

override func isEqual(_ object: Any?) -> Bool {
guard let other = object as? AudioRendererAdapter else { return false }
return target === other.target
return targetHashValue == other.targetHashValue
}

override var hash: Int {
guard let target else { return 0 }
return ObjectIdentifier(target).hashValue
targetHashValue
}
}
35 changes: 2 additions & 33 deletions Sources/LiveKit/Track/Remote/RemoteAudioTrack.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,6 @@ internal import LiveKitWebRTC

@objc
public class RemoteAudioTrack: Track, RemoteTrack, AudioTrack {
// State used to manage AudioRenderers
private struct RendererState {
var didAttacheAudioRendererAdapter: Bool = false
let audioRenderers = MulticastDelegate<AudioRenderer>(label: "AudioRenderer")
}

private lazy var _audioRendererAdapter = AudioRendererAdapter(target: self)
private let _rendererState = StateSync(RendererState())

/// Volume with range 0.0 - 1.0
public var volume: Double {
get {
Expand All @@ -59,26 +50,12 @@ public class RemoteAudioTrack: Track, RemoteTrack, AudioTrack {

public func add(audioRenderer: AudioRenderer) {
guard let audioTrack = mediaTrack as? LKRTCAudioTrack else { return }

_rendererState.mutate {
$0.audioRenderers.add(delegate: audioRenderer)
if !$0.didAttacheAudioRendererAdapter {
audioTrack.add(_audioRendererAdapter)
$0.didAttacheAudioRendererAdapter = true
}
}
audioTrack.add(AudioRendererAdapter(target: audioRenderer))
}

public func remove(audioRenderer: AudioRenderer) {
guard let audioTrack = mediaTrack as? LKRTCAudioTrack else { return }

_rendererState.mutate {
$0.audioRenderers.remove(delegate: audioRenderer)
if $0.audioRenderers.allDelegates.isEmpty {
audioTrack.remove(_audioRendererAdapter)
$0.didAttacheAudioRendererAdapter = false
}
}
audioTrack.remove(AudioRendererAdapter(target: audioRenderer))
}

// MARK: - Internal
Expand All @@ -91,11 +68,3 @@ public class RemoteAudioTrack: Track, RemoteTrack, AudioTrack {
try await AudioManager.shared.trackDidStop(.remote)
}
}

extension RemoteAudioTrack: AudioRenderer {
public func render(sampleBuffer: CMSampleBuffer) {
_rendererState.audioRenderers.notify { audioRenderer in
audioRenderer.render?(sampleBuffer: sampleBuffer)
}
}
}
4 changes: 2 additions & 2 deletions Tests/LiveKitTests/Support/Tracks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,8 @@ class AudioTrackWatcher: AudioRenderer {
}
}

func render(sampleBuffer: CMSampleBuffer) {
print("did receive first audio frame: \(String(describing: sampleBuffer))")
func render(pcmBuffer: AVAudioPCMBuffer) {
print("did receive first audio frame: \(String(describing: pcmBuffer))")

_state.mutate {
if !$0.didRenderFirstFrame {
Expand Down

0 comments on commit f812fec

Please sign in to comment.