同时在iOS上录制视频和播放音频

17

我希望能够同时录制视频和播放音频。当开始录制视频时,预加载的音频开始播放,当停止视频录制时,音频也停止播放。

我尝试使用第三方库“SwiftyCam”(https://github.com/Awalz/SwiftyCam)录制视频,并在委托方法中开始播放音频。

主视图控制器代码如下:

override func viewDidAppear(_ animated: Bool) {
 super.viewDidAppear(animated)
 var temp = Data()
 let audioPath = Bundle.main.path(forResource: "ab1-FAST", ofType: "mp3")
        temp = FileManager.default.contents(atPath: (audioPath)!)!
     do {
            player = try  AVAudioPlayer(data: temp)
        }
        catch let error {

            print(error)
        }

        self.configureAudioSession()
        player!.delegate = self
        self.player!.prepareToPlay()
}

    // MARK: -
    // MARK: - SwiftyCamViewControllerDelegate method

func swiftyCam(_ swiftyCam: SwiftyCamViewController, didBeginRecordingVideo camera: SwiftyCamViewController.CameraSelection) {
  self.player?.play()
}

func swiftyCam(_ swiftyCam: SwiftyCamViewController, didFinishRecordingVideo camera: SwiftyCamViewController.CameraSelection) 
{
        if self.player != nil{
            if (self.player?.isPlaying)! {
                self.player?.stop()
            }
        }
}


@IBAction func btnStartStopClick(_ sender: UIButton) {

        sender.isSelected = !sender.isSelected
        if sender.isSelected{

            DispatchQueue.main.async {
                self.objVideoRecorderVC.startVideoRecording()
            }
        }else{
             self.objVideoRecorderVC.stopVideoRecording()

        }
  }

swiftycam库:

/**

    Begin recording video of current session

    SwiftyCamViewControllerDelegate function SwiftyCamDidBeginRecordingVideo() will be called

    */
public func startVideoRecording() {
        guard let movieFileOutput = self.movieFileOutput else {
            return
        }

        if currentCamera == .rear && flashEnabled == true {
            enableFlash()
        }

        if currentCamera == .front && flashEnabled == true {
            flashView = UIView(frame: view.frame)
            flashView?.backgroundColor = UIColor.white
            flashView?.alpha = 0.85
            previewLayer.addSubview(flashView!)
        }

        sessionQueue.async { [unowned self] in
            if !movieFileOutput.isRecording {
                if UIDevice.current.isMultitaskingSupported {
                    self.backgroundRecordingID = UIApplication.shared.beginBackgroundTask(expirationHandler: nil)
                }

                // Update the orientation on the movie file output video connection before starting recording.
                let movieFileOutputConnection = self.movieFileOutput?.connection(withMediaType: AVMediaTypeVideo)


                //flip video output if front facing camera is selected
                if self.currentCamera == .front {
                    movieFileOutputConnection?.isVideoMirrored = true
                }

                movieFileOutputConnection?.videoOrientation = self.getVideoOrientation()

                // Start recording to a temporary file.
                let outputFileName = UUID().uuidString
                let outputFilePath = (NSTemporaryDirectory() as NSString).appendingPathComponent((outputFileName as NSString).appendingPathExtension("mov")!)


                movieFileOutput.startRecording(toOutputFileURL: URL(fileURLWithPath: outputFilePath), recordingDelegate: self)
                self.isVideoRecording = true
    DispatchQueue.main.async {
                    self.cameraDelegate?.swiftyCam(self, didBeginRecordingVideo: self.currentCamera)
                }
            }
            else {
                movieFileOutput.stopRecording()
            }
        }
    }

问题:有时候微秒级别的音频播放会出现延迟。当音频开始播放并且录制视频时,有时候声音同步正常,有时候声音有延迟。
我用合并原始音频来检查了这个问题,如下图所示存在一些延迟。这个问题并不总是出现,而是随机延迟并且不同步。enter image description here enter image description here 是否有解决办法? 如何同时录制视频和播放音频(单击一个按钮开始),避免延迟和同步问题?是否有其他方法?
音频播放使用:AVAudioPlayer 视频录制使用:Swiftycam (AVCaptureSession)

也许你可以尝试这个 Stack Overflow 的答案:https://dev59.com/r5bfa4cB1Zd3GeqPs2Kt#36912798 - Akshit Zaveri
@AkshitZaveri,我可以同时播放音频和录制视频。在单个按钮点击时开始音频播放和视频录制。但问题是音频播放会有0.5秒的延迟(并非总是如此)。 - Bhargav B. Bajani
1
理论上我认为这是可能的,但我不知道如何同步这两个任务。希望有人能给我们展示一个优雅的解决方案。 - sage444
你想要录制只有音频,还是希望在视频中添加一些背景音乐?如果你想加入背景音乐,那么可以尝试使用 AVMutableCompositionTrack 在程序中合并音频轨道,将音乐添加到其中。我之前也做过类似的任务,将音频与视频合并后最终导出了视频。@BhargavB.Bajani - Dhiru
@dhiru...我正在启动同时录制视频和播放音频。 因此,音频声音记录在视频中。 之后,当我将播放的音频与录制的视频音频进行比较时,它们不同步。 - Bhargav B. Bajani
1个回答

6
您可以尝试以下两个方法:

1)在后台队列中播放音频:

dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUN‌​D, 0)) {
    self.player.play()
}

2) 将您在viewDidAppear中的代码(包括prepareToPlay())移动到viewDidLoad。我认为这可能不是很有帮助的建议,因为播放是用户发起的,但在prepareToPlay()和您的音频准备就绪之间存在延迟。

如果您尝试了这些方法,但仍然有延迟太大的问题,则可能必须使用其他东西来替代AVAudioPlayer,例如OpenAL


我尝试将代码从“viewDidAppear”移动到“viewDidLoad”。还尝试了prepareToPlay() -> play() -> pause()。 - Bhargav B. Bajani
@BhargavB.Bajani,你解决了这个问题吗?这条评论对你有帮助吗? - Rikh
@Rikh 没有找到任何解决方案。尝试了上面的评论,但问题没有得到解决。 我认为这个问题与硬件和线程有关,因为延迟是正负任意的。 - Bhargav B. Bajani

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接