来自GPUImageMovie的视频在开头有一个红框

时间:2014-04-23 05:13:39

标签: objective-c video avfoundation gpuimage gpuimagestillcamera

感谢您看到这个问题。

我从GPUImageMovieComposition和GPUImageWriter创建一部电影,有时(5%~10%)电影在开头有红框。

请教我这种现象的原因。

我使用AVFileTypeMPEG4作为样本文件类型,但AVFileTypeQuickTimeMovie也是相同的。

_movieFile = [[GPUImageMovieComposition alloc] initWithComposition:composition andVideoComposition:videoComposition andAudioMix:nil];
_movieFile.playAtActualSpeed = YES;

_movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:processedMovieURL
                                                        size:CGSizeMake(1280.0, 720.0)
                                                    fileType:AVFileTypeMPEG4
                                              outputSettings:videoSetting];
_movieWriter.shouldPassthroughAudio = NO;
[_movieWriter setVideoInputReadyCallback:nil];
[_movieWriter setHasAudioTrack:YES audioSettings:audioSetting];
[_movieFile addTarget:_movieWriter];
_movieFile.audioEncodingTarget = _movieWriter;
[_movieFile enableSynchronizedEncodingUsingMovieWriter:_movieWriter];    

[_movieWriter startRecording];
[_movieFile startProcessing];

最后我找到了解决方法...但不是完美的方式...

我修改了  - (void)processMovieFrame:(CVPixelBufferRef)movieFrame withSampleTime:(CMTime)currentSampleTime
GPUImageMovie.m一点点。

设置currentSampleTime后,所有红框都有currentSampleTime.value == 0 所以我在currentSampleTime

时避免设置currentSampleTime.value == 0

以下是我实际使用的一些代码。

 for (id<GPUImageInput> currentTarget in targets)
  {
       NSInteger indexOfObject = [targets indexOfObject:currentTarget];
       NSInteger targetTextureIndex = [[targetTextureIndices objectAtIndex:indexOfObject] integerValue];
       if(currentSampleTime.value != 0){
           [currentTarget newFrameReadyAtTime:currentSampleTime atIndex:targetTextureIndex];
       }
   }

2 个答案:

答案 0 :(得分:2)

在我的情况下, GPUImageMovieWriter 录制的视频开头有不是红色但只是空白帧

问题是音频样本出现的时间早于视频帧和assetWriter会话早于第一个视频帧可用时。

我通过替换此代码修改 processAudioBuffer 功能来解决这个问题

if (CMTIME_IS_INVALID(startTime))
{
  runSynchronouslyOnContextQueue(_movieWriterContext, ^{
    if ((audioInputReadyCallback == NULL) && (assetWriter.status != AVAssetWriterStatusWriting))
    {
      [assetWriter startWriting];
    }
    [assetWriter startSessionAtSourceTime:currentSampleTime];
    startTime = currentSampleTime;
  });
}

在此

if (CMTIME_IS_INVALID(startTime))
{
  NSLog(@"0: Had to drop an audio frame: %@", CFBridgingRelease(CMTimeCopyDescription(kCFAllocatorDefault, currentSampleTime)));
  if (_shouldInvalidateAudioSampleWhenDone)
  {
    CMSampleBufferInvalidate(audioBuffer);
  }
  CFRelease(audioBuffer);
  return;
}

此修复程序适用于2014年5月27日至7月1日的最新版本的GPUImage。

答案 1 :(得分:1)

到目前为止,我发现的唯一解决方案是让我从这个问题中解脱出来,恢复提交e98cc813b。 我通过使用 git bisect 并在同一视频上执行批量处理测试来解决这个问题。 此提交已经具有我的项目的所有必需功能,并且只需要很少的更改就可以使其更稳定。您可以在此处查看更改:https://github.com/crazyjooe/GPUImage

此外,经过大量测试后,我可以说处理本身变得更加稳定,特别是在取消方面。 我想知道在引入所有更改后,视频处理如何变得不那么可靠和稳定。