diff --git a/Sources/PlayerBridge.swift b/Sources/PlayerBridge.swift index 78ad951..180982a 100644 --- a/Sources/PlayerBridge.swift +++ b/Sources/PlayerBridge.swift @@ -186,6 +186,9 @@ final class PlayerBridge: ObservableObject { let output = AVPlayerItemVideoOutput(pixelBufferAttributes: pixelBufferAttributes) playerItem.add(output) videoOutput = output + + // 预装音频 Tap(在播放前设置 audioMix,避免播放中设置导致视频卡顿) + screenRecorder.installAudioTap(on: playerItem) #endif player.replaceCurrentItem(with: playerItem) diff --git a/Sources/PlayerRecorder.swift b/Sources/PlayerRecorder.swift index e24f747..7733f04 100644 --- a/Sources/PlayerRecorder.swift +++ b/Sources/PlayerRecorder.swift @@ -319,7 +319,8 @@ final class PlayerRecorder: NSObject { // MARK: - Audio Tap Setup /// 安装音频 Tap(使用 playerItem.tracks 获取轨道,支持 HLS 虚拟 asset) - private func installAudioTap(on playerItem: AVPlayerItem) { + /// 应在 playerItem 开始播放前调用(playIndex 中),避免播放中设置 audioMix 导致视频卡顿 + func installAudioTap(on playerItem: AVPlayerItem) { // 确保全局上下文存在 if gTapContext == nil { gTapContext = AudioTapContext() @@ -344,10 +345,8 @@ final class PlayerRecorder: NSObject { } } - guard audioTrackID != kCMPersistentTrackID_Invalid else { - print("[Recorder:DIAG] ⚠️ No enabled audio track in playerItem.tracks!") - writeDiagLog("No audio track in playerItem.tracks (count=\(itemTracks.count))") - return + if audioTrackID == kCMPersistentTrackID_Invalid { + print("[Recorder:DIAG] ⚠️ No enabled audio track found yet (tracks=\(itemTracks.count)), using wildcard") } print("[Recorder:DIAG] Using audio trackID=\(audioTrackID)") @@ -431,8 +430,12 @@ final class PlayerRecorder: NSObject { isRunning = false recordStartTime = startTime - // 安装音频 Tap(录制时 asset 已加载,同步获取 track) - installAudioTap(on: playerItem) + // 安装音频 Tap(如果 playIndex 中已预装,则跳过) + if playerItem.audioMix == nil { + installAudioTap(on: playerItem) + } else { + print("[Recorder:DIAG] audioMix already installed, skipping") + } let tempFilename = "temp_recording_\(Int(Date().timeIntervalSince1970)).mp4" let url = saveDirectory.appendingPathComponent(tempFilename)