Ios 同时录制视频和播放音频

Ios 同时录制视频和播放音频,ios,swift,swift3,avaudioplayer,video-capture,Ios,Swift,Swift3,Avaudioplayer,Video Capture,我想同时录制视频和播放音频。开始录制视频时,预加载的音频开始播放;停止视频录制时,音频也停止播放 我尝试使用第三方库“SwiftyCam”()录制视频,并在start写入视频录制文件时开始以代理方法播放音频 主视图控制器代码如下: override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) var temp = Data() let audioPath = Bundle.main.path(fo

我想同时录制视频和播放音频。开始录制视频时,预加载的音频开始播放;停止视频录制时,音频也停止播放

我尝试使用第三方库“SwiftyCam”()录制视频,并在start写入视频录制文件时开始以代理方法播放音频

主视图控制器代码如下:

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()

        }
  }
/**

    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()
            }
        }
    }
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()

        }
  }
/**

    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()
            }
        }
    }
问题:有时开始播放音频会延迟一微秒。 在视频录制中,当音频开始播放和录音时,一些时间同步正确,一些声音延迟

我用合并音频和原始音频检查它,有一些延迟,如下图所示。问题并不总是存在的,而是随机延迟和不同步

有什么解决办法吗? 如何同时录制视频和播放音频(只需单击一个按钮)启动且无延迟和同步问题? 还有别的办法吗

用于播放音频的:AVAudioPlayer


录制使用的视频:Swiftycam(AVCaptureSession)

您可以尝试以下几种方法:

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

dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUN‌​D, 0)) {
    self.player.play()
}
2) 将您在
viewdideappear
(包括
prepareToPlay()
)中的代码移动到
viewdideload
。我认为这是一个不太有用的建议,因为播放是由用户发起的,但在
prepareToPlay()
和音频准备就绪之间有延迟


如果您尝试这些,但延迟仍然太大,您可能只需要使用
AVAudioPlayer
以外的其他工具,例如
OpenAL

,您可以尝试这样做,以便asnwer:@AkshitZaveri,,,,,我可以同时播放音频和录制视频。在单个按钮上单击开始音频播放和视频录制开始。但问题是播放音频延迟了0.5秒(并不总是)。理论上我认为这是可能的,但不知道如何同步这两个任务。希望有人能向我们展示优雅的解决方案您是想在录音时只听音频,还是想在视频中添加一些背景音乐?如果您想添加背景音乐,可以尝试使用
AVMutableCompositionTrack
以编程方式将音频曲目合并到视频中。您可以将音乐添加到其中,我有一个类似的任务,我将音频合并到视频中,最后将视频@BhargavB导出。Bajani@dhiru... 我正在同时开始录像和音频播放。视频中没有音频录音。之后,当我比较播放的音频和录制的视频的音频时,它不同步。我尝试将代码从“ViewDidDisplay”移动到“viewDidLoad”。还尝试了prepareToPlay()->play()->pause()@BhargavB.Bajani您找到解决方案了吗?这个评论对你有帮助吗?@Rikh没有任何解决办法。并尝试了上述评论,但没有解决问题。我认为这个问题与硬件和线程有关。因为延迟是+/-任意的。