【问题标题】:iOS: Process audio from AVPlayer video trackiOS:处理来自 AVPlayer 视频轨道的音频
【发布时间】:2017-11-24 14:41:34
【问题描述】:

我计划在我的 iOS 应用中重构我的录音系统。 语境: 到目前为止,我分别录制视频和音频,几乎同时开始录制。录制完成后,在同一系统中,我分别播放视频和音频,并在音频上动态应用 AudioUnits。最后,我合并了视频和修改后的音频。 碰巧两条记录不会同时开始(出于任何原因),从而产生不同步的结果。

是否可以像这样重构我的系统:

1) Record normal video with audio into mov file --> I would be sure that audio+video would be synchronized.

2) During viewing the result with AVPlayer, process the audio part on the fly. (I will use AudioKit) --> that's the part I m not confident. 
   Would I be able to send the audio buffer to Audiokit (which would process it) and give back the processed audio to AVPlayer like if it was the original AVPlayer audio part?

3) Save a final file with video and audio modified --> easy part with AVFundation

请询问任何信息;)

【问题讨论】:

  • 只是为了确保您正在录制视频,但想要更改音频样本?如果是这样,您可以将 AVCaptureVideoDataOutput 与 AVCaptureAudioDataOutput 一起使用,这将为您提供 CMSample 的音频,您可以将其放入同步队列中的任何进程,该进程将通过 AVAssetWriter 输出
  • 差不多就是这样。录制后需要进行音频处理,因为用户会选择将哪种音频效果应用于最终视频。拥有与 AVCaptureAudioDataOutput 等效但在 AVPlayer 级别会很酷(Audiokit 确实提供此功能,但不支持视频)
  • 我认为你可以使用 AVAssetReader,它也会输出已记录文件的样本
  • 好的,谢谢。下周我将深入探讨这个问题,跟进第一个线索。我会回来询问更多和/或发布我的工作。

标签: ios video avplayer audiounit audiokit


【解决方案1】:

我能想到一种相当简单的方法来做到这一点。

基本上,您只需在 AKPlayer 实例中打开您的视频文件。然后,您将视频音频静音。现在,您在 AudioKit 中拥有了视频音频。使用通用时钟将视频和音频锁定在一起非常简单。流程伪代码:

// This will represent a common clock using the host time
var audioClock = CMClockGetHostTimeClock()

// your video player
let videoPlayer = AVPlayer( url: videoURL )
videoPlayer.masterClock = audioClock
videoPlayer.automaticallyWaitsToMinimizeStalling = false

....

var audioPlayer: AKPlayer?

// your video-audio player
if let player = try? AKPlayer(url: videoURL) {
    audioPlayer = player
}

func schedulePlayback(videoTime: TimeInterval, audioTime: TimeInterval, hostTime: UInt64 ) {
    audioPlay( audioTime, hostTime: hostTime )
    videoPlay(at: 0, hostTime: hostTime)
}


func audioPlay(at time: TimeInterval = 0, hostTime: UInt64 = 0) {
    audioPlayer.play(when: time, hostTime: hostTime)    
}

func videoPlay(at time: TimeInterval = 0, hostTime: UInt64 = 0 ) {
    let cmHostTime = CMClockMakeHostTimeFromSystemUnits(hostTime)
    let cmVTime = CMTimeMakeWithSeconds(time, 1000000)
    let futureTime = CMTimeAdd(cmHostTime, cmVTime)
    videoPlayer.setRate(1, time: kCMTimeInvalid, atHostTime: futureTime)
}

您可以以正常方式将播放器连接到任何 AudioKit 处理链。

当您想要导出音频时,请在最终输出处理链上运行 AKNodeRecorder。将此记录到文件中,然后将您的音频合并到您的视频中。我不确定正在处理的 AudioKit 离线处理是否准备就绪,因此您可能需要实时播放音频以捕获处理输出。

【讨论】:

  • 谢谢瑞恩。如果我做对了,我会有一个用于视频的标准 AVPlayer(静音),一个用于播放和处理音频的 AKAudioPlayer。我必须检查如何同步播放器,如果它很简单那么酷! :P(我不明白你为什么说“但听起来他们无论如何都没有被锁定”,你能详细说明一下吗?关于离线渲染(我的情况将非常感激),下面的帖子说 Audiokit可以在没有 iOS 11 的情况下做到这一点,但它与上一个 audiokit 发行说明形成鲜明对比。stackoverflow.com/q/45799686/6731119
  • 我将编辑我的答案以展示如何将 AVPlayer 和 AKAudioPlayers 锁定到一个公共时钟。
猜你喜欢
  • 2011-10-07
  • 1970-01-01
  • 2012-10-02
  • 2014-10-16
  • 2015-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多