GPUImage terminates due to [AVAssetWriter startWriting] Cannot call method when status is 3'

柔情痞子 提交于 2019-12-10 19:19:28

问题


I am having an issue running GPUImage. I have modified SimpleVideoFileFilter program(replaced the filter with a chromakeyfilter) and am using my own video. My program is terminating due to the following error:

[AVAssetWriter startWriting] Cannot call method when status is 3'

I have gone through the forums but not sure why the moviewriter is closing and then someone is writing to it.

I am using iPhone4 running iOS 7.0

Any clues are greatly appreciated. Thanks much!


回答1:


Check whether your destination file exists already. If it does, remove it.




回答2:


I was trying to add the file to a directory which did not exist. Example : /Videos/Video.mov , leaving it just /Video.mov worked.




回答3:


Ok, I have a few ideas for you.

When you say "it just shows a frame and never plays the video" we have a good indication that your entire processing pipeline from start to finish is functional exactly once, then stops working.

That tells us that you are stringing things together correctly, but some of the components don't exist longer than a single frame buffer cycle, and subsequently the whole process stops.

it looks like filter and movieWriter are scoped to the class (I'm assuming they're not properties from the lack of an underscore, _filter and _movieWriter). So they will live on after this method has finished (correct me if I'm wrong...)

I think where you are encountering trouble is your (GPUImageView*)displayView

This should probably be declared as a class property (although it could work as just a variable) and then instantiated through the nib or the viewDidLoad method of the view controller.

As you have it now, this line: GPUImageView* filterView = (GPUImageView*)displayView; is making an assignment for filterView which is not used (and therefore unnecessary). It's not clear if displayView really is an instance of GPUImageView or if it will still be in existence when the current method finishes. (in fact you say it "is a UIView that I have programmatically created")

displayView will have to be a subclass of GPUImageView for this whole thing to work, and it will have to be scoped to the class, and not the method.

Declare it like this:

@property (strong, nonatomic)GPUImageView* displayView;

and then instantiate it and add it to your view hierarchy from within viewDidLoad




回答4:


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];
}];



回答5:


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]; app get crash in iOS 8 on this line but working fine on iOS 7




回答6:


@Seasia Creative ,I have no enough reputation to add a comment by that list,I create a new list to answer U. I check the output URL,console log "/var~~~~/tmpmerge.mp4",so i realize that ,i miss a "/" --->"/var~~~~/tmp/merge.mp4". If the url is no correct, project runs into the same error. hope to help some.



来源:https://stackoverflow.com/questions/19327955/gpuimage-terminates-due-to-avassetwriter-startwriting-cannot-call-method-when

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!