我正在使用AVPlayer播放youtube视频,如下所示,
- (void)startYoutubeVideoAtUrl:(NSURL *)videoUrl
{
NSLog(@"start player at url : %@", videoUrl);
[HCYoutubeParser h264videosWithYoutubeURL:videoUrl completeBlock:^(NSDictionary *videoDictionary, NSError *error) {
if (videoDictionary && videoDictionary.count > 0) {
NSString *URLString = [self chooseYoutubeUrlFromUrlList:videoDictionary];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:[self videoURLWithCustomScheme:@"streaming" uRLString:URLString] options:nil];
[asset.resourceLoader setDelegate:self queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
pendingRequests = [NSMutableArray array];
avPlayerItem = [AVPlayerItem playerItemWithAsset:asset];
[self startVideoPlayBack];
}
else {
[_delegate failedStartPalyInlineVideo];
}
}];
}
-(void)startVideoPlayBack
{
startTime = CFAbsoluteTimeGetCurrent();
avPlayer = [[AVQueuePlayer alloc] initWithPlayerItem:avPlayerItem];
avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:avPlayer];
[avPlayerItem addObserver:self forKeyPath:@"status" options:0 context:nil];
[avPlayerLayer addObserver:self forKeyPath:@"readyForDisplay" options:NSKeyValueObservingOptionNew context:nil];
avPlayerLayer.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
[self.view.layer addSublayer:avPlayerLayer];
[self watchApiCall];
avPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[avPlayer currentItem]];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(playerItemPlaybackStalled:)
name:AVPlayerItemPlaybackStalledNotification
object:[avPlayer currentItem]];
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
@try {
if (!avPlayer) {
return;
}
if (avPlayerItem.status == AVPlayerStatusReadyToPlay) {
}
else if (avPlayerItem.status == AVPlayerStatusFailed) {
NSLog(@"----- AVPlayerStatusFailed ----");
[self playbackVideo];
}
if (object == avPlayerLayer && [keyPath isEqualToString:@"readyForDisplay"]) {
[self resetNetworkSpeedUsingLoadingTime];
if (avPlayerLayer.readyForDisplay) {
id<LoopingVideoDelegate> strongDelegate = self.delegate;
if([strongDelegate readyForVideoDisplay]) {
[avPlayer play];
}
else {
[self removePlayer];
}
}
}
}
@catch(NSException *ex) {
NSLog(@"EXCEPTION : %@", ex);
}
}
我的问题有时会导致视频停滞并触发AVPlayerItemPlaybackStalledNotification
。此外,有时在调用[avPlayerItem seekToTime:kCMTimeZero];
选择器之后,它没有响应AVPlayerItemDidPlayToEndTimeNotification
。我无法找到解决方案。我查了一下,
[HCYoutubeParser thumbnailForYoutubeURL:videoUrl thumbnailSize:YouTubeThumbnailDefaultHighQuality completeBlock:^(UIImage *image, NSError *error) {
if (!error) {
[HCYoutubeParser h264videosWithYoutubeURL:videoUrl completeBlock:^(NSDictionary *videoDictionary, NSError *error) {
NSString *URLString = [self chooseYoutubeUrlFromUrlList:videoDictionary];
NSURL *urlToLoad = [NSURL URLWithString:URLString];
avPlayerItem = [[AVPlayerItem alloc] initWithURL:urlToLoad];
[self startVideoPlayBack];
}];
}
else {
NSLog(@"error in youtube parser");
}
}];
并且没有任何玩家失误问题或seekToTime:
没有回应问题。请帮忙。
答案 0 :(得分:0)
观察您的AVPlayerItem's
loadedTimeRanges
和seekableTimeRanges
媒体资源,确保AVPlayer
已加载可播放数据。在进行漫游时,AVPlayer
经常会暂停不可播放(可以由AVPlayer
)数据播放的数据。这应有助于进一步调查此问题。您也可以通过致电avPlayerItem.status == AVPlayerStatusReadyToPlay
play
,在AVPlayer
时尝试开始播放
来自AV Foundation编程指南
监控播放
您可以监控播放器的演示状态和正在播放的播放器项目的多个方面。这对于不受您直接控制的状态更改特别有用。例如:
如果用户使用多任务切换到其他应用程序,则玩家的费率属性将降至0.0。
如果您正在播放远程媒体,则播放器项的loadedTimeRanges和seekableTimeRanges属性将随着更多数据的变化而变化。
这些属性告诉您玩家项目时间轴的哪些部分可用。
当为HTTP直播流创建一个播放器项目时,玩家的currentItem属性会发生变化。
播放HTTP直播时,播放器项的曲目属性可能会发生变化。 如果流为内容提供不同的编码,则可能发生这种情况;如果播放器切换到不同的编码,则曲目会改变。
如果由于某种原因播放失败,播放器或播放器项的状态属性可能会更改。 您可以使用键值观察来监视对这些属性值的更改。