当前位置:首页 > 通信资讯 > 正文

好久没有写东西了,最近加班太严重,今天抽空把用到的音乐播放器douaudiostreamer整理一下,由于项目之前用的是avplayer,这个也可以,但是就是要先缓存一段时间再播放,老板看了之后要求,要变缓存变播放(有网时,点击播放按钮就立刻播放),怎么不早说!怎么不早说!怎么不早说!还能怎样?只能原谅他,继续敲代码。。。。。。(还是直接上代码吧)

一、导入三方库

?
1 pod 'douaudiostreamer'

或者githup下载地址:https://github.com/douban/douaudiostreamer

二、使用

1.从demo中获取nakplaybackindicatorview文件和musicindicator.h和musicindicator.m 文件,并导入头文件

?
1 //音乐播放<br>#import "douaudiostreamer.h"<br>#import "nakplaybackindicatorview.h"<br>#import "musicindicator.h"<br>#import "track.h"

如图:

ios开发音乐播放器(ios下载音乐怎么用播放器播放)

2.创建一个track类,用于音乐播放的url存放

ios开发音乐播放器(ios下载音乐怎么用播放器播放)

3.需要的界面.h中,添加douaudiostreamer,并用单利来初始化

?
1 2 + (instancetype)sharedinstance ; @property (nonatomic, strong) douaudiostreamer *streamer;

如图:

ios开发音乐播放器(ios下载音乐怎么用播放器播放)

在.m中实现:

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 static void *kstatuskvokey = &kstatuskvokey; static void *kdurationkvokey = &kdurationkvokey; static void *kbufferingratiokvokey = &kbufferingratiokvokey; @property (strong, nonatomic) musicindicator *musicindicator; @property (nonatomic, strong) track *audiotrack; + (instancetype)sharedinstance { static hynentertainmentcontroller *_sharedmusicvc = nil; static dispatch_once_t oncetoken; dispatch_once(&oncetoken, ^{ _sharedmusicvc = [[hynentertainmentcontroller alloc] init]; _sharedmusicvc.streamer = [[douaudiostreamer alloc] init]; }); return _sharedmusicvc; }

播放按钮事件

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #pragma mark ---音乐播放按钮 -(void)playmusicstart:(uibutton *)sender { //通过按钮获取cell musiccollectionviewcell *musiccell = (musiccollectionviewcell *)[[sender superview] superview]; if(_playfirst == 0){//_playfirst == 0首次播放,其他为暂停 nsurl *url = [nsurl urlwithstring:httpimgurl(musiccell.model.musicurl)]; _audiotrack.audiofileurl = url; @try { [self removestreamerobserver]; } @catch(id anexception){ } //在douaudiostreamer进行播放时,必须先置为nil _streamer = nil; _streamer = [douaudiostreamer streamerwithaudiofile:_audiotrack]; [self addstreamerobserver]; [_streamer play]; } if([_streamer status] == douaudiostreamerpaused || [_streamer status] == douaudiostreameridle){ [sender setbackgroundimage:[uiimage imagenamed:@"music_play_icon"] forstate:uicontrolstatenormal]; [_streamer play]; }else{ [sender setbackgroundimage:[uiimage imagenamed:@"music_stop_icon"] forstate:uicontrolstatenormal]; [_streamer pause]; } _playfirst++; }

对添加监听

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 - (void)addstreamerobserver { [_streamer addobserver:self forkeypath:@"status" options:nskeyvalueobservingoptionnew context:kstatuskvokey]; [_streamer addobserver:self forkeypath:@"duration" options:nskeyvalueobservingoptionnew context:kdurationkvokey]; [_streamer addobserver:self forkeypath:@"bufferingratio" options:nskeyvalueobservingoptionnew context:kbufferingratiokvokey]; } /// 播放器销毁 - (void)dealloc{ if (_streamer !=nil) { [_streamer pause]; [_streamer removeobserver:self forkeypath:@"status" context:kstatuskvokey]; [_streamer removeobserver:self forkeypath:@"duration" context:kdurationkvokey]; [_streamer removeobserver:self forkeypath:@"bufferingratio" context:kbufferingratiokvokey]; _streamer =nil; } } - (void)removestreamerobserver { [_streamer removeobserver:self forkeypath:@"status"]; [_streamer removeobserver:self forkeypath:@"duration"]; [_streamer removeobserver:self forkeypath:@"bufferingratio"]; } - (void)observevalueforkeypath:(nsstring *)keypath ofobject:(id)object change:(nsdictionary *)change context:(void *)context { if (context == kstatuskvokey) { [self performselector:@selector(updatestatus) onthread:[nsthread mainthread] withobject:nil waituntildone:no]; } else if (context == kdurationkvokey) { [self performselector:@selector(updateslidervalue:) onthread:[nsthread mainthread] withobject:nil waituntildone:no]; } else if (context == kbufferingratiokvokey) { [self performselector:@selector(updatebufferingstatus) onthread:[nsthread mainthread] withobject:nil waituntildone:no]; } else { [super observevalueforkeypath:keypath ofobject:object change:change context:context]; } } - (void)updateslidervalue:(id)timer { } -(void)updatebufferingstatus { } - (void)updatestatus { //self.musicisplaying = no; _musicindicator.state = nakplaybackindicatorviewstatestopped; switch ([_streamer status]) { case douaudiostreamerplaying: // self.musicisplaying = yes; _musicindicator.state = nakplaybackindicatorviewstateplaying; break; case douaudiostreamerpaused: break; case douaudiostreameridle: break; case douaudiostreamerfinished: break; case douaudiostreamerbuffering: _musicindicator.state = nakplaybackindicatorviewstateplaying; break; case douaudiostreamererror: break; } }

这样就能播放了。

锁屏时的音乐显示、拔出耳机后暂停播放、监听音频打断事件

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 -(void)viewwillappear:(bool)animated { [super viewwillappear:animated]; //接受远程控制 [self becomefirstresponder]; [[uiapplication sharedapplication] beginreceivingremotecontrolevents]; } //这个不能忘记了 -(bool)canbecomefirstresponder{ return yes; } - (void)viewdidload { [super viewdidload]; //音乐播放器 [self initplayer]; } #pragma mark =========================音乐播放============================== //音乐播放器 -(void)initplayer { _audiotrack = [[track alloc] init]; avaudiosession *session = [avaudiosession sharedinstance]; [session setactive:yes error:nil]; [session setcategory:avaudiosessioncategoryplayback error:nil]; //让app支持接受远程控制事件 [[uiapplication sharedapplication] beginreceivingremotecontrolevents]; //添加通知,拔出耳机后暂停播放 [[nsnotificationcenter defaultcenter] addobserver:self selector:@selector(routechange:) name:avaudiosessionroutechangenotification object:nil]; // 监听音频打断事件 [[nsnotificationcenter defaultcenter] addobserver:self selector:@selector(audiosessionwasinterrupted:) name:avaudiosessioninterruptionnotification object:session]; } // 监听音频打断事件 - (void)audiosessionwasinterrupted:(nsnotification *)notification { //被打断时 if (avaudiosessioninterruptiontypebegan == [notification.userinfo[avaudiosessioninterruptiontypekey] intvalue]) { [_streamer pause]; uibutton *btn = (uibutton *)[self.view viewwithtag:2000]; [btn setbackgroundimage:[uiimage imagenamed:@"music_stop_icon"] forstate:uicontrolstatenormal]; } else if (avaudiosessioninterruptiontypeended == [notification.userinfo[avaudiosessioninterruptiontypekey] intvalue]) { } } // 拔出耳机后暂停播放 -(void)routechange:(nsnotification *)notification{ nsdictionary *dic=notification.userinfo; int changereason= [dic[avaudiosessionroutechangereasonkey] intvalue]; //等于avaudiosessionroutechangereasonolddeviceunavailable表示旧输出不可用 if (changereason==avaudiosessionroutechangereasonolddeviceunavailable) { avaudiosessionroutedescription *routedescription=dic[avaudiosessionroutechangepreviousroutekey]; avaudiosessionportdescription *portdescription= [routedescription.outputs firstobject]; //原设备为耳机则暂停 if ([portdescription.porttype isequaltostring:@"headphones"]) { [_streamer pause]; uibutton *btn = (uibutton *)[self.view viewwithtag:2000]; [btn setbackgroundimage:[uiimage imagenamed:@"music_stop_icon"] forstate:uicontrolstatenormal]; } } } //锁屏时音乐显示(这个方法可以在点击播放时,调用传值) - (void)setuplockscreeninfowithsing:(nsstring *)sign withsigner:(nsstring *)signer withimage:(uiimage *)image { // 1.获取锁屏中心 mpnowplayinginfocenter *playinginfocenter = [mpnowplayinginfocenter defaultcenter]; //初始化一个存放音乐信息的字典 nsmutabledictionary *playinginfodict = [nsmutabledictionary dictionary]; // 2、设置歌曲名 if (sign) { [playinginfodict setobject:sign forkey:mpmediaitempropertyalbumtitle]; } // 设置歌手名 if (signer) { [playinginfodict setobject:signer forkey:mpmediaitempropertyartist]; } // 3设置封面的图片 //uiimage *image = [self getmusicimagewithmusicid:self.currentmodel]; if (image) { mpmediaitemartwork *artwork = [[mpmediaitemartwork alloc] initwithimage:image]; [playinginfodict setobject:artwork forkey:mpmediaitempropertyartwork]; } // 4设置歌曲的总时长 //[playinginfodict setobject:self.currentmodel.detailduration forkey:mpmediaitempropertyplaybackduration]; //音乐信息赋值给获取锁屏中心的nowplayinginfo属性 playinginfocenter.nowplayinginfo = playinginfodict; // 5.开启远程交互 [[uiapplication sharedapplication] beginreceivingremotecontrolevents]; } //锁屏时操作 - (void)remotecontrolreceivedwithevent:(uievent *)receivedevent { if (receivedevent.type == uieventtyperemotecontrol) { uibutton *sender = (uibutton *)[self.view viewwithtag:2000]; switch (receivedevent.subtype) {//判断是否为远程控制 case uieventsubtyperemotecontrolpause: [[hynentertainmentcontroller sharedinstance].streamer pause]; [sender setbackgroundimage:[uiimage imagenamed:@"music_stop_icon"] forstate:uicontrolstatenormal]; break; case uieventsubtyperemotecontrolstop: break; case uieventsubtyperemotecontrolplay: [[hynentertainmentcontroller sharedinstance].streamer play]; [sender setbackgroundimage:[uiimage imagenamed:@"music_play_icon"] forstate:uicontrolstatenormal]; break; case uieventsubtyperemotecontroltoggleplaypause: break; case uieventsubtyperemotecontrolnexttrack: break; case uieventsubtyperemotecontrolprevioustrack: break; default: break; } } }

整体图片:

ios开发音乐播放器(ios下载音乐怎么用播放器播放)

上图为未播放

ios开发音乐播放器(ios下载音乐怎么用播放器播放)

上图为播放中

ios开发音乐播放器(ios下载音乐怎么用播放器播放)

上图为锁屏时状态

应该没有什么要添加的了,暂时告一段落,有不足之处,可以在下方的留言区讨论,感谢对服务器之家的支持。

原文链接:https://my.oschina.net/huangyn/blog/1593368

如果您对该产品感兴趣,请填写办理(客服微信:xiaoxiongyidong)

为您推荐:

发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。