Search code examples
iosobjective-cgpuimagem4v

Cannot play video recorder by GPUImage


I am using GPUImage library to record a video to a file on filesystem. I save it as m4v file. This is the code I'm using:

    NSString *pathToMovie = [NSHomeDirectory() stringByAppendingPathComponent:recordingDestination];
    unlink([pathToMovie UTF8String]);
    NSURL *movieURL = [NSURL fileURLWithPath:pathToMovie];

    movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(1280.0, 720.0)];
    [videoCameraFilter addTarget:movieWriter];

    movieWriter.shouldPassthroughAudio = YES;
    movieFile.audioEncodingTarget = movieWriter;
    [movieFile enableSynchronizedEncodingUsingMovieWriter:movieWriter];

    [movieWriter startRecording];
    [movieFile startProcessing];

    [movieWriter setCompletionBlock:^{
        [videoCameraFilter removeTarget:movieWriter];
        [movieWriter finishRecording];
    }];

This records a m4v video. I then try to play it with MPMoviePlayerController:

    NSString *videoPath = [NSString stringWithFormat:@"%@/%@", [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"], [libraryFiles objectAtIndex:selectedCell]];
    NSLog(videoPath);
    NSURL *url=[[NSURL alloc] initWithString:videoPath];
    MPMoviePlayerController *moviePlayer=[[MPMoviePlayerController alloc] initWithContentURL:url];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayBackDidFinish) name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayer];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayBackDonePressed) name:MPMoviePlayerDidExitFullscreenNotification object:moviePlayer];

    moviePlayer.controlStyle=MPMovieControlStyleDefault;
    [moviePlayer play];
    [self.view addSubview:moviePlayer.view];
    [moviePlayer setFullscreen:YES animated:YES];

However, the player just starts buffering and nothing happens. The video doesn't start playing. The player is just buffering forever. The app doesn't crash and there are no warnings in the console, so I don't know what is the problem.


Solution

  • I see at a couple of things that don't look right.

    First off you're writing directly to NSHomeDirectory which returns the application directory that is however not writeable (see reference). Either write to the Documents folder or the Library/Caches folder instead.

    Secondly I don't see how videoCameraFilter is defined. You need to make sure to add it as a target of movieFile

    GPUImageMovie *movieFile = [[GPUImageMovie alloc] initWithURL:sampleURL];
    
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *pathToMovie = [documentsDirectory stringByAppendingPathComponent:@"filtered-movie.m4v"];
    unlink([pathToMovie UTF8String]);
    NSURL *movieURL = [NSURL fileURLWithPath:pathToMovie];
    
    GPUImageMovieWriter *movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(1920.0, 1080.0)];
    GPUImageBoxBlurFilter * videoCameraFilter = [[GPUImageBoxBlurFilter alloc] init]; // just a random filter...
    videoCameraFilter.blurSize = 2.0;
    [movieFile addTarget:videoCameraFilter];
    [videoCameraFilter addTarget:movieWriter];
    
    movieWriter.shouldPassthroughAudio = YES;
    movieFile.audioEncodingTarget = movieWriter;
    [movieFile enableSynchronizedEncodingUsingMovieWriter:movieWriter];
    
    [movieWriter startRecording];
    [movieFile startProcessing];
    
    __weak GPUImageMovieWriter *weakMoviewWriter = movieWriter;
    [movieWriter setCompletionBlock:^{
        [movieFile removeTarget:weakMoviewWriter];
        [weakMoviewWriter finishRecording];
    }];
    

    * EDIT:

    Did you try yo making moviePlayer a property/ivar as @SAMIR RATHOD suggested? The fact that the moviePlayer stays there buffering endlessly is most probably caused because it's not being retained.

    add a property to your viewController's interface:

    @property (nonatomic, strong) MPMoviePlayerController *moviePlayer;
    

    and instantiate your MPMoviewPlayerController:

    self.moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];