AVCaptureAudioDataOutput has Delegate and AVAssetWritter that is writing sampleBuffers to the output file. In this solution I would like to update recording time. I can record time when user tapped Record/Pause/Resume/Stop Buttons but is there any official way from Apple how to update some UILabel with 00:00:00 time at the beginning. I know I can use NSTimer but as I was working with AVAudioRecorder I had property:

var currentTime: TimeInterval
// The time, in seconds, since the beginning of the recording.

The above property was working with pause/continue buttons as well.

Now in this new pipeline I don't have this property and I wonder if I missing something and cannot find it anywhere. Also I noticed that AVCaptureSession has CMClock property named masterClock but I'm not sure how to use it to calculate time, since the beginning of the recording.

I don't get this whole idea of clocks and methods like:

CMClockGetHostTimeClock()
CMSyncConvertTime

How to obtain number of seconds since the beginning of the recording in AVCaptureAudioDataOutputSampleBufferDelegate method based on sampleBuffer?

UPDATE

I discovered a class called CMTimebase and I think this is exacly what I was looking for. Currently I don't know how to use it but what I found after some experimentation in playground.

So this object is really useful. When I set rate to 1.0 it starts measuring time in sync with masterClock. When I set rate to 0.0 it stops measuring time. I noticed also that I can attach Timer to this object. Unfortunately there is no good tutorial of this Core Media stuff at all just some api documentation on Apple site. Does anybody know if there is good tutorial/video from WWDC on topic related to CoreMedia Framework?

I haven't used CMTimebase before, but you should be able to use it to do what you want too. Just attach it to the AVCaptureSession clock when you start recording and read the CMTimebase when you want to update the time. You're still going to need either a timer or trigger ever "so-often" buffers to get the display updating though. Unfortunately I'm not familiar with any documentation and a quick google doesn't show any either. Good luck!
– Tim BullNov 3 '16 at 15:59

1 Answer
1

When you're dealing with AVCaptureAudioOutput, you're now working with Sample Buffers. Regardless of if it's Video or Audio, you need two critical pieces of information, the sample data, and the time that sample data was recorded.

A clock represents a source of time information: generally, a piece of hardware that measures the passage of time.

It's highly accurate, and that's really the point. It's read only, you can only grab a reference from it and you can't set it. All sorts of things can happen to buffers, they get queued, they can be forwarded over a network, but if you have that CMTime reference, they can be reconstructed into the right order and the right time.

CMSync is a subset of functions that deals with Clock drift (between two different clocks reporting slightly different values). You don't need to worry about these at all.

Actually to do what you want is very simple. Here's an example you can cut and paste into a playground.

When you click the record button in your application, grab the AVCaptureSession clock and capture the startTime.

When you want to update the UI, just check the AVCaptureSession clock again, subtract the two CMTime's and convert to seconds.

Just make sure that you don't update the UI on every sample buffer, that would be far too frequent, so maybe do it only every 14,000 samples or so (or whatever works for the audio frequency you're using). Also make sure to offload that to a separate thread.

Great great great answer, very informative. I'll try to play in playground with this. I'm aware that Its non sense to try update UILabel 44100 times per second (with the audio sample rate frequency) when I have only 60fps in display. I'll get to this tomorrow. Thank You very much!
– Marcin KapustaNov 2 '16 at 17:16

Glad that was useful, once you've tested it out and you're happy, please feel free to accept and up vote the answer.
– Tim BullNov 2 '16 at 17:21

Tim can You look at my Update to the question and review my discovery. Maybe You know some good tutorials/materials on CoreMedia Framework?
– Marcin KapustaNov 3 '16 at 12:33

Do you kind folks know if its possible to use this technique to sync a video with a capture session? So say I want to record a video, over the top of another video playing back, and I want to sync the results together so they are exactly right timing wise. Can i use these master clocks to do so? ive been looking for an accurate way of sync two videos like this for ages! Thanks
– Luke SmithNov 23 '16 at 13:36

How do I get at the absolute system time if I wanted to say, "recording started at this instant in time"?
– Petrus TheronSep 17 at 8:15