在 GPUImage 中应用视频过滤器时播放音频

Playing audio while applying video filter in GPUImage

我用谷歌搜索了这个问题,但没有找到任何解决方案。

所以,我的问题是, 我正在使用 GPUImage 将视频过滤器应用于视频文件。同时,该视频的声音没有播放。我知道 GPUImage 在应用过滤器时不支持声音播放。

那么,我该如何实现呢?

像这样添加对AVPlayer的支持就可以实现声音播放

  1. GPUImageMovie.h

    @property(readwrite, nonatomic) BOOL playSound;

  2. GPUImageMovie.m 中,像这样更新 @interface GPUImageMovie ()

    @interface GPUImageMovie() <AVPlayerItemOutputPullDelegate> 
    {
        // Add this
        BOOL hasAudioTrack;
    
        .........
        ........
    
       // Add all below three lines
       AVPlayer *theAudioPlayer;
       CFAbsoluteTime startActualFrameTime;
       CGFloat currentVideoTime;
    }
    
  3. 之后,在 -(void)startProcessing 方法中,添加以下行。

    - (void)startProcessing
    {
       // Add this
       currentVideoTime = 0.0f;
    
       .....
       .....
    
       // Add this
       if (self.playSound)
       {
           [self setupSound];
       }
    
       GPUImageMovie __block *blockSelf = self;
    
       [inputAsset loadValuesAsynchronouslyForKeys:[NSArray arrayWithObject:@"tracks"] completionHandler: ^{
        runSynchronouslyOnVideoProcessingQueue(^{
    
                .........
                .........
    
                // Add this
                startActualFrameTime = CFAbsoluteTimeGetCurrent() - currentVideoTime;
    
                .......
                .......
            });
       }];
    }
    
  4. 再次,在-(AVAssetReader*)createAssetReader更新它,

    - (AVAssetReader*)createAssetReader
    {
        .......
        .......  
        BOOL shouldRecordAudioTrack = (([audioTracks count] > 0) &&  (self.audioEncodingTarget != nil));
    
        // Add this
        hasAudioTrack = ([audioTracks count] > 0);
    
        .........
    }
    
  5. - (void)processAsset,

    - (void)processAsset
    {
    
       .......
       .......
    
       if ([reader startReading] == NO)
       {
          NSLog(@"Error reading from file at URL: %@", self.url);
          return;
       }
    
       // Add this
       if (self.playSound && hasAudioTrack)
       {
          [theAudioPlayer seekToTime:kCMTimeZero];
          [theAudioPlayer play];
       }
    
       .........
       .........
    }
    
  6. -(void)endProcessing,

    - (void)endProcessing
    {
       .........
       .........
    
       if (self.playerItem && (displayLink != nil))
       {
          [displayLink invalidate]; // remove from all run loops
          displayLink = nil;
       } 
    
       // Add this
       if (theAudioPlayer != nil)
       {
          [theAudioPlayer pause];
          [theAudioPlayer seekToTime:kCMTimeZero];
       }
    
       .........
       .........
    }
    
  7. 最后添加新方法-(void)setupSound,

    // Add this
    - (void)setupSound
    {
       if (theAudioPlayer != nil)
       {
           [theAudioPlayer pause];
           [theAudioPlayer seekToTime:kCMTimeZero];
           theAudioPlayer = nil;
       }
    
       theAudioPlayer = [[AVPlayer alloc] initWithURL:self.url];
    }
    
  8. 最后,当您创建 GPUImageMovie 对象时,不要忘记将 playSound 标志设置为 YES.

    像这样:movieFile.playSound = YES;

    希望对您有所帮助。

如何在 GPUImage 应用过滤器期间暂停音频?

就像我们可以在暂停电影写作时通过movieWriter.paused = YES;暂停视频写作一样,我也需要暂停音频。