iOS开发拓展篇—封装音频文件播放工具类

一、简单说明

1.关于音乐播放的简单说明

(1)音乐播放用到一个叫做AVAudioPlayer的类

(2)AVAudioPlayer常用方法

  加载音乐文件

- (id)initWithContentsOfURL:(NSURL *)url error:(NSError **)outError;

- (id)initWithData:(NSData *)data error:(NSError **)outError;

  准备播放(缓冲,提高播放的流畅性) - (BOOL)prepareToPlay;

  播放(异步播放)- (BOOL)play;

  暂停 - (void)pause;

  停止- (void)stop;

  是否正在播放  @property(readonly, getter=isPlaying) BOOL playing;

  时长      @property(readonly) NSTimeInterval duration;

  当前的播放位  @property NSTimeInterval currentTime;

  播放次数(-1代表无限循环播放,其他代表播放numberOfLoops+1次 @property NSInteger numberOfLoops;

  音量      @property float volume;

  是否允许更改速率@property BOOL enableRate;

  播放速率(1是正常速率,0.5是一般速率,2是双倍速率)  @property float rate;

  有多少个声道 @property(readonly) NSUInteger numberOfChannels;

2.播放多个音乐文件

说明:如果要播放多个音乐文件,那么最傻瓜的做法是,创建多个全局的播放器去播放对应的音乐文件,但是这种方法无法适用于需要播放的文件数量巨大的情况。

  另外一种做法是:自己封装一个播放音乐文件的工具类。

封装工具类的实现步骤:

  新建一个类,继承自NSObject类。提供三个对外的接口:

  

分别是:

播放音乐(参数:文件名)

暂停音乐(参数:文件名)

停止音乐(参数:文件名)

该工具类中的代码设计如下:

XZAudioTool.h文件

 1 #import <Foundation/Foundation.h>
 2
 3 @interface XZAudioTool : NSObject
 4
 5 /**
 6  *  根据音乐文件名称播放音乐
 7  *
 8  *  @param filename 音乐文件名称
 9  */
10 + (void)playMusicWithFilename:(NSString  *)filename;
11
12 /**
13  *  根据音乐文件名称暂停音乐
14  *
15  *  @param filename 音乐文件名称
16  */
17 + (void)pauseMusicWithFilename:(NSString  *)filename;
18
19 /**
20  *  根据音乐文件名称停止音乐
21  *
22  *  @param filename 音乐文件名称
23  */
24 + (void)stopMusicWithFilename:(NSString  *)filename;
25 @end

XZAudioTool.m文件测试程序:

  1 #import "XZAudioTool.h"
  2 #import <AVFoundation/AVFoundation.h>
  3
  4 @implementation XZAudioTool
  5 /**
  6  *  存放所有的音乐播放器
  7  */
  8 static NSMutableDictionary *_players;
  9 + (NSMutableDictionary *)players
 10 {
 11     if (!_players) {
 12         _players = [NSMutableDictionary dictionary];
 13     }
 14     return _players;
 15 }
 16
 17 /**
 18  *  根据音乐文件名称播放音乐
 19  *
 20  *  @param filename 音乐文件名称
 21  */
 22 + (void)playMusicWithFilename:(NSString  *)filename
 23 {
 24     // 0.判断文件名是否为nil
 25     if (filename == nil) {
 26         return;
 27     }
 28
 29     // 1.从字典中取出播放器
 30     AVAudioPlayer *player = [self players][filename];
 31
 32     // 2.判断播放器是否为nil
 33     if (!player) {
 34         NSLog(@"创建新的播放器");
 35
 36         // 2.1根据文件名称加载音效URL
 37         NSURL *url = [[NSBundle mainBundle] URLForResource:filename withExtension:nil];
 38
 39         // 2.2判断url是否为nil
 40         if (!url) {
 41             return;
 42         }
 43
 44         // 2.3创建播放器
 45         player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
 46
 47         // 2.4准备播放
 48         if(![player prepareToPlay])
 49         {
 50             return; //如果缓冲失败,那么就直接返回
 51         }
 52         // 允许快进
 53         player.enableRate = YES;
 54         player.rate = 3;
 55
 56         // 2.5将播放器添加到字典中
 57         [self players][filename] = player;
 58
 59     }
 60     // 3.播放音乐
 61     if (!player.playing)
 62     {
 63         [player play];
 64     }
 65
 66 }
 67
 68 /**
 69  *  根据音乐文件名称暂停音乐
 70  *
 71  *  @param filename 音乐文件名称
 72  */
 73 + (void)pauseMusicWithFilename:(NSString  *)filename
 74 {
 75     // 0.判断文件名是否为nil
 76     if (filename == nil) {
 77         return;
 78     }
 79
 80     // 1.从字典中取出播放器
 81     AVAudioPlayer *player = [self players][filename];
 82
 83     // 2.判断播放器是否存在
 84     if(player)
 85     {
 86         // 2.1判断是否正在播放
 87         if (player.playing)
 88         {
 89             // 暂停
 90             [player pause];
 91         }
 92     }
 93
 94 }
 95
 96 /**
 97  *  根据音乐文件名称停止音乐
 98  *
 99  *  @param filename 音乐文件名称
100  */
101 + (void)stopMusicWithFilename:(NSString  *)filename
102 {
103     // 0.判断文件名是否为nil
104     if (filename == nil) {
105         return;
106     }
107
108     // 1.从字典中取出播放器
109     AVAudioPlayer *player = [self players][filename];
110
111     // 2.判断播放器是否为nil
112     if (player) {
113         // 2.1停止播放
114         [player stop];
115         // 2.2清空播放器
116 //        player = nil;
117         // 2.3从字典中移除播放器
118         [[self players] removeObjectForKey:filename];
119     }
120 }
121 @end

在storyboard中拖拽控件,并进行连线,以做控制。

导入可供播放的音乐素材。

测试程序的代码设计如下:

 1 //
 2 //  ViewController.m
 3 //  03-多个音乐文件的播放
 4 //
 5 //  Created by XZ on 14/11/7.
 6 //  Copyright (c) 2014年 github. All rights reserved.
 7 //
 8
 9 #import "ViewController.h"
10 #import <AVFoundation/AVFoundation.h>
11 #import "XZAudioTool.h"
12
13 @interface ViewController ()
14 //  播放器
15 @property (nonatomic, strong) AVAudioPlayer *player;
16
17 // 播放
18 - (IBAction)playMusic;
19
20 // 暂停
21 - (IBAction)pauseMusic;
22
23 // 停止
24 - (IBAction)stopMusic;
25
26 // 下一首
27 - (IBAction)nextMusic;
28
29 // 用一个数组来保存所有的音乐文件
30 @property (nonatomic, strong) NSArray *musics;
31
32 // 用一个int型的属性来记录当前播放音乐的索引
33 @property (nonatomic, assign) int  currentIndex;
34 @end
35
36 @implementation ViewController
37
38 #pragma mark - 懒加载
39 - (NSArray *)musics
40 {
41     if (!_musics) {
42         _musics = @[@"最佳损友.mp3", @"心碎了无痕.mp3", @"瓦解.mp3", @"简单爱.mp3"];
43     }
44     return _musics;
45 }
46
47 - (void)viewDidLoad {
48     [super viewDidLoad];
49 }
50
51 - (IBAction)playMusic {
52     // 开始播放/继续播放
53     [XZAudioTool playMusicWithFilename:self.musics[self.currentIndex]];
54 }
55
56 - (IBAction)pauseMusic {
57     // 暂停
58     [XZAudioTool pauseMusicWithFilename:self.musics[self.currentIndex]];
59 }
60
61 - (IBAction)stopMusic {
62     // 停止
63     [XZAudioTool stopMusicWithFilename:self.musics[self.currentIndex]];
64
65 }
66
67 - (IBAction)nextMusic {
68     // 下一首
69
70     // 1.递增索引
71     int nextIndex = self.currentIndex + 1;
72
73     // 1.1.判断是否越界
74     if (nextIndex >= self.musics.count) {
75         nextIndex = 0;
76     }
77     NSLog(@"当前 %d  下一首 %d",  self.currentIndex, nextIndex);
78     // 2.播放
79     // 2.1停止上一首播放
80     [self stopMusic];
81     self.currentIndex = nextIndex;
82     // 2.2播放下一首
83     [self playMusic];
84 }
85
86 @end

二、对工具类进行改造,让其兼能播放音效文件

说明:

  音效只有创建、播放和销毁(停止)三个操作,因为音效一般都很短,因此没有暂停的方法。

  

把对音效文件的播放加入到工具类中,实现的代码如下:

XZAudioTool.h文件

 1 #import <Foundation/Foundation.h>
 2
 3 @interface XZAudioTool : NSObject
 4 /**
 5  *  根据音效文件名称播放音效
 6  *
 7  *  @param filename 音效文件名称
 8  */
 9 + (void)playAudioWithFilename:(NSString  *)filename;
10
11 /**
12  *  根据音效文件名称销毁音效
13  *
14  *  @param filename 音效文件名称
15  */
16 + (void)disposeAudioWithFilename:(NSString  *)filename;
17
18 /**
19  *  根据音乐文件名称播放音乐
20  *
21  *  @param filename 音乐文件名称
22  */
23 + (void)playMusicWithFilename:(NSString  *)filename;
24
25 /**
26  *  根据音乐文件名称暂停音乐
27  *
28  *  @param filename 音乐文件名称
29  */
30 + (void)pauseMusicWithFilename:(NSString  *)filename;
31
32 /**
33  *  根据音乐文件名称停止音乐
34  *
35  *  @param filename 音乐文件名称
36  */
37 + (void)stopMusicWithFilename:(NSString  *)filename;
38 @end

SLAudioTool.m文件测试程序:

  1 #import "XZAudioTool.h"
  2 #import <AVFoundation/AVFoundation.h>
  3
  4 @implementation XZAudioTool
  5 /**
  6  *  存放所有的音效ID
  7  */
  8 static NSMutableDictionary *_soundIDs;
  9 + (NSMutableDictionary *)soundIDs
 10 {
 11     if (!_soundIDs) {
 12         _soundIDs = [NSMutableDictionary dictionary];
 13     }
 14     return _soundIDs;
 15 }
 16
 17 /**
 18  *  存放所有的音乐播放器
 19  */
 20 static NSMutableDictionary *_players;
 21 + (NSMutableDictionary *)players
 22 {
 23     if (!_players) {
 24         _players = [NSMutableDictionary dictionary];
 25     }
 26     return _players;
 27 }
 28
 29 /**
 30  *  根据音效文件名称播放音乐
 31  *
 32  *  @param filename 音效文件名称
 33  */
 34 + (void)playAudioWithFilename:(NSString *)filename
 35 {
 36
 37     // 0.判断文件名是否为nil
 38     if (filename == nil) {
 39         return;
 40     }
 41
 42     // 1.从字典中取出音效ID
 43     SystemSoundID soundID = [[self soundIDs][filename] unsignedIntValue];
 44
 45     // 判断音效ID是否为nil
 46     if (!soundID) {
 47         NSLog(@"创建新的soundID");
 48
 49         // 音效ID为nil
 50         // 根据文件名称加载音效URL
 51         NSURL *url = [[NSBundle mainBundle] URLForResource:filename withExtension:nil];
 52
 53         // 判断url是否为nil
 54         if (!url) {
 55             return;
 56         }
 57
 58         // 创建音效ID
 59         AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url), &soundID);
 60
 61         // 将音效ID添加到字典中
 62         [self soundIDs][filename] = @(soundID);
 63     }
 64     // 播放音效
 65     AudioServicesPlaySystemSound(soundID);
 66 }
 67
 68 /**
 69  *  根据音效文件名称销毁音乐
 70  *
 71  *  @param filename 音效文件名称
 72  */
 73 + (void)disposeAudioWithFilename:(NSString *)filename
 74 {
 75     // 0.判断文件名是否为nil
 76     if (filename == nil) {
 77         return;
 78     }
 79
 80     // 1.从字典中取出音效ID
 81     SystemSoundID soundID = [[self soundIDs][filename] unsignedIntValue];
 82
 83     if (soundID) {
 84         // 2.销毁音效ID
 85         AudioServicesDisposeSystemSoundID(soundID);
 86
 87         // 3.从字典中移除已经销毁的音效ID
 88         [[self soundIDs] removeObjectForKey:filename];
 89     }
 90
 91 }
 92
 93
 94 /**
 95  *  根据音乐文件名称播放音乐
 96  *
 97  *  @param filename 音乐文件名称
 98  */
 99 + (void)playMusicWithFilename:(NSString  *)filename
100 {
101     // 0.判断文件名是否为nil
102     if (filename == nil) {
103         return;
104     }
105
106     // 1.从字典中取出播放器
107     AVAudioPlayer *player = [self players][filename];
108
109     // 2.判断播放器是否为nil
110     if (!player) {
111         NSLog(@"创建新的播放器");
112
113         // 2.1根据文件名称加载音效URL
114         NSURL *url = [[NSBundle mainBundle] URLForResource:filename withExtension:nil];
115
116         // 2.2判断url是否为nil
117         if (!url) {
118             return;
119         }
120
121         // 2.3创建播放器
122         player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
123
124         // 2.4准备播放
125         if(![player prepareToPlay])
126         {
127             return; //如果缓冲失败,那么就直接返回
128         }
129         // 允许快进
130         player.enableRate = YES;
131         player.rate = 3;
132
133         // 2.5将播放器添加到字典中
134         [self players][filename] = player;
135
136     }
137     // 3.播放音乐
138     if (!player.playing)
139     {
140         [player play];
141     }
142
143 }
144
145 /**
146  *  根据音乐文件名称暂停音乐
147  *
148  *  @param filename 音乐文件名称
149  */
150 + (void)pauseMusicWithFilename:(NSString  *)filename
151 {
152     // 0.判断文件名是否为nil
153     if (filename == nil) {
154         return;
155     }
156
157     // 1.从字典中取出播放器
158     AVAudioPlayer *player = [self players][filename];
159
160     // 2.判断播放器是否存在
161     if(player)
162     {
163         // 2.1判断是否正在播放
164         if (player.playing)
165         {
166             // 暂停
167             [player pause];
168         }
169     }
170
171 }
172
173 /**
174  *  根据音乐文件名称停止音乐
175  *
176  *  @param filename 音乐文件名称
177  */
178 + (void)stopMusicWithFilename:(NSString  *)filename
179 {
180     // 0.判断文件名是否为nil
181     if (filename == nil) {
182         return;
183     }
184
185     // 1.从字典中取出播放器
186     AVAudioPlayer *player = [self players][filename];
187
188     // 2.判断播放器是否为nil
189     if (player) {
190         // 2.1停止播放
191         [player stop];
192         // 2.2清空播放器
193 //        player = nil;
194         // 2.3从字典中移除播放器
195         [[self players] removeObjectForKey:filename];
196     }
197 }
198 @end

代码测试:

- (IBAction)playMusic {
    // 开始播放/继续播放
//    [HMAudioTool playMusicWithFilename:self.musics[self.currentIndex]];
    [HMAudioTool playAudioWithFilename:@"buyao.wav"];
}

代码说明:

打印的值为0,播放成功(因为函数是C++中的)

时间: 08-11

iOS开发拓展篇—封装音频文件播放工具类的相关文章

iOS开发拓展篇—音频处理(音乐播放器3)

iOS开发拓展篇—音频处理(音乐播放器3) 说明:这篇文章主要介绍音频工具类和播放工具类的封装. 一.控制器间数据传递 1.两个控制器之间数据的传递 第一种方法:self.parentViewController.music=self.music[indexPath.row];不能满足 第二种做法:把整个数组传递给它 第三种做法:设置一个数据源,设置播放控制器的数据源是这个控制器.self.parentViewController.dataSource=self;好处:没有耦合性,任何实现了协议

iOS开发拓展篇—音频处理(音乐播放器1

iOS开发拓展篇—音频处理(音乐播放器1) 说明:该系列文章通过实现一个简单的音乐播放器来介绍音频处理的相关知识点,需要重点注意很多细节的处理. 一.调整项目的结构,导入必要的素材 调整后的项目结构如下: 二.新建两个控制器 (1)新建一个控制器,用于展示音乐文件列表界面,其继承自UITableViewController (2)新建一个控制器,用于展示播放界面,其继承自UIViewController (3)在storyboard中,把之前的控制器删除,换上一个导航控制器,设置tableVie

iOS开发拓展篇—音频处理(音乐播放器2)

iOS开发拓展篇—音频处理(音乐播放器2) 说明:该文主要介绍音乐播放界面的搭建. 一.跳转 1.跳转到音乐播放界面的方法选择 (1)使用模态跳转(又分为手动的和自动的) (2)使用xib并设置跳转 2.两种方法的分析 可以使用模态的方法,添加一个控制器,让这个控制器和音乐播放控制器类进行关联,脱线,设置标识符且在cell的点击事件中执行segue即可. 步骤说明: (1)在storyboard中新拖入一个控制器,然后设置和playing控制器类相关联. (2)设置手动跳转 (3)设置segue

iOS开发拓展篇—音频处理(音乐播放器5)

iOS开发拓展篇—音频处理(音乐播放器5) 实现效果: 一.半透明滑块的设置 1 /** 2 *拖动滑块 3 */ 4 - (IBAction)panSlider:(UIPanGestureRecognizer *)sender { 5 6 //1.获得挪动的距离 7 CGPoint t=[sender translationInView:sender.view]; 8 //把挪动清零 9 [sender setTranslation:CGPointZero inView:sender.view

iOS开发拓展篇—音频处理(音乐播放器6)

iOS开发拓展篇—音频处理(音乐播放器6) 一.图片处理 说明: Aspect表示按照原来的宽高比进行缩放. Aspectfit表示按照原来的宽高比缩放,要求看到全部图片,后果是不能完全覆盖窗口,会留有空白. Aspectfill表示按照原来的宽高比缩放,但只能看到部分图片.引发的问题:可能会有一部分超出屏幕. 所以,如果选择了Aspectfill模式,那么需要剪切超出的图片,在storyboard中也可以进行设置. 下面的两种设置是等效的. (1)在storyboard中进行设置 (2)使用代

iOS开发拓展篇—音频处理(音乐播放器4)

iOS开发拓展篇—音频处理(音乐播放器4) 说明:该文主要介绍音乐播放器实现过程中的一些细节控制. 实现的效果: 一.完整的代码 YYPlayingViewController.m文件 1 // 2 // YYPlayingViewController.m 3 // 20-音频处理(音乐播放器1) 4 // 5 // Created by apple on 14-8-13. 6 // Copyright (c) 2014年 yangyong. All rights reserved. 7 //

iOS开发拓展篇—音乐的播放

iOS开发拓展篇—音乐的播放 一.简单说明 音乐播放用到一个叫做AVAudioPlayer的类,这个类可以用于播放手机本地的音乐文件. 注意: (1)该类(AVAudioPlayer)只能用于播放本地音频. (2)时间比较短的(称之为音效)使用AudioServicesCreateSystemSoundID来创建,而本地时间较长(称之为音乐)使用AVAudioPlayer类. 二.代码示例 AVAudioPlayer类依赖于AVFoundation框架,因此使用该类必须先导入AVFoundati

iOS开发拓展篇—音效播放

iOS开发拓展篇—音效播放 一.简单介绍 简单来说,音频可以分为2种 (1)音效 又称“短音频”,通常在程序中的播放时长为1~2秒 在应用程序中起到点缀效果,提升整体用户体验 (2)音乐 比如游戏中的“背景音乐”,一般播放时间较长 框架:播放音频需要用到AVFoundation.framework框架 二.音效的播放 1.获得音效文件的路径 NSURL *url = [[NSBundle mainBundle] URLForResource:@"m_03.wav" withExtens

iOS开发拓展篇—音效的播放

iOS开发拓展篇—音效的播放 一.简单介绍 简单来说,音频可以分为2种 (1)音效 又称“短音频”,通常在程序中的播放时长为1~2秒 在应用程序中起到点缀效果,提升整体用户体验 (2)音乐 比如游戏中的“背景音乐”,一般播放时间较长 框架:播放音频需要用到AVFoundation.framework框架 二.音效的播放 1.获得音效文件的路径 NSURL *url = [[NSBundle mainBundle] URLForResource:@"m_03.wav" withExten