首先我们定义变量:
NSTimeInterval totalDration;
@property (strong, nonatomic) AVPlayer *player;
@property (retain, nonatomic) AVPlayerItem *playerItem;
@property (retain, nonatomic) id playbackTimeObserver;
而AVPlayer的使用离不开AVPlayerLayer,因此我们需要设置如下:
+ (Class)layerClass {
return [AVPlayerLayer class];
}
- (AVPlayer *)player {
return [(AVPlayerLayer *)[self layer] player];
}
- (void)setPlayer:(AVPlayer *)player {
[(AVPlayerLayer *)[self layer] setPlayer:player];
}
视频播放的初始化
self.playerItem = [[[AVPlayerItem alloc]initWithURL:_videoURL] autorelease];
[self.playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
[self.playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
self.player = [[[AVPlayer alloc]initWithPlayerItem:self.playerItem] autorelease];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(videoPlayDidEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.playerItem];
[(AVPlayerLayer*)[self layer] setVideoGravity:AVLayerVideoGravityResizeAspect];
添加的observer可以监控缓存进度及播放进度
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
AVPlayerItem *playerItem = (AVPlayerItem *)object;
if ([keyPath isEqualToString:@"status"]) {
if ([playerItem status] == AVPlayerStatusReadyToPlay) {
// ready to play
NSLog(@"AVPlayerStatusReadyToPlay");
CMTime duration = self.playerItem.duration;// 获取视频总长度
totalDration = playerItem.duration.value / playerItem.duration.timescale;// 转换成秒
// 可以更新视频总长度
if (_didEnterFullScreenMode && !_is_s_video) {
[self monitoringPlayback:self.playerItem];// 监听播放状态
}
}
else if ([playerItem status] == AVPlayerStatusFailed) {
NSLog(@"AVPlayerStatusFailed");
// 播放失败的处理
}
}
else if ([keyPath isEqualToString:@"loadedTimeRanges"]) {
NSTimeInterval timeInterval = [self availableDuration];// 计算缓冲进度
CMTime duration = self.playerItem.duration;
CGFloat totalDuration = CMTimeGetSeconds(duration);
// 更新缓存进度
}
}
- (void)monitoringPlayback:(AVPlayerItem *)playerItem {
self.playbackTimeObserver = [self.player addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:NULL usingBlock:^(CMTime time) {
CGFloat currentSecond = playerItem.currentTime.value/playerItem.currentTime.timescale;// 计算当前在第几秒
// 更新播放进度
}];
}
需要注意的是playerItem销毁前一定先移除observer
[self.playerItem removeObserver:self forKeyPath:@"status"];
[self.playerItem removeObserver:self forKeyPath:@"loadedTimeRanges"];
通过slide或者其他方式改变播放进度:
CGFloat value = progressView.progressValue;
CGFloat curTime = value * totalDration;
CMTime time = CMTimeMake(curTime, 1);
[self.player pause];
[self.player seekToTime:time completionHandler:^(BOOL f){
[self.player play];
}];
在完成了视频播放,经过尝试需要设置如下才可以继续播放:
// 初始化值
[self.playerItem setReversePlaybackEndTime:kCMTimeZero];
[self.playerItem seekToTime:kCMTimeZero];
关于视频播放音量的设置,如下:
- (void) setVolome:(CGFloat) volome {
if (self.playerItem == nil) {
return;
}
if (volome > 1) {
volome = 1;
}
if (volome < 0) {
volome = 0;
}
NSArray *audioTracks = [_playerItem.asset tracksWithMediaType:AVMediaTypeAudio];
NSMutableArray *allAudioParams = [NSMutableArray array];
for (AVAssetTrack *track in audioTracks) {
AVMutableAudioMixInputParameters *audioInputParams =
[AVMutableAudioMixInputParameters audioMixInputParameters];
[audioInputParams setVolume:volome atTime:kCMTimeZero];
[audioInputParams setTrackID:[track trackID]];
[allAudioParams addObject:audioInputParams];
}
AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix];
[audioMix setInputParameters:allAudioParams];
[_playerItem setAudioMix:audioMix];
}