GPUImageMovieWriter录制视频问题
来源:互联网 发布:java 写入word 编辑:程序博客网 时间:2024/04/29 19:50
- (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex;
{
// You can set up infinite update loops, so this helps to short circuit them
if (hasReceivedFirstFrame && hasReceivedSecondFrame)
{
return;
}
BOOL updatedMovieFrameOppositeStillImage = NO;
if (textureIndex == 0)
{
hasReceivedFirstFrame = YES;
firstFrameTime = frameTime;
if (secondFrameCheckDisabled)
{
hasReceivedSecondFrame = YES;
}
if (!CMTIME_IS_INDEFINITE(frameTime))
{
if CMTIME_IS_INDEFINITE(secondFrameTime)
{
updatedMovieFrameOppositeStillImage = YES;
}
}
}
else
{
hasReceivedSecondFrame = YES;
secondFrameTime = frameTime;
if (firstFrameCheckDisabled)
{
hasReceivedFirstFrame = YES;
}
if (!CMTIME_IS_INDEFINITE(frameTime))
{
if CMTIME_IS_INDEFINITE(firstFrameTime)
{
updatedMovieFrameOppositeStillImage = YES;
}
}
}
// || (hasReceivedFirstFrame && secondFrameCheckDisabled) || (hasReceivedSecondFrame && firstFrameCheckDisabled)
if ((hasReceivedFirstFrame && hasReceivedSecondFrame) || updatedMovieFrameOppositeStillImage)
{
CMTime passOnFrameTime = (!CMTIME_IS_INDEFINITE(firstFrameTime)) ? firstFrameTime : secondFrameTime;
[super newFrameReadyAtTime:passOnFrameTime atIndex:0]; // Bugfix when trying to record: always use time from first input (unless indefinite, in which case use the second input)
hasReceivedFirstFrame = NO;
hasReceivedSecondFrame = NO;
}
}
因为两个movie在不同的线程,如果2个movie帧率不一样,因为录制的时候是全速的,这样可能movie1已经来到上面方法很多次,而movie2才来一帧,这样就导致movie1
丢失了帧。解决方法:
- (BOOL)readNextVideoFrameFromOutput:(AVAssetReaderOutput *)readerVideoTrackOutput;
{
if (reader.status == AVAssetReaderStatusReading && ! videoEncodingIsFinished)
{
CMSampleBufferRef sampleBufferRef = [readerVideoTrackOutput copyNextSampleBuffer];
if (sampleBufferRef)
{
if (_playAtActualSpeed)
{
...
}else{
//这里判断另外一个movie是否准备,没准备就等一下
}
__unsafe_unretained GPUImageMovie *weakSelf = self;
runSynchronouslyOnVideoProcessingQueue(^{
[weakSelf processMovieFrame:sampleBufferRef];
CMSampleBufferInvalidate(sampleBufferRef);
CFRelease(sampleBufferRef);
});
return YES;
}
else
{
if (!keepLooping) {
videoEncodingIsFinished = YES;
if( videoEncodingIsFinished && audioEncodingIsFinished )
[self endProcessing];
}
}
}
else if (synchronizedMovieWriter != nil)
{
if (reader.status == AVAssetReaderStatusCompleted)
{
[self endProcessing];
}
}
return NO;
}
2、使用GPUImageMovieWriter的processAudioBuffer写音频时,如果是写太快,可能导致音频丢失,可以在线程中sleep一下。
When expectsMediaDataInRealTime is YES, readyForMoreMediaData will become NO only when the input cannot process media samples as quickly as they are being provided by the client. If readyForMoreMediaData becomes NO for a real-time source, the client may need to drop samples or consider reducing the data rate of appended samples.
3、使用GPUImageThreeInput,需要自己写fragment shafer,init的时候传入。
- GPUImageMovieWriter录制视频问题
- GPUImageMovieWriter黑屏问题
- 安卓录制视频问题
- android视频录制问题描述
- android 录制视频清晰度问题
- directshow音视频录制同步问题
- 用MediaRecorder录制视频太短崩的问题
- MediaRecorder 录制视频适配问题
- 使用MediaRecorder录制视频时模糊问题
- android vlc截图与视频录制问题
- 关于视频录制预览摄像头拉伸问题
- 关于视频录制预览摄像头拉伸问题
- 录制视频
- 视频录制
- 视频录制
- 视频录制
- 录制视频
- 录制视频
- equals()和hashCode()隐式调用时的约定详解
- 探讨对理想团队模式构建的设想以及对软件流程的理解
- java source attacher
- linux下syscall函数,SYS_gettid
- 如何获取用户
- GPUImageMovieWriter录制视频问题
- poj 生理周期 1006 (中国剩余定理)水
- Qt上传文件
- numpy、scipy、matplotlib安装与配置
- 责任链模式
- 在Windows Server 2008 R2 ServerCore上配置IIS服务
- android之Afinal框架
- HTTP状态码大全
- Goldengate简单搭建