GPUImageMovie pause while applying filter

前端 未结 2 1561
一整个雨季
一整个雨季 2020-12-17 05:36

I am using Brad Larson\'s great library GPUImage for my application. Currently I am stuck with an issue. My application captures 10 second videos and after that allows

相关标签:
2条回答
  • 2020-12-17 05:44

    And finally I fixed this after too many searches and try. We need to initiate GPUImageMovie with AVPlayerItem instead of URL. I got this valuable clue from here.

    I am posting my code which I am currently using in my application and it is working as expected. But there are performance issues in iPod 6.1 and I am working on enhancements of the same.

    Initial method to setup GPUImageMovie,

    - (void)setupVideo
    {
        playerItem = [[AVPlayerItem alloc]initWithURL:self.recordSession.outputUrl];
        player = [AVPlayer playerWithPlayerItem:playerItem];
    
        movieFile = [[GPUImageMovie alloc] initWithPlayerItem:playerItem];
    
        movieFile.runBenchmark = YES;
        movieFile.playAtActualSpeed = YES;
        [self.view sendSubviewToBack:self.videoView];
    
        [movieFile addTarget:filter];
        [filter addTarget:self.videoView];
    
        [movieFile startProcessing];
        movieRunning = YES;
    
        dispatch_async(dispatch_get_main_queue(), ^{
            self.playButton.hidden = YES;
        });
    
        player.rate = 1.0;
    }
    

    This method is called when user clicks on a filter button.

    - (void)filterClicked:(UIButton *)button
    {
        // Set paused time. If player reaches end of the video, set pausedTime to 0.
        if (CMTIME_COMPARE_INLINE(pausedTime, !=,  player.currentItem.asset.duration)) {
            pausedTime = player.currentTime;
        } else {
            pausedTime = CMTimeMake(0, 600.0);
        }
        [self.videoView setBackgroundColor:[UIColor clearColor]];
    
        [movieFile cancelProcessing];
    
        switch (button.tag)
        {
        case 0:
            filter = [[GPUImageFilter alloc] init];
            break;
        case 1:
            filter = [[GPUImageColorInvertFilter alloc] init];
            break;
        case 2:
            filter = [[GPUImageEmbossFilter alloc] init];
            break;
        case 3:
            filter = [[GPUImageGrayscaleFilter alloc] init];
            break;
        default:
            filter = [[GPUImageFilter alloc] init];
            break;
        }
    
        [self filterVideo];
    
    }
    

    After filter generation, video play resume is handled in this method.

    - (void)filterVideo {
    
        // AVPlayerItem is initialized with required url
    
        playerItem = [[AVPlayerItem alloc]initWithURL:self.outputUrl]; 
        [player replaceCurrentItemWithPlayerItem:playerItem];
    
        //GPUImageMovie is initialized with AVPlayerItem
    
        movieFile = [[GPUImageMovie alloc] initWithPlayerItem:playerItem];
    
        movieFile.runBenchmark = YES;
        movieFile.playAtActualSpeed = YES;
    
        // Adding targets for movieFile and filter
    
        [movieFile addTarget:filter];
        [filter addTarget:self.videoView]; // self.videoView is my GPUImageView
    
        [movieFile startProcessing];
        movieRunning = YES;
    
        dispatch_async(dispatch_get_main_queue(), ^{
            self.playButton.hidden = YES;
        });
    
        // Player rate is set to 0 means player is paused
    
        [player setRate:0.0];
    
        // Seeking to the point where video was paused
    
         if (CMTIME_COMPARE_INLINE(pausedTime, !=, player.currentItem.asset.duration)) {
            [player seekToTime:pausedTime];
        }
        [player play];
    }
    
    0 讨论(0)
  • 2020-12-17 05:54

    In my case, using an AVPlayerItem was not feasible (I use compositions).

    Instead I made this code:

    class PausableGPUImageMovie: GPUImageMovie {
        var isPaused = false
    
        override func readNextVideoFrame(from readerVideoTrackOutput: AVAssetReaderOutput!) -> Bool {
            while isPaused {
                usleep(100_000)
            }
            return super.readNextVideoFrame(from: readerVideoTrackOutput)
        }
    }
    

    Very dump but feel free to improve it.

    0 讨论(0)
提交回复
热议问题