iOS--音乐播放器之DOUAudioStreamer


声明:本文转载自https://my.oschina.net/huangyn/blog/1593368,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

好久没有写东西了,最近加班太严重,今天抽空把用到的音乐播放器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;         }     } }   

 

 

整体图片:

上图为未播放

上图为播放中

 

 

上图为锁屏时状态

 

 

应该没有什么要添加的了,暂时告一段落,有不足之处,可以留言,谢谢!

 

 

 

 

 

 

 

 

本文发表于2017年12月22日 00:33
(c)注:本文转载自https://my.oschina.net/huangyn/blog/1593368,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 1978 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1