AVPlayer音频播放器基本实现
#import <AVFoundation/AVFoundation.h>
@property (nonatomic, strong) AVPlayer *player;
- 播放
- (void)playWithURL:(NSURL *)url {
// 1. 资源的请求
AVURLAsset *asset = [AVURLAsset assetWithURL:url];
// 2. 资源的组织
AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset];
// 当资源的组织者, 告诉我们资源准备好了之后, 我们再播放
// AVPlayerItemStatus status
[item addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
// 3. 资源的播放
self.player = [AVPlayer playerWithPlayerItem:item];
}
- 暂停
- (void)pause {
[self.player pause];
}
- 继续
- (void)resume {
[self.player play];
}
- 停止
- (void)stop {
[self.player pause];
self.player = nil;
}
- 进度条拉动
- (void)seekWithProgress:(float)progress {
if (progress < 0 || progress > 1) {
return;
}
// 可以指定时间节点去播放
// 时间: CMTime : 影片时间
// 影片时间 -> 秒
// 秒 -> 影片时间
// 1. 当前音频资源的总时长
CMTime totalTime = self.player.currentItem.duration;
// 2. 当前音频, 已经播放的时长
// self.player.currentItem.currentTime
NSTimeInterval totalSec = CMTimeGetSeconds(totalTime);
NSTimeInterval playTimeSec = totalSec * progress;
CMTime currentTime = CMTimeMake(playTimeSec, 1);
[self.player seekToTime:currentTime completionHandler:^(BOOL finished) {
if (finished) {
NSLog(@"确定加载这个时间点的音频资源");
}else {
NSLog(@"取消加载这个时间点的音频资源");
}
}];
}
- 快进一段时间
- (void)seekWithTimeDiffer:(NSTimeInterval)timeDiffer {
// 1. 当前音频资源的总时长
CMTime totalTime = self.player.currentItem.duration;
NSTimeInterval totalTimeSec = CMTimeGetSeconds(totalTime);
// 2. 当前音频, 已经播放的时长
CMTime playTime = self.player.currentItem.currentTime;
NSTimeInterval playTimeSec = CMTimeGetSeconds(playTime);
playTimeSec += timeDiffer;
[self seekWithProgress:playTimeSec / totalTimeSec];
}
- 倍数播放
- (void)setRate:(float)rate {
[self.player setRate:rate];
}
- 静音
- (void)setMuted:(BOOL)muted {
self.player.muted = muted;
}
- 调节音量
- (void)setVolume:(float)volume {
if (volume < 0 || volume > 1) {
return;
}
if (volume > 0) {
[self setMuted:NO];
}
self.player.volume = volume;
}
#pragma mark - KVO
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
if ([keyPath isEqualToString:@"status"]) {
AVPlayerItemStatus status = [change[NSKeyValueChangeNewKey] integerValue];
if (status == AVPlayerItemStatusReadyToPlay) {
NSLog(@"资源准备好了, 这时候播放就没有问题");
[self.player play];
}else {
NSLog(@"状态未知");
}
}
}