GPUImage завершается из-за [AVAssetWriter startWriting] Невозможно вызвать метод, когда статус 3'
У меня проблема с запуском GPUImage. Я изменил программу SimpleVideoFileFilter (заменил фильтр на chromakeyfilter) и использую свое собственное видео. Моя программа завершается из-за следующей ошибки:
[AVAssetWriter startWriting] Невозможно вызвать метод, когда статус 3'
Я прошел через форумы, но не уверен, почему moviewriter закрывается, а затем кто-то пишет на него.
Я использую iPhone4 под управлением iOS 7.0
Любые подсказки очень ценятся. Большое спасибо!
6 ответов
Проверьте, существует ли уже файл назначения. Если это так, удалите его.
Я пытался добавить файл в каталог, который не существует. Пример: /Videos/Video.mov, оставив его только /Video.mov сработало.
@Seasia Creative, у меня недостаточно репутации, чтобы добавить комментарий к этому списку, я создаю новый список, чтобы ответить U. Я проверяю выходной URL, журнал консоли "/var~~~~/tmpmerge.mp4", так что я понимаю, что я скучаю по "/" --->"/var~~~~/tmp/merge.mp4". Если URL неверный, проект сталкивается с той же ошибкой. надеюсь помочь некоторым.
movieFile1 = [[GPUImageMovie alloc] initWithURL:movieFileURL1];
movieFile2 = [[GPUImageMovie alloc] initWithURL:movieFileURL2];
movieFile2.runBenchmark = YES;
movieFile2.playAtActualSpeed = NO;
filter = [[GPUImageChromaKeyBlendFilter alloc] init];
[(GPUImageChromaKeyBlendFilter *)filter setColorToReplaceRed:0.0 green:1.0 blue:0.0];
[(GPUImageChromaKeyBlendFilter *)filter setThresholdSensitivity:0.4];
GPUImageView *filterView = (GPUImageView*)displayView;
[filter addTarget:displayView];
[movieFile1 addTarget:filter];
[movieFile2 addTarget:filter];
NSString *pathToMovie = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Movie.m4v"];
unlink([pathToMovie UTF8String]);
NSURL *movieURL = [NSURL fileURLWithPath:pathToMovie];
movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(1920.0, 1280.0)];
[filter addTarget:movieWriter];
movieWriter.shouldPassthroughAudio = YES;
movieFile1.audioEncodingTarget = movieWriter;
[movieFile1 enableSynchronizedEncodingUsingMovieWriter:movieWriter];
[movieWriter startRecording];
[movieFile1 startProcessing];
[movieFile2 startProcessing];
[movieWriter setCompletionBlock:^{
[filter removeTarget:movieWriter];
[movieWriter finishRecording];
}];
Хорошо, у меня есть несколько идей для вас.
Когда вы говорите "он просто показывает кадр и никогда не воспроизводит видео", у нас есть хороший признак того, что весь ваш конвейер обработки от начала до конца функционирует ровно один раз, а затем перестает работать.
Это говорит нам о том, что вы правильно связываете воедино, но некоторые компоненты не существуют дольше, чем один буферный цикл кадра, и впоследствии весь процесс останавливается.
это выглядит как filter
а также movieWriter
относятся к классу (я предполагаю, что они не свойства из-за отсутствия подчеркивания, _filter and _movieWriter
). Так что они будут жить после того, как этот метод закончен (поправьте меня, если я ошибаюсь...)
Я думаю, где вы сталкиваетесь с проблемами, это ваша (GPUImageView*)displayView
Это, вероятно, следует объявить как свойство класса (хотя оно может работать как переменную), а затем создать его экземпляр с помощью метода nib или viewDidLoad контроллера представления.
Как и сейчас, эта строка: GPUImageView* filterView = (GPUImageView*)displayView;
делает назначение для filterView, которое не используется (и, следовательно, не нужно). Не понятно если displayView
на самом деле является примером GPUImageView
или если он все еще будет существовать, когда текущий метод завершится. (на самом деле вы говорите, что это "UIView, который я создал программно")
displayView должен быть подклассом GPUImageView, чтобы все это работало, и он должен быть ограничен классом, а не методом.
Объявите это так:
@property (strong, nonatomic)GPUImageView* displayView;
а затем создать его экземпляр и добавить его в иерархию представлений изнутри viewDidLoad
if (outputPath) {
finalURL = [[stongObj tempFileURL] copy];
DebugLog(@"Start Filter Processing :%@",finalURL);
DebugLog(@"movieUrl :%@",movieUrl);
// [CSUtils removeChuckFilePaths:@[outputPath]];
//Create Image Movie Object
_movieFile = [[GPUImageMovie alloc] initWithURL:outputPath];
//_movieFile = [[GPUImageMovie alloc] initWithURL:[[NSBundle mainBundle] URLForResource:@"videoviewdemo" withExtension:@"mp4"]];
_movieFile.runBenchmark = NO;
_movieFile.playAtActualSpeed = YES;
_movieFile.delegate = self;
//Movie Writer Object
_movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:finalURL size:CGSizeMake([UIScreen mainScreen].bounds.size.height,[UIScreen mainScreen].bounds.size.height)];
//_movieWriter.delegate = self;
//Create Selecetive GPU Image Filter
[stongObj setGpuOutputFilter:selectedVideoFilterType];
//Create Group Filter
groupFilter = [[GPUImageFilterGroup alloc] init];
[groupFilter addTarget:imageOutputFilter];
// Only Single Filter is implemented.
//Apply Initial and Terminal Filter
[(GPUImageFilterGroup *)groupFilter setInitialFilters:[NSArray arrayWithObject:imageOutputFilter]];
[(GPUImageFilterGroup *)groupFilter setTerminalFilter:imageOutputFilter];
//_movieWriter -> groupFilter ->_movieFile
[_movieFile addTarget:groupFilter];
[groupFilter addTarget:_movieWriter];
_movieWriter.shouldPassthroughAudio = YES;
_movieFile.audioEncodingTarget = _movieWriter;
[_movieFile enableSynchronizedEncodingUsingMovieWriter:_movieWriter];
//Start Recording
[_movieWriter startRecording];
//Start Processing
[_movieFile startProcessing];
__weak typeof(self) weekSelf=self;
[_movieWriter setCompletionBlock:^{
__strong typeof(self) stongSelf=weekSelf;
DebugLog(@"Movie Write Completed");
//Finish Recording.
[stongSelf.movieWriter finishRecording];
//Release all object
// [self releaseAllObject];
//remove movieUrl,audioUrl,outputPath
[CSUtils removeChuckFiles:@[movieUrl,audioUrl,outputPath]];
}];
[_movieFile startProcessing]; в этой строке происходит сбой приложения в iOS 8, но на iOS 7 работает нормально