首页 > 代码库 > iOS开发拓展篇—封装音频文件播放工具类

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

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类。提供三个对外的接口:
  
分别是:
播放音乐(参数:文件名,返回值:BOOL)
暂停音乐(参数:文件名)
停止音乐(参数:文件名)
该工具类中的代码设计如下:
YYAudioTool.h文件
 1 // 2 //  YYAudioTool.h 3 //  17-多个音乐文件的播放 4 // 5 //  Created by apple on 14-8-9. 6 //  Copyright (c) 2014年 yangyong. All rights reserved. 7 // 8  9 #import <Foundation/Foundation.h>10 #import <AVFoundation/AVFoundation.h>11 @interface YYAudioTool : NSObject12 /**13  *播放音乐文件14  */15 +(BOOL)playMusic:(NSString *)filename;16 /**17  *暂停播放18  */19 +(void)pauseMusic:(NSString *)filename;20 /**21  *播放音乐文件22  */23 +(void)stopMusic:(NSString *)filename;24 @end

YYAudioTool.m文件

 1 // 2 //  YYAudioTool.m 3 //  17-多个音乐文件的播放 4 // 5 //  Created by apple on 14-8-9. 6 //  Copyright (c) 2014年 yangyong. All rights reserved. 7 // 8  9 #import "YYAudioTool.h"10 11 @implementation YYAudioTool12 /**13  *存放所有的音乐播放器14  */15 static NSMutableDictionary *_musices;16 +(NSMutableDictionary *)musices17 {18     if (_musices==nil) {19         _musices=[NSMutableDictionary dictionary];20     }21     return _musices;22 }23 24 /**25  *播放音乐26  */27 +(BOOL)playMusic:(NSString *)filename28 {29     if (!filename) return NO;//如果没有传入文件名,那么直接返回30     //1.取出对应的播放器31     AVAudioPlayer *player=[self musices][filename];32     33     //2.如果播放器没有创建,那么就进行初始化34     if (!player) {35         //2.1音频文件的URL36         NSURL *url=[[NSBundle mainBundle]URLForResource:filename withExtension:nil];37         if (!url) return NO;//如果url为空,那么直接返回38         39         //2.2创建播放器40         player=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:nil];41         42         //2.3缓冲43         if (![player prepareToPlay]) return NO;//如果缓冲失败,那么就直接返回44         45         //2.4存入字典46         [self musices][filename]=player;47     }48     49     //3.播放50     if (![player isPlaying]) {51         //如果当前没处于播放状态,那么就播放52         return [player play];53     }54 55     return YES;//正在播放,那么就返回YES56 }57 58 +(void)pauseMusic:(NSString *)filename59 {60     if (!filename) return;//如果没有传入文件名,那么就直接返回61     62     //1.取出对应的播放器63     AVAudioPlayer *player=[self musices][filename];64     65     //2.暂停66     [player pause];//如果palyer为空,那相当于[nil pause],因此这里可以不用做处理67 68 }69 70 +(void)stopMusic:(NSString *)filename71 {72     if (!filename) return;//如果没有传入文件名,那么就直接返回73     74     //1.取出对应的播放器75     AVAudioPlayer *player=[self musices][filename];76     77     //2.停止78     [player stop];79     80     //3.将播放器从字典中移除81     [[self musices] removeObjectForKey:filename];82 }83 @end

测试程序:

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

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

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

 1 // 2 //  YYViewController.m 3 //  17-多个音乐文件的播放 4 // 5 //  Created by apple on 14-8-9. 6 //  Copyright (c) 2014年 yangyong. All rights reserved. 7 // 8  9 #import "YYViewController.h"10 #import "YYAudioTool.h"11 12 @interface YYViewController ()13 - (IBAction)play;14 - (IBAction)pause;15 - (IBAction)stop;16 - (IBAction)next;17 18 //用一个数组来保存所有的音乐文件19 @property(nonatomic,strong)NSArray *songs;20 //用一个int型的属性来记录当前的索引21 @property(nonatomic,assign)int currentIndex;22 @end23 24 @implementation YYViewController25 #pragma mark-懒加载26 -(NSArray *)songs27 {28     if (_songs==nil) {29         self.songs=@[@"235319.mp3",@"309769.mp3",@"120125029.mp3"];30     }31     return _songs;32 }33 34 - (void)viewDidLoad35 {36     [super viewDidLoad];37 }38 39 - (IBAction)play {40     //开始播放/继续播放41     [YYAudioTool playMusic:self.songs[self.currentIndex]];42 }43 44 - (IBAction)pause {45     //暂停播放46     [YYAudioTool pauseMusic:self.songs[self.currentIndex]];47 }48 49 - (IBAction)stop {50     //停止播放51     [YYAudioTool stopMusic:self.songs[self.currentIndex]];52 }53 54 //播放下一首55 - (IBAction)next {56     //1.先停止当前播放57     [self stop];58     59     //2.设置当前索引+160     self.currentIndex++;61     if (self.currentIndex>=self.songs.count) {62         self.currentIndex=0;63     }64     65     //3.播放音乐66     [self play];67 }68 @end

 

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

说明

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

  

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

YYAudioTool.h文件

 1 // 2 //  YYAudioTool.h 3 //  17-多个音乐文件的播放 4 // 5 //  Created by apple on 14-8-9. 6 //  Copyright (c) 2014年 yangyong. All rights reserved. 7 // 8  9 #import <Foundation/Foundation.h>10 #import <AVFoundation/AVFoundation.h>11 @interface YYAudioTool : NSObject12 /**13  *播放音乐文件14  */15 +(BOOL)playMusic:(NSString *)filename;16 /**17  *暂停播放18  */19 +(void)pauseMusic:(NSString *)filename;20 /**21  *播放音乐文件22  */23 +(void)stopMusic:(NSString *)filename;24 25 /**26  *播放音效文件27  */28 +(void)playSound:(NSString *)filename;29 /**30  *销毁音效31  */32 +(void)disposeSound:(NSString *)filename;33 @end

YYAudioTool.m文件

  1 //  2 //  YYAudioTool.m  3 //  17-多个音乐文件的播放  4 //  5 //  Created by apple on 14-8-9.  6 //  Copyright (c) 2014年 yangyong. All rights reserved.  7 //  8   9 #import "YYAudioTool.h" 10  11 @implementation YYAudioTool 12 /** 13  *存放所有的音乐播放器 14  */ 15 static NSMutableDictionary *_musicPlayers; 16 +(NSMutableDictionary *)musicPlayers 17 { 18     if (_musicPlayers==nil) { 19         _musicPlayers=[NSMutableDictionary dictionary]; 20     } 21     return _musicPlayers; 22 } 23  24 /** 25  *存放所有的音效ID 26  */ 27 static NSMutableDictionary *_soundIDs; 28 +(NSMutableDictionary *)soundIDs 29 { 30     if (_soundIDs==nil) { 31         _soundIDs=[NSMutableDictionary dictionary]; 32     } 33     return _soundIDs; 34 } 35  36  37 /** 38  *播放音乐 39  */ 40 +(BOOL)playMusic:(NSString *)filename 41 { 42     if (!filename) return NO;//如果没有传入文件名,那么直接返回 43     //1.取出对应的播放器 44     AVAudioPlayer *player=[self musicPlayers][filename]; 45      46     //2.如果播放器没有创建,那么就进行初始化 47     if (!player) { 48         //2.1音频文件的URL 49         NSURL *url=[[NSBundle mainBundle]URLForResource:filename withExtension:nil]; 50         if (!url) return NO;//如果url为空,那么直接返回 51          52         //2.2创建播放器 53         player=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:nil]; 54          55         //2.3缓冲 56         if (![player prepareToPlay]) return NO;//如果缓冲失败,那么就直接返回 57          58         //2.4存入字典 59         [self musicPlayers][filename]=player; 60     } 61      62     //3.播放 63     if (![player isPlaying]) { 64         //如果当前没处于播放状态,那么就播放 65         return [player play]; 66     } 67  68     return YES;//正在播放,那么就返回YES 69 } 70  71 +(void)pauseMusic:(NSString *)filename 72 { 73     if (!filename) return;//如果没有传入文件名,那么就直接返回 74      75     //1.取出对应的播放器 76     AVAudioPlayer *player=[self musicPlayers][filename]; 77      78     //2.暂停 79     [player pause];//如果palyer为空,那相当于[nil pause],因此这里可以不用做处理 80  81 } 82  83 +(void)stopMusic:(NSString *)filename 84 { 85     if (!filename) return;//如果没有传入文件名,那么就直接返回 86      87     //1.取出对应的播放器 88     AVAudioPlayer *player=[self musicPlayers][filename]; 89      90     //2.停止 91     [player stop]; 92      93     //3.将播放器从字典中移除 94     [[self musicPlayers] removeObjectForKey:filename]; 95 } 96  97 //播放音效 98 +(void)playSound:(NSString *)filename 99 {100     if (!filename) return;101     //1.取出对应的音效102     SystemSoundID soundID=[[self soundIDs][filename] unsignedIntegerValue];103     104     //2.播放音效105     //2.1如果音效ID不存在,那么就创建106     if (!soundID) {107         108         //音效文件的URL109         NSURL *url=[[NSBundle mainBundle]URLForResource:filename withExtension:nil];110         if (!url) return;//如果URL不存在,那么就直接返回111         112         OSStatus status = AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url), &soundID);113         NSLog(@"%ld",status);114         //存入到字典中115         [self soundIDs][filename]=@(soundID);116     }117     118     //2.2有音效ID后,播放音效119     AudioServicesPlaySystemSound(soundID);120 }121 122 //销毁音效123 +(void)disposeSound:(NSString *)filename124 {125     //如果传入的文件名为空,那么就直接返回126     if (!filename) return;127     128     //1.取出对应的音效129     SystemSoundID soundID=[[self soundIDs][filename] unsignedIntegerValue];130     131     //2.销毁132     if (soundID) {133         AudioServicesDisposeSystemSoundID(soundID);134         135         //2.1销毁后,从字典中移除136         [[self soundIDs]removeObjectForKey:filename];137     }138 }139 @end

代码测试:

代码说明:

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