AVPlayerItemVideoOutput

AVPlayerItemVideoOutput

本文介绍了[iOS] AVPlayerItemVideoOutput.hasNewPixelBufferForItemTime无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的第一个问题,所以不要太严厉。

It's my first question here, so don't be severe.

我正在使用AVPlayer从网上播放视频。我使用附加到 AVPlayer 播放的 AVPlayerItem AVPlayerItemVideoOutput 输出当前帧。要检查新帧是否准备好,我调用 [AVPlayerItemVideoOutput hasNewPixelBufferForItemTime] ,然后使用OpenGL ES输出它。如果我读mp4,一切都很完美,但如果我尝试读取m3u8,它可以工作约1秒钟(~30帧),但在此期间之后 [AVPlayerItemVideoOutput hasNewPixelBufferForItemTime] 开始仅返回FALSE,所以当前帧未更新。

I'm playing video from the net using AVPlayer. I output the current frame using AVPlayerItemVideoOutput attached to the AVPlayerItem played by the AVPlayer. To check if new frame is ready I call [AVPlayerItemVideoOutput hasNewPixelBufferForItemTime], then output it using OpenGL ES. All works perfectly if I read mp4, but if I try to read m3u8, it works for about 1 second(~30 frames), but after this period [AVPlayerItemVideoOutput hasNewPixelBufferForItemTime] starts returning FALSE only, so the current frame isn't updated.

如果我在此问题首次出现之前使用 [AVPlayer seekToTime] 寻找当前帧,则一切正常。

In case I seek the current frame using [AVPlayer seekToTime] before this problem's first occur all goes normally.

测试m3u8视频我在这里使用生活:

Test m3u8 video I use lives here:

http://195.16.112.71/adaptive/3006a26a-9154-4b38-a327-4fa2a2381ae6.video/3006a26a-9154-4b38-a327-4fa2a2381ae6.m3u8

为了重现这个问题,我修改了Apple的样本AVPlayerDemo,就在这里:

To reproduce this problem I modified Apple's sample AVPlayerDemo, here is it: https://yadi.sk/d/T2aVGoKnWmf5Z

主要的变化在于我调用 [AVPlayerDemoPlaybackViewController update] ,其中提到了 [AVPlayerItemVideoOutput hasNewPixelBufferForItemTime] 。此函数具有静态变量的计数器存储成功的 [AVPlayerItemVideoOutput copyPixelBufferForItemTime] 呼叫量。

The main change is in that I call [AVPlayerDemoPlaybackViewController update] which calls mentioned [AVPlayerItemVideoOutput hasNewPixelBufferForItemTime]. This function has static variable counter which stores the amount of successful [AVPlayerItemVideoOutput copyPixelBufferForItemTime] calls.

视频链接在 [AVPlayerDemoPlaybackViewController setURL] 中设置,它在函数的开头硬编码。默认情况下,它的值指向m3u8视频,它会再现问题,在这种情况下,计数器的平均值约为30,在具有该索引的帧 [AVPlayerItemVideoOutput hasNewPixelBufferForItemTime] 之后。返回FALSE仅

Video Url is set in [AVPlayerDemoPlaybackViewController setURL], it's hardcoded in the beginning of the function. By default its value points to m3u8 video, which reproduces the problem, in this case the average value of counter is about 30, after the frame with that index [AVPlayerItemVideoOutput hasNewPixelBufferForItemTime] returns FALSE only.

在的情况下当其他视频地址被使用(见的开头的 [AVPlayerDemoPlaybackViewController setURL] - 存在另一种地址你可以取消注释),所有帧都被成功读取。

In the case when other video Url is used(see beginning of [AVPlayerDemoPlaybackViewController setURL] - there is an alternative Url you can uncomment), all the frames are successfully read.

任何帮助将不胜感激!

推荐答案

代码的打击并没有解决我的问题,我还是得到了 [AVPlayerItemVideoOutput hasNewPixelBufferForItemTime]

Code blow does not solve my problem, I still got nothing from [AVPlayerItemVideoOutput hasNewPixelBufferForItemTime]

if (failedCount > 100) {
    failedCount = 0;
    [_playerItem removeOutput:_output];
    [_playerItem addOutput:_output];
}

最后在测试我的代码一整天后。我找到了解决问题的方法。

Finally after testing my code for a whole day. I found a way to solve it.

#pragma mark - AVPlayerItemOutputPullDelegate
- (void)outputMediaDataWillChange:(AVPlayerItemOutput *)sender {
    if (![self.videoOutput hasNewPixelBufferForItemTime:CMTimeMake(1, 10)]) {
        [self configVideoOutput];
    }
    [self.displayLink setPaused:NO];
}



检查 [AVPlayerItemVideoOutput hasNewPixelBufferForItemTime] outputMediaDataWillChange:被调用时。 如果没有0.1秒的新像素缓冲区,则重新创建 AVPlayerItemVideoOutput

Check [AVPlayerItemVideoOutput hasNewPixelBufferForItemTime] when outputMediaDataWillChange: called. Recreate your AVPlayerItemVideoOutput if no new pixel buffer at 0.1s.

[self configVideoOutput]; 只需重新创建一个新的 AVPlayerItemVideoOutput 来替换当前的 videoOutput 属性。

Code in [self configVideoOutput]; just recreate a new AVPlayerItemVideoOutput to replace current videoOutput property.

为什么0.1s?

我经过多次测试和实验我发现第一个或者2帧可能总是没有像素缓冲区。因此,首先1 / 30s,2 / 30s(对于30fps的视频)可能没有帧和像素缓冲区。但如果在0.1秒之后没有视频像素缓冲,则视频输出可能会破坏或出现问题。所以我们需要重新创建它。

I tested and experimented many times I found that first 1 or 2 frame may always get no pixel buffer. So first 1/30s, 2/30s (for video at 30fps) may have no frame and pixel buffer. But if no video pixel buffer after 0.1s, the video output may broken or something problem with it. So we need recreate it.

这篇关于[iOS] AVPlayerItemVideoOutput.hasNewPixelBufferForItemTime无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-17 08:34