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

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

整体图片:

上图为未播放

上图为播放中

上图为锁屏时状态

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

(0)

相关推荐

  • iOS中的音频服务和音频AVAudioPlayer音频播放器使用指南

    AudioServicesPlaySystemSound音频服务 对于简单的.无混音音频,AVAudio ToolBox框架提供了一个简单的C语言风格的音频服务.你可以使用AudioservicesPlaySystemSound函数来播放简单的声音.要遵守以下几个规则: 1.音频长度小于30秒 2.格式只能是PCM或者IMA4 3.文件必须被存储为.caf..aif.或者.wav格式 4.简单音频不能从内存播放,而只能是磁盘文件 除了对简单音频的限制外,你对于音频播放的方式也基本无法控制.一旦音

  • iOS中视频播放器的简单封装详解

    前言 如果仅仅是播放视频两者的使用都非常简单,但是相比MediaPlayer,AVPlayer对于视频播放的可控制性更强一些,可以通过自定义的一些控件来实现视频的播放暂停等等.因此这里使用AVPlayer的视频播放. 视频播放器布局 首先使用xib创建CLAVPlayerView继承UIView用来承载播放器,这样我们在外部使用的时候,直接在控制器View或者Cell上添加CLAVPlayerView即可,至于播放器播放或者暂停等操作交给CLAVPlayerView来管理.下面来看一下CLAVP

  • iOS音乐播放器实现代码完整版

    本文实例为大家分享了iOS实现音乐播放器的具体代码,供大家参考,具体内容如下 audio_queue.cpp /* * This file is part of the FreeStreamer project, * (C)Copyright 2011-2013 Matias Muhonen. * See the file ''LICENSE'' for using the code. * * Part of the code in this file has been rewritten fr

  • 实例解析iOS中音乐播放器应用开发的基本要点

    一.调整项目的结构,导入必要的素材 调整后的项目结构如下: 二.新建两个控制器 (1)新建一个控制器,用于展示音乐文件列表界面,其继承自UITableViewController (2)新建一个控制器,用于展示播放界面,其继承自UIViewController (3)在storyboard中,把之前的控制器删除,换上一个导航控制器,设置tableViewController与之前新建的控制器类进行关联 三.音乐文件列表控制器中基本界面的搭建 (1)新建一个音乐文件的模型 根据plist文件建立模

  • 运用iOS教你轻松制作音乐播放器

    本文实例为大家分享了iOS音乐播放器制作的具体代码,供大家参考,具体内容如下 效果图 目录结构 代码 // // ViewController.m // 播放音乐 // // Created by xubh on 2017/3/24. // Copyright © 2017年 xubh. All rights reserved. // #import "ViewController.h" #import <AVFoundation/AVFoundation.h> @inte

  • ios 流媒体播放器实现流程及FreeStreamer的使用的示例

    简介 最近实现了一个流媒体播放器,使用的是FreeStreamer库,至于为什么不用avaudioplayer或者avplayer,前一个是不能播放网络音乐,后一个则是体验不好,缓存不够会暂停,然后又要手动播放.去github上搜了下,发现FreeStreamer评分比较高,于是就用它来实现了一个流媒体播放器. 演示效果 附上项目地址 chenfengxiaoxixi 实现功能 实现了流媒体音乐播放,后台持续播放,歌曲切换,进度条显示以及快进后退等功能. 实现技术点及流程 1.单例 播放器所在c

  • iOS之基于FreeStreamer的简单音乐播放器示例

    前提准备 为了能够有明确的思路来做这个demo,我下载了QQ音乐和网易云音乐,然后分别对比,最终选择了QQ音乐来参照,先是获取了其中的所有资源文件(如果有不知道怎么提取资源文件的,可以参考iOS提取APP中的图片资源),在这之后就是研究使用技术,这里我选择了FreeStreamer,虽然系统也有,但是该框架可能更好用点. 实现部分 在这之前,先来看看大概效果图吧 再看完效果图之后,我们就来看看这其中涉及到的几个难点吧(在我看开~) 1.先让播放器跑起来 这里我使用的是pods来管理三方库,代码如

  • iOS开发中音频工具类的封装以及音乐播放器的细节控制

    一.控制器间数据传递 两个控制器之间数据的传递 第一种方法: 复制代码 代码如下: self.parentViewController.music=self.music[indexPath.row]; 不能满足 第二种做法:把整个数组传递给它 第三种做法:设置一个数据源,设置播放控制器的数据源是这个控制器.self.parentViewController.dataSource=self;好处:没有耦合性,任何实现了协议的可以作为数据源. 第四种做法:把整个项目会使用到的音频资源交给一个工具类去

  • ios开发:一个音乐播放器的设计与实现案例

    这个Demo,关于歌曲播放的主要功能都实现了的.下一曲.上一曲,暂停,根据歌曲的播放进度动态滚动歌词,将当前正在播放的歌词放大显示,拖动进度条,歌曲跟着变化,并且使用Time Profiler进行了优化,还使用XCTest对几个主要的类进行了单元测试. 已经经过真机调试,在真机上可以后台播放音乐,并且锁屏时,显示一些主要的歌曲信息. 根据歌曲的播放来显示对应歌词的.用UITableView来显示歌词,可以手动滚动界面查看后面或者前面的歌词. 并且,当拖动进度条,歌词也会随之变化,下一曲.上一曲依

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

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

  • Android版音乐播放器

    音乐播放器是一个非常常见的应用,这篇博客就是介绍如何制作一个简单的音乐播放器,这款音乐播放器具有以下的功能:播放歌曲.暂停播放歌曲..显示歌曲的总时长.显示歌曲的当前播放时长.调节滑块可以将歌曲调节到任何时间播放.退出音乐播放器. 实现效果如下 实现方式: 第一步:使用Android Studio创建一个Android工程,并且修改activity_main.xml文件 <?xml version="1.0" encoding="utf-8"?> <

  • java 实现音乐播放器的简单实例

    java 实现音乐播放器的简单实例 实现效果图: 代码如下 package cn.hncu.games; import java.applet.Applet; import java.applet.AudioClip; import java.awt.Color; import java.awt.Font; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.Mou

  • iOS实现音乐播放器图片旋转

    本文实例为大家分享了iOS实现音乐播放器图片旋转的具体代码,供大家参考,具体内容如下 通过给继承与 UIImageView 的类 CXGImageView 添加 CABasicAnimation 转动动画,实现播放器图片转动效果. 主要提供三个方法: startRotating, stopRotating,resumeRotate startRotating /// 开始动画 func startRotating() { let rotateAnimation = CABasicAnimatio

  • Android编程开发音乐播放器实例

    本文实例讲述了Android编程开发音乐播放器,分享给大家供大家参考,具体如下: 音乐播放器中综合了以下内容: SeekBar.ListView.广播接收者(以代码的形式注册Receiver).系统服务.MediaPlayer 实现的功能: 1.暂停/播放.下一首/上一首,点击某一首时播放 2.支持拖动进度条快进 3.列表排序 4.来电话时,停止播放,挂断后继续播放 5.可在后台播放 效果图: 界面: main.xml: <?xml version="1.0" encoding=

  • Android 音乐播放器的开发实例详解

    本文将引导大家做一个音乐播放器,在做这个Android开发实例的过程中,能够帮助大家进一步熟悉和掌握学过的ListView和其他一些组件.为了有更好的学习效果,其中很多功能我们手动实现,例如音乐播放的快进快退等. 先欣赏下本实例完成后运行的界面效果: 首先我们建立项目,我使用的SDK是Android2.2的,然后在XML中进行布局. 上方是一个ListView用来显示我们的音乐列表,中间是一个SeekBar可以拖动当前音乐的播放进度,之所以用SeekBar而不用ProgressBar是因为我们需

随机推荐