Search code examples
iosobjective-ciphoneios9gpuimage

How to save GPUImage filtered video with Audio?


I have already apply filter on video. But the issue with saving it in Camera roll with Audio output. But unfortunately I am failing to save it.

see below code.

-(IBAction)saveVideo:(id)sender{

    NSString *pathToMovie = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Movie.mov"];
    unlink([pathToMovie UTF8String]); // If a file already exists, AVAssetWriter won't let you record new frames, so delete the old movie
    NSURL *movieURL = [NSURL fileURLWithPath:pathToMovie];

    _movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(720.0, 1280.0)];
    _movieWriter.shouldPassthroughAudio = YES;
    //_movieWriter.assetWriter.movieFragmentInterval = kCMTimeInvalid;
    _movieWriter.hasAudioTrack = YES;
    _movieFile.audioEncodingTarget = self.movieWriter;
    [_filter addTarget:_movieWriter];
    [_movieFile enableSynchronizedEncodingUsingMovieWriter:_movieWriter];

    [_movieWriter startRecording];
    __block GPUImageOutput<GPUImageInput> *weekfilter = _filter;
    __block GPUImageMovieWriter *weekMovieWriter = _movieWriter;
    ViewControllerFilters* __weak weakSelf = self;

    [_movieWriter setCompletionBlock:^{
        [weekfilter removeTarget:weekMovieWriter];
        [weekMovieWriter finishRecording];

        dispatch_async(dispatch_get_main_queue(), ^{
            // [timer invalidate];
            //self.progressLabel.text = @"100%";
//            [[SoundManager sharedManager] stopAnimating];
//            [weakSelf performSegueWithIdentifier:export sender:movieURL];
            [weakSelf saveToCameraRoll:movieURL];
        });
    }];
}

I got the log can't write frame. and receive memory warning and app crash.


Solution

  • Make sure that moviefile declare as strong.

    -(void)saveVideo{
        NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    
        AVURLAsset *asset = [AVURLAsset URLAssetWithURL:self.url options:nil];
        AVAssetTrack *videoAssetTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
        //CGAffineTransform videoTransform = CGAffineTransformMakeRotation(self.ValueOrientation);
    
        self.movieFile1 = [[GPUImageMovie alloc] initWithURL:self.url];
        self.movieFile1.runBenchmark = YES;
        self.filterExport = self.filterobject;
        [self.movieFile1 addTarget:self.filterExport];
    
        [self.filterExport removeAllTargets];
    
        NSString* filteredFile= [documentsDirectory stringByAppendingPathComponent:@"MovieFiltered.m4v"];
        unlink([filteredFile UTF8String]);
        NSURL *movieURL = [NSURL fileURLWithPath:filteredFile];
    
        self.movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(videoAssetTrack.naturalSize.width, videoAssetTrack.naturalSize.height)];
        [self.filterExport addTarget:self.movieWriter];
    
        self.movieWriter.shouldPassthroughAudio = YES;
        self.movieFile1.audioEncodingTarget = self.movieWriter;
        [self.movieFile1 enableSynchronizedEncodingUsingMovieWriter:self.movieWriter];
         [self.movieWriter startRecording];
        [self.movieFile1 startProcessing];
    
        __weak typeof(self) weakSelf = self;
    
        [self.movieWriter setCompletionBlock:^{
            NSLog(@"Recording done");
            [weakSelf.movieWriter finishRecording];
           // [weakSelf writeToAlbum:movieURL];
        }];
    }