4

I want to record video/audio in a series of fluid, variable length clips. That is, vid1.mp4 followed by vid2.mp4 should connect together seamlessly, or mostly seamlessly.

My current problem is that I cannot seem to switch files immediately without getting errors.

The crux of the issue is this:

func recordNewClip() {
    let file = self.outputUrl()
    let filePath = file!.path!
    try? NSFileManager.defaultManager().removeItemAtPath(filePath)
    movieOutput!.stopRecording()
    movieOutput!.startRecordingToOutputFileURL(file, recordingDelegate: self)
}

If I don't call stopRecording, I get errors, and if I do call stopRecording, only random video clips ever record; most recordings fail.

How can I capture sequential video clips with AVFoundation?

Stefan Kendall
  • 66,414
  • 68
  • 253
  • 406
  • What errors do you get? – jtbandes Sep 27 '15 at 01:22
  • @jtbandes a movie is already in progress. Every other record seems to be working for this reason. I can't call stopRecording then immediately startRecording, but I also can't string startRecording calls sequentially. – Stefan Kendall Sep 27 '15 at 01:33
  • follow the code from this question and make sure to read the answer: https://stackoverflow.com/q/58323683/4833705 – Lance Samaria Oct 15 '19 at 13:40

1 Answers1

2

Here We Go!!! So, This is a topic that not a lot of people deal with so let me give you some help.

When you Record you have a Session, and an Output

If you read apple's documentation to the delegate methods you will see that the

    startRecordingToOutputFileURL

That will still fire the

    didFinishRecordingToOutputFileAtURL

The problem is that you need to renew the output and add / remove it from the session.

So for swift ->

    ....
    // Remove old output
    session.removeOutput(output);
    // Create new output
    output = AVCaptureMovieFileOutput()
    if session.canAddOutput(output) {
        session.addOutput(output)
        output.startRecordingToOutputFileURL(fileDest, recordingDelegate: self.delegate)
    }  
    .... 

and that will fire the delegate method (DELEGATE METHOD !!!)

    func captureOutput(captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAtURL outputFileURL: NSURL!, fromConnections connections: [AnyObject]!, error: NSError!) {
    let outputPath = outputFileURL.path!
    do {
        print(outputPath);
        try NSFileManager.defaultManager().removeItemAtPath(outputPath)
    } catch _ {
        print("error removing file");

    }
    do {
        try NSFileManager.defaultManager().moveItemAtPath(outputFileURL.path!, toPath: outputPath)
    } catch _ {
    print(error);
    }
}

The idea is that you have to do it this way because if you stop recording you need to create a new session and then a new output. This way you only need to create a new output.

Please let me know if this needs any edits or tweaking but it works for me.

  • Hmm well the documentation here says that on iOS you need to call stopRecording() before you call startRecording() I've tried to get your suggested code working in Apple's sample AVCam app but it seems to throw an error after I try to start the first new movie segment "Stop any other actions using the recording device and try again." So I dunno I think you gotta use AVAssetWriter to make this work unfortunately – joel.d Dec 29 '22 at 05:01
  • The code I provided is old, and there may be better ways to do it now / the old code deprecated. The point I think I was trying to make - is that if you “stop recording” you need to handle the session, I was giving a workaround. Because it is a workaround, plugging it into Apple’s sample application may not be that simple. – Andrew Riznyk Jan 03 '23 at 12:56
  • Yea I agree stop recording isn't what you want here. I actually got this working recently (so on latest iOS etc.) by creating multiple AVAssetWriters and manually sending the CMSampleBuffer's to each based on their presentationTimestamp. The tricky thing was they come out-of-order so you have to determine a cutoff time and then keep both writers open for a while to avoid blanks. – joel.d Jan 09 '23 at 22:47