首页 > 系统 > iOS > 正文

实例讲解iOS音乐播放器DOUAudioStreamer用法

2020-07-26 02:34:31
字体:
来源:转载
供稿:网友

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

一、导入三方库

pod 'DOUAudioStreamer'

或者GitHup下载地址:https://github.com/douban/DOUAudioStreamer

二、使用

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

//音乐播放
#import "DOUAudioStreamer.h"
#import "NAKPlaybackIndicatorView.h"
#import "MusicIndicator.h"
#import "Track.h"

如图:

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

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

+ (instancetype)sharedInstance ;@property (nonatomic, strong) DOUAudioStreamer *streamer;

 

如图:

在.m中实现:

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;}

 

播放按钮事件

#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++; }

 

对添加监听

- (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; } }

这样就能播放了。

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

-(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;}}}

整体图片:

上图为未播放

上图为播放中

上图为锁屏时状态

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

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表