我正在实施一个AVPlayer
播放器,该播放器将播放来自网址的视频。这个URL可以用于"固定长度"视频(具有预定的持续时间)和实时视频(其持续时间未知/未定义)。
我使用的固定长度网址链接到.mp4文件(使用H264编解码器),而实时视频的扩展名为.m3u8(还有H264)。
我可以播放多个.m3u8网址,但是当我尝试播放.mp4时,它无法加载。
但是,如果我首先启动应用并播放.mp4网址,我可以播放其他.mp4网址,但我无法切换到.m3u8。
两种格式都可以正常播放,但是当我从一种格式切换到另一种格式时会出现问题。
这些是我用来实例化的方法," clean"玩家:
- (void)prepareAndPlayAutomatically:(BOOL)playAutomatically {
currentItem = [AVPlayerItem playerItemWithURL:videoURL];
[[self player] replaceCurrentItemWithPlayerItem:currentItem];
[self.layer addSublayer:[self playerLayer]];
[[self player] addObserver:self forKeyPath:@"rate" options:0 context:nil];
[[self player] seekToTime:kCMTimeZero];
if (playAutomatically) {
[[self player] play];
}
}
- (void)clean {
[[self player] pause];
[[self player] seekToTime:kCMTimeZero];
[[self player] replaceCurrentItemWithPlayerItem:nil];
[[self player] removeObserver:self forKeyPath:@"rate"];
[self removeFromSuperview];
}
[self player]
将返回单例AVPlayer实例;
[self playerLayer]
还将返回单例AVPlayerLayer实例;
- (AVPlayer *)player {
static dispatch_once_t once;
static AVPlayer *player;
dispatch_once(&once, ^{
player = [AVPlayer playerWithPlayerItem:currentItem];
});
return player;
}
- (AVPlayerLayer *)playerLayer {
static dispatch_once_t once;
static AVPlayerLayer *playerLayer;
dispatch_once(&once, ^{
playerLayer = [AVPlayerLayer playerLayerWithPlayer:[self player]];
});
return playerLayer;
}
我已经把问题缩小到了这些单身人士。如果我删除单例模式,则不会出现任何问题,我可以播放这两种视频。
当我"清洁"还有什么我应该做的。玩家?
答案 0 :(得分:2)
似乎AVPlayer类不适用于具有不同视频合成的项目。
来自[AVPlayer replaceCurrentItemWithPlayerItem:] method上的文档:
特别注意事项
新项目必须与其替换的项目具有相同的合成器,或者 没有合成者。
答案 1 :(得分:0)
我最近也遇到了同样的问题。我通过维护AVQueuePlayer的2个实例来解决它 - 一个用于播放Mp4而另一个用于M3u8。 并通过隐藏一个玩家视图并根据视频格式显示另一个玩家视图(Mp4 / M3u8)来切换这些玩家。