1,最近写了一个关于音乐播放器的demo,查阅资料的过程中,学会不少新东西。简单记录一下写的过程中遇到问题,备忘。
2,为了方便使用,将播放器写成单例 .h
先导入需要的库
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>
#import <objc/runtime.h>
生成一个播放器的实例
@property (nonatomic,strong) AVPlayer *AVplay;
@property (nonatomic,strong) AVPlayerItem *AVItem;
3, 在.m文件中实现方法
AVplay = [[AVPlayer alloc] init];
添加播放完成的通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:AVplay.currentItem];
-(void)playbackFinished:(NSNotification *)notification{
/*
播放完成后的操作在这里进行,比如播放下一曲
*/
}
4,初始化播放的链接
AVItem = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:url]];
[AVplay replaceCurrentItemWithPlayerItem:AVItem];
5,点击播放按钮,控制播放和暂停
_isPlaying = !_isPlaying;
if (_isPlaying) {
[self resume]; // 开始/继续 播放
}else{
[self pause]; // 暂停
}
- (void)resume{
[AVplay play];
}
- (void)pause{
[AVplay pause];
}
6,上一曲、下一曲 调用4的方法,AVItem重新赋值
7,获得当前播放的进度,赋值给进度条
-(float)progress{
float percentage = (CMTimeGetSeconds(AVplay.currentItem.currentTime)/CMTimeGetSeconds(AVplay.currentItem.duration));
return percentage;
}
8,获得进度条移动后的值,调整播放的进度
-(void)moveToSection:(CGFloat)section{
int32_t timeScale = AVplay.currentItem.asset.duration.timescale;
Float64 playerSection = CMTimeGetSeconds(AVplay.currentItem.duration) * section;
[AVplay seekToTime:CMTimeMakeWithSeconds(playerSection, timeScale) toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
}
9,为了实现后台播放
// 后台播放 设置 音频会话类型
//需要 导入头文件 #import <AVFoundation/AVFoundation.h>
AVAudioSession *session = [AVAudioSession sharedInstance];
NSError *setCategoryError = nil;
BOOL success = [session setCategory:AVAudioSessionCategoryPlayback error:&setCategoryError];
if (!success)
{
return;
}
NSError *activationError = nil;
success = [session setActive:YES error:&activationError];
if (!success)
{
return;
}
同时还要再info.plist文件中找到 Required background modes 这一行,添加key值 选择App plays audio or streams audio/video using AirPlay
10,为了实现锁屏时显示播放信息
- (void)applicationDidEnterBackground:(UIApplication *)application {
// 让应用在后台运行
[application beginBackgroundTaskWithExpirationHandler:nil];
// 为了显示锁屏状态下的内容
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder]; // 相应事件
//刚进入后台时刷新一下锁屏内容
[[PlayManager sharedInstance] configPlayingInfo];
}
//判断时间类型
- (void)remoteControlReceivedWithEvent:(UIEvent *)event
{
if (event.type == UIEventTypeRemoteControl) {
switch (event.subtype) {
case UIEventSubtypeRemoteControlPlay:
[[PlayManager sharedInstance] resume]; // 播放
break;
case UIEventSubtypeRemoteControlPause:
[[PlayManager sharedInstance] pause];//暂停
break;
case UIEventSubtypeRemoteControlPreviousTrack:
[[PlayManager sharedInstance] last]; // 播放上一曲按钮
break;
case UIEventSubtypeRemoteControlNextTrack:
[[PlayManager sharedInstance] next]; // 播放下一曲按钮
break;
default:
break;
}
}
}
//进入前台后取消相应
- (void)applicationWillEnterForeground:(UIApplication *)application {
[[UIApplication sharedApplication] endReceivingRemoteControlEvents];
[self resignFirstResponder];
}
11,锁屏显示的内容的方法
- (void)configPlayingInfo{
if (_currentModel!=nil) {
if (NSClassFromString(@"MPNowPlayingInfoCenter")) {
NSMutableDictionary *dict = [[NSMutableDictionary alloc]init];
[dict setObject:_currentModel.title forKey:MPMediaItemPropertyTitle];//歌曲名设置
[dict setObject:_currentModel.source_name forKey:MPMediaItemPropertyArtist];//歌手名设置
[dict setObject:[[MPMediaItemArtwork alloc] initWithImage:[UIImage imageNamed:@"car"]] forKey:MPMediaItemPropertyArtwork];//专辑图片设置
[dict setObject:[NSNumber numberWithDouble:CMTimeGetSeconds(AVplay.currentItem.currentTime)] forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime]; //音乐当前已经播放时间
[dict setObject:[NSNumber numberWithFloat:1.0] forKey:MPNowPlayingInfoPropertyPlaybackRate];//进度光标的速度 (这个随 自己的播放速率调整,我默认是原速播放)
[dict setObject:[NSNumber numberWithDouble:CMTimeGetSeconds(AVplay.currentItem.duration)] forKey:MPMediaItemPropertyPlaybackDuration];//歌曲总时间设置
[[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:dict];
}
[atWorkImg sd_setImageWithURL:[NSURL URLWithString:_currentModel.cover_url] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
//锁屏状态下显示的图片是网络的,下载完再切换,否则会出现问题
NSDictionary *dic = [[MPNowPlayingInfoCenter defaultCenter] nowPlayingInfo];
NSMutableDictionary *muDic = [[NSMutableDictionary alloc] initWithDictionary:dic];
[muDic setObject:[[MPMediaItemArtwork alloc] initWithImage:atWorkImg.image] forKey:MPMediaItemPropertyArtwork];
[[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:muDic];
}];
}
}
// 暂时没有对打断事件的处理