Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Examples/Sources/SCRecorderViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ - (void)viewDidLoad {
_recorder = [SCRecorder recorder];
_recorder.sessionPreset = AVCaptureSessionPreset1280x720;
_recorder.maxRecordDuration = CMTimeMake(5, 1);
_recorder.videoConfiguration.maxFrameRate = 10;
_recorder.videoConfiguration.timeScale = 0.333;

_recorder.delegate = self;
_recorder.autoSetVideoOrientation = YES;
Expand Down
25 changes: 24 additions & 1 deletion Library/Sources/SCRecordSession.m
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,10 @@ - (id)init {
_currentSegmentCount = 0;
_timeOffset = kCMTimeZero;
_lastTimeAudio = kCMTimeZero;
_lastAppendedVideo = kCMTimeZero;
_currentSegmentDuration = kCMTimeZero;
_segmentsDuration = kCMTimeZero;
_sessionBegan = kCMTimeZero;
_date = [NSDate date];
_recordSegmentsDirectory = SCRecordSessionTemporaryDirectory;
_identifier = [NSString stringWithFormat:@"%ld", (long)[_date timeIntervalSince1970]];
Expand Down Expand Up @@ -599,6 +601,10 @@ - (BOOL)appendAudioSampleBuffer:(CMSampleBufferRef)audioSampleBuffer {
if ([_audioInput isReadyForMoreMediaData]) {
CMTime actualBufferTime = CMSampleBufferGetPresentationTimeStamp(audioSampleBuffer);

if (CMTIME_IS_INVALID(_sessionBegan)) {
_sessionBegan = actualBufferTime;
}

if (CMTIME_IS_INVALID(_timeOffset)) {
_timeOffset = CMTimeSubtract(actualBufferTime, _currentSegmentDuration);
}
Expand Down Expand Up @@ -631,6 +637,23 @@ - (BOOL)appendVideoSampleBuffer:(CMSampleBufferRef)videoSampleBuffer duration:(C
if ([_videoInput isReadyForMoreMediaData]) {
CMTime actualBufferTime = CMSampleBufferGetPresentationTimeStamp(videoSampleBuffer);

if (CMTIME_IS_INVALID(_sessionBegan)) {
_sessionBegan = actualBufferTime;
}

if (_videoConfiguration.maxFrameRate > 0) {
CMTime interval = CMTimeMake(1, _videoConfiguration.maxFrameRate);

CMTime offset = CMTimeSubtract(actualBufferTime, _lastAppendedVideo);
if (CMTIME_COMPARE_INLINE(_lastAppendedVideo, ==, kCMTimeZero)) {
offset = CMTimeSubtract(actualBufferTime, _sessionBegan);
}

if (CMTIME_COMPARE_INLINE(offset, <, interval)) {
return NO;
}
}

if (CMTIME_IS_INVALID(_timeOffset)) {
_timeOffset = CMTimeSubtract(actualBufferTime, _currentSegmentDuration);
// NSLog(@"Recomputed time offset to: %fs", CMTimeGetSeconds(_timeOffset));
Expand All @@ -644,7 +667,6 @@ - (BOOL)appendVideoSampleBuffer:(CMSampleBufferRef)videoSampleBuffer duration:(C
}

CMTime bufferTimestamp = CMTimeSubtract(actualBufferTime, _timeOffset);

if (_videoPixelBufferAdaptor != nil) {
CIImage *image = [CIImage imageWithCVPixelBuffer:CMSampleBufferGetImageBuffer(videoSampleBuffer)];

Expand Down Expand Up @@ -674,6 +696,7 @@ - (BOOL)appendVideoSampleBuffer:(CMSampleBufferRef)videoSampleBuffer duration:(C
CFRelease(adjustedBuffer);
}

_lastAppendedVideo = actualBufferTime;
_currentSegmentDuration = CMTimeAdd(bufferTimestamp, duration);

_currentSegmentHasVideo = YES;
Expand Down
2 changes: 2 additions & 0 deletions Library/Sources/SCRecordSession_Internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
int _currentSegmentCount;
CMTime _timeOffset;
CMTime _lastTimeAudio;
CMTime _lastAppendedVideo;
CMTime _sessionBegan;

SCVideoConfiguration *_videoConfiguration;
SCAudioConfiguration *_audioConfiguration;
Expand Down
28 changes: 26 additions & 2 deletions Library/Sources/SCRecorder.m
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ - (void)commitSessionConfiguration {
if (_captureSession != nil) {
_beginSessionConfigurationCount--;
if (_beginSessionConfigurationCount == 0) {
[_captureSession commitConfiguration];
[self.captureSession commitConfiguration];
}
}
}
Expand Down Expand Up @@ -967,7 +967,31 @@ - (void)setPhotoOutputSettings:(NSDictionary *)photoOutputSettings {
- (void)setDevice:(AVCaptureDevicePosition)device {
_device = device;
if (_captureSession != nil) {
[self reconfigureVideoInput:self.videoConfiguration.enabled audioInput:NO];

[self beginSessionConfiguration];
NSError *error = nil;
AVCaptureDeviceInput *currentInput = [self currentDeviceInputForMediaType:AVMediaTypeVideo];
AVCaptureDeviceInput *newInput = [[AVCaptureDeviceInput alloc] initWithDevice:[self videoDevice] error:&error];

if (error == nil) {
[_captureSession removeInput:currentInput];
if ([_captureSession canAddInput:newInput]) {
[_captureSession addInput:newInput];
} else {
[_captureSession addInput:currentInput];
error = [SCRecorder createError:@"Failed to add input to capture session"];
}
}

dispatch_sync(_recordSessionQueue, ^{
[self updateVideoOrientation];
});
[self commitSessionConfiguration];

id<SCRecorderDelegate> delegate = self.delegate;
if ([delegate respondsToSelector:@selector(recorder:didReconfigureVideoInput:)]) {
[delegate recorder:self didReconfigureVideoInput:error];
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion Library/Sources/SCVideoConfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ typedef enum : NSUInteger {
@property (copy, nonatomic) NSString *scalingMode;

/**
The maximum framerate that this SCRecordSession should handle
The maximum input framerate that this SCRecordSession should handle
If the camera appends too much frames, they will be dropped.
If this property's value is 0, it will use the current video
framerate from the camera.
Expand Down