Record Video and play audio at same time ios

2019-03-23 20:00发布

问题:

I want to record video and play audio simultaneously. when start recording video, preloaded audio start play and when stop video recording, audio also stops playing.

I tried to record Video by using third party library "SwiftyCam" (https://github.com/Awalz/SwiftyCam) and start playing audio in delegate method when start writes video recording file.

main ViewCOntroller code is below :

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 Library :

/**

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

issue: sometimes getting a delay in start playing audio in a microsecond. when audio start play and sound record in video recording some time sync proper and some time delay in sound.

I check it with merge audio with original audio and there is some delay as shown below image. the issue is not always but random delay and not sync.

are any solutions? how to do record video and play audio at the same time(on single button click) start and no delay and no sync issue? is any other way?

for play audio used: AVAudioPlayer

for record video used : Swiftycam (AVCaptureSession)

回答1:

Couple thing you can try:

1) Play audio on the background queue:

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

2) Move the code you have in viewDidAppear (including prepareToPlay()) to viewDidLoad. I assume this will be a less helpful suggestions since playing is user-initiated but there is a delay between prepareToPlay() and when your audio is ready.

If you try these and the delay is still too much, you simply might have to use something other than AVAudioPlayer, such as OpenAL.