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)
Visit Google Play Store and download the Together app. Launch your music app and play the desired track. Launch the Together app and tap the video camera icon at the bottom to start recording. The music should continue playing.
Couple thing you can try:
1) Play audio on the background queue:
dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With