首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在AVPlayerItemVideoOutput中使用AVPlayerLooper?

如何在AVPlayerItemVideoOutput中使用AVPlayerLooper?
EN

Stack Overflow用户
提问于 2021-01-20 10:44:33
回答 1查看 265关注 0票数 2

AVPlayerLooper接受模板AVPlayerItemAVQueuePlayer作为设置参数,然后在内部操作队列的项,播放器不断更改其currentItem

这在AVPlayerLayer中工作得很好,它接受这个循环播放器作为参数并只是渲染它,但是我如何在AVPlayerItemVideoOutput中使用它,它被附加到AVPlayerItem,播放器内部有多个?如何在内部重现AVPlayerLayer所做的相同事情?

文档中的AVPlayerLooper设置示例

代码语言:javascript
复制
NSString *videoFile = [[NSBundle mainBundle] pathForResource:@"example" ofType:@"mov"];
NSURL *videoURL = [NSURL fileURLWithPath:videoFile];

_playerItem = [AVPlayerItem playerItemWithURL:videoURL];
_player = [AVQueuePlayer queuePlayerWithItems:@[_playerItem]];
_playerLooper = [AVPlayerLooper playerLooperWithPlayer:_player templateItem:_playerItem];
_playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
_playerLayer.frame = self.view.bounds;
[self.view.layer addSublayer:_playerLayer];
[_player play];

这就是AVPlayerItemVideoOutput的用法

代码语言:javascript
复制
[item addOutput:_videoOutput];

我想出的唯一解决办法是观察currentItem的变化,每次从旧项目中分离视频输出并将其附加到新项目,如下面的示例,但这显然中和了我试图实现的无缝回放。

代码语言:javascript
复制
- (void)observeValueForKeyPath:(NSString*)path
                      ofObject:(id)object
                        change:(NSDictionary*)change
                       context:(void*)context {
   if (context == currentItemContext) {
      AVPlayerItem* newItem = [change objectForKey:NSKeyValueChangeNewKey];
      AVPlayerItem* oldItem = [change objectForKey:NSKeyValueChangeOldKey];
      if(oldItem.status == AVPlayerItemStatusReadyToPlay) {
          [newItem removeOutput:_videoOutput];
      }
      if(newItem.status == AVPlayerItemStatusReadyToPlay) {
          [newItem addOutput:_videoOutput];
      }
      [self removeItemObservers:oldItem];
      [self addItemObservers:newItem];
   }
}

为了了解更多上下文,我正在尝试为flutter的video_player插件https://github.com/flutter/flutter/issues/72878提供一个修复方案

插件的代码可以在这里找到https://github.com/flutter/plugins/blob/172338d02b177353bf517e5826cf6a25b5f0d887/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m

EN

回答 1

Stack Overflow用户

发布于 2021-01-21 02:39:53

您可以通过将AVQueuePlayer子类化(yay OOP)并根据需要在其中创建和添加AVPlayerItemVideoOutput来实现这一点。我以前从未见过多个AVPlayerItemVideoOutput,但内存消耗似乎很合理,一切都正常。

代码语言:javascript
复制
@interface OutputtingQueuePlayer : AVQueuePlayer
@end

@implementation OutputtingQueuePlayer

- (void)insertItem:(AVPlayerItem *)item afterItem:(nullable AVPlayerItem *)afterItem;
{
    if (item.outputs.count == 0) {
        NSLog(@"Creating AVPlayerItemVideoOutput");
        AVPlayerItemVideoOutput *videoOutput = [[AVPlayerItemVideoOutput alloc] initWithOutputSettings:nil]; // or whatever
        [item addOutput:videoOutput];
    }
    [super insertItem:item afterItem:afterItem];
}
@end

当前输出的访问方式如下:

代码语言:javascript
复制
AVPlayerItemVideoOutput *videoOutput = _player.currentItem.outputs.firstObject;
CVPixelBufferRef pixelBuffer = [videoOutput copyPixelBufferForItemTime:_player.currentTime itemTimeForDisplay:nil];
// do something with pixelBuffer here
CVPixelBufferRelease(pixelBuffer);

配置就变成了:

代码语言:javascript
复制
_playerItem = [AVPlayerItem playerItemWithURL:videoURL];
_player = [OutputtingQueuePlayer queuePlayerWithItems:@[_playerItem]];
_playerLooper = [AVPlayerLooper playerLooperWithPlayer:_player templateItem:_playerItem];
_playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
[self.view.layer addSublayer:_playerLayer];
[_player play];
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65802373

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档