我正在实现一个带有 AVPlayer
的播放器,它将播放来自网址的视频 . 此URL可用于"fixed-length"视频(具有预定持续时间)和实时视频(其持续时间未知/未定义) .
我使用的固定长度URL链接到.mp4文件(使用H264编解码器),而实时视频有.m3u8扩展名(但也有H264) .
我可以播放一些.m3u8网址,但是当我尝试播放.mp4时,它赢得了't load. However, if I start the app and play a .mp4 URL first, I can play other .mp4 URLs, but I can' t切换到.m3u8 .
这两种格式都很好,但是当我从一种格式切换到另一种格式时会出现问题 .
这些是我用来实例化和“清理”播放器的方法:
- (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;
}
我把问题缩小到这些单身人士 . 如果我删除单例模式,不会出现问题,我可以播放这两种视频 .
当我“清理”玩家时,还有什么我应该做的吗?
2 回答
似乎AVPlayer类不适用于具有不同视频合成的项目 .
来自[AVPlayer replaceCurrentItemWithPlayerItem:] method上的文档:
我最近也遇到了同样的问题 . 我通过维护AVQueuePlayer的2个实例来解决它 - 一个用于播放Mp4而另一个用于M3u8 . 并通过隐藏一个玩家视图并根据视频格式(Mp4 / M3u8)显示另一个玩家视图在这些玩家之间切换 .