分段录制的实现
来源:互联网 发布:起点写作软件 编辑:程序博客网 时间:2024/05/18 22:17
分段录制也就是可以暂停之后恢复录制,并且录制结束之后是在同一个文件中。不管video还是audio都是有时间戳的frame,真是因为有时间戳播放器才能有序的进行播放了。因此在分段录制中,只要在暂停的时候记录一下当前的一个时间戳,然后在恢复之后计算一下这之间的时间差,然后在将这个frame写入之前修改一下这个frame的时间戳就行了。原理还是蛮简单的,因此实现也简单的多了。code说明一切,需要的咨询读一下代码。
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection{ @synchronized(self) { if(!self.isRecording||self.isPause){ return; } BOOL isVideo = YES; if(captureOutput == self.audioOutput){ isVideo = NO; } if(![self processSampleBuffer:sampleBuffer isVideo:isVideo]){ if((sampleBuffer = [self processPartialRecord:sampleBuffer isVideo:isVideo])) { [self encodeFrame:sampleBuffer isVideo:isVideo]; CFRelease(sampleBuffer); } } } }- (CMSampleBufferRef)processPartialRecord:(CMSampleBufferRef)sampleBuffer isVideo:(BOOL)isVideo{ if (_interrupted){ if (isVideo){ return nil; } _interrupted = NO; CMTime presentTimeStamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer); CMTime last = isVideo ? _lastVideo : _lastAudio; if (CMTIME_IS_VALID(last)){ if (CMTIME_IS_VALID(_timeOffset)){ presentTimeStamp = CMTimeSubtract(presentTimeStamp, _timeOffset); } CMTime offset = CMTimeSubtract(presentTimeStamp, last); [self logCMTime:offset]; if (_timeOffset.value == 0){ _timeOffset = offset; } else{ _timeOffset = CMTimeAdd(_timeOffset, offset); } } _lastVideo.flags = 0; _lastAudio.flags = 0; } CFRetain(sampleBuffer); if (_timeOffset.value > 0){ CFRelease(sampleBuffer); sampleBuffer = [self adjustTime:sampleBuffer by:_timeOffset]; } CMTime presentTimeStamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer); CMTime duration = CMSampleBufferGetDuration(sampleBuffer); if (duration.value > 0){ presentTimeStamp = CMTimeAdd(presentTimeStamp, duration); } if (isVideo){ _lastVideo = presentTimeStamp; } else{ _lastAudio = presentTimeStamp; } return sampleBuffer;}- (CMSampleBufferRef) adjustTime:(CMSampleBufferRef) sample by:(CMTime) offset{ CMItemCount count; CMSampleBufferGetSampleTimingInfoArray(sample, 0, nil, &count); CMSampleTimingInfo* pInfo = malloc(sizeof(CMSampleTimingInfo) * count); CMSampleBufferGetSampleTimingInfoArray(sample, count, pInfo, &count); for (CMItemCount i = 0; i < count; i++){ pInfo[i].decodeTimeStamp = CMTimeSubtract(pInfo[i].decodeTimeStamp, offset); pInfo[i].presentationTimeStamp = CMTimeSubtract(pInfo[i].presentationTimeStamp, offset); } CMSampleBufferRef sout; CMSampleBufferCreateCopyWithNewTiming(nil, sample, count, pInfo, &sout); free(pInfo); return sout;}- (BOOL) encodeFrame:(CMSampleBufferRef) sampleBuffer isVideo:(BOOL)isVideo{ if (CMSampleBufferDataIsReady(sampleBuffer)) { if (_writer.status == AVAssetWriterStatusUnknown){ CMTime startTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer); [_writer startWriting]; [_writer startSessionAtSourceTime:startTime]; } if (_writer.status == AVAssetWriterStatusFailed){ NSLog(@"error %@", _writer.error.localizedDescription); return NO; } if (isVideo){ if (self.videoWriterInput.readyForMoreMediaData){ [self.videoWriterInput appendSampleBuffer:sampleBuffer]; return YES; } }else{ if(self.audioWriterInput.readyForMoreMediaData){ [self.audioWriterInput appendSampleBuffer:sampleBuffer]; return YES; } } } return NO;}
0 1
- 分段录制的实现
- android--分段录制视频
- Android Multimedia实战(二)使用MediaRecorder实现分段录制视频,mp4parser合成视频功能
- sql实现分段功能的函数
- 虚拟内存的分段与分页实现
- Android学习之分段选择器的实现
- iphone实现声音的录制和播放
- iphone实现声音的录制和播放
- IOS 实现声音的录制和播放
- iphone实现声音的录制和播放
- iOS 使用AVAudioRecorder实现音频的录制
- Android录制屏幕的实现方法
- 关于monkeyrunner录制与回放的实现
- 屏幕录制在h323上的实现
- 分段表视图cell乱的问题(分段表示图cellForRowAtIndexPath的正确实现)
- EasySegmentedBarView简单易用的自定义分段控件,方便快速实现分段效果
- 简易的android 通话录音实现【只能录制MIC的声音,不能录制对方的声音】
- LoadRunner日积月累(9) —— 分段录制脚本
- oracle的JDK替换openJDK
- 动画演示10个有趣但毫无用处的Linux命令
- ubuntu 忘记密码,忘记root密码的解决办法
- lua学习笔记
- ARM汇编
- 分段录制的实现
- 编译安装glibc
- cocos2d-x在eclipse上搭建开发环境
- 10款设计精巧的jQuery/CSS3插件
- BufferedOutputStream 源码分析
- [QT]——Qt 常用命令,宏,pro文件格式
- 驗證漢字的正則表達式
- Delphi实现RGB色环的代码绘制
- DataInputStream 源码分析