实例解析iOS app开发中音频文件播放工具类的封装

一、简单说明

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文件


//

//  YYAudioTool.h

//  17-多个音乐文件的播放

//

//  Created by apple on 14-8-9.

//  Copyright (c) 2014年 yangyong. All rights reserved.

//

#import <Foundation/Foundation.h> #import <AVFoundation/AVFoundation.h> @interface YYAudioTool : NSObject /**  *播放音乐文件  */ +(BOOL)playMusic:(NSString *)filename; /**  *暂停播放  */ +(void)pauseMusic:(NSString *)filename; /**  *播放音乐文件  */ +(void)stopMusic:(NSString *)filename; @end


YYAudioTool.m文件

//

//  YYAudioTool.m

//  17-多个音乐文件的播放

//

//  Created by apple on 14-8-9.

//  Copyright (c) 2014年 yangyong. All rights reserved.

//

#import "YYAudioTool.h"

@implementation YYAudioTool /**  *存放所有的音乐播放器  */ static NSMutableDictionary *_musices; +(NSMutableDictionary *)musices {     if (_musices==nil) {         _musices=[NSMutableDictionary dictionary];     }     return _musices; }

/**  *播放音乐  */ +(BOOL)playMusic:(NSString *)filename {     if (!filename) return NO;//如果没有传入文件名,那么直接返回     //1.取出对应的播放器     AVAudioPlayer *player=[self musices][filename];         //2.如果播放器没有创建,那么就进行初始化     if (!player) {         //2.1音频文件的URL         NSURL *url=[[NSBundle mainBundle]URLForResource:filename withExtension:nil];         if (!url) return NO;//如果url为空,那么直接返回                 //2.2创建播放器         player=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:nil];                 //2.3缓冲         if (![player prepareToPlay]) return NO;//如果缓冲失败,那么就直接返回                 //2.4存入字典         [self musices][filename]=player;     }         //3.播放     if (![player isPlaying]) {         //如果当前没处于播放状态,那么就播放         return [player play];     }

    return YES;//正在播放,那么就返回YES }

+(void)pauseMusic:(NSString *)filename {     if (!filename) return;//如果没有传入文件名,那么就直接返回         //1.取出对应的播放器     AVAudioPlayer *player=[self musices][filename];         //2.暂停     [player pause];//如果palyer为空,那相当于[nil pause],因此这里可以不用做处理

}

+(void)stopMusic:(NSString *)filename {     if (!filename) return;//如果没有传入文件名,那么就直接返回         //1.取出对应的播放器     AVAudioPlayer *player=[self musices][filename];         //2.停止     [player stop];         //3.将播放器从字典中移除     [[self musices] removeObjectForKey:filename]; } @end


测试程序:

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

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

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


//

//  YYViewController.m

//  17-多个音乐文件的播放

//

//  Created by apple on 14-8-9.

//  Copyright (c) 2014年 yangyong. All rights reserved.

//

#import "YYViewController.h" #import "YYAudioTool.h"

@interface YYViewController () - (IBAction)play; - (IBAction)pause; - (IBAction)stop; - (IBAction)next;

//用一个数组来保存所有的音乐文件 @property(nonatomic,strong)NSArray *songs; //用一个int型的属性来记录当前的索引 @property(nonatomic,assign)int currentIndex; @end



@implementation YYViewController

#pragma mark-懒加载

-(NSArray *)songs

{

    if (_songs==nil) {

        self.songs=@[@"235319.mp3",@"309769.mp3",@"120125029.mp3"];

    }

    return _songs;

}

- (void)viewDidLoad {     [super viewDidLoad]; }

- (IBAction)play {     //开始播放/继续播放     [YYAudioTool playMusic:self.songs[self.currentIndex]]; }

- (IBAction)pause {     //暂停播放     [YYAudioTool pauseMusic:self.songs[self.currentIndex]]; }

- (IBAction)stop {     //停止播放     [YYAudioTool stopMusic:self.songs[self.currentIndex]]; }

//播放下一首 - (IBAction)next {     //1.先停止当前播放     [self stop];         //2.设置当前索引+1     self.currentIndex++;     if (self.currentIndex>=self.songs.count) {         self.currentIndex=0;     }         //3.播放音乐     [self play]; } @end


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

说明:

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

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

YYAudioTool.h文件


//

//  YYAudioTool.h

//  17-多个音乐文件的播放

//

//  Created by apple on 14-8-9.

//  Copyright (c) 2014年 yangyong. All rights reserved.

//

#import <Foundation/Foundation.h> #import <AVFoundation/AVFoundation.h> @interface YYAudioTool : NSObject /**  *播放音乐文件  */ +(BOOL)playMusic:(NSString *)filename; /**  *暂停播放  */ +(void)pauseMusic:(NSString *)filename; /**  *播放音乐文件  */ +(void)stopMusic:(NSString *)filename;

/**  *播放音效文件  */ +(void)playSound:(NSString *)filename; /**  *销毁音效  */ +(void)disposeSound:(NSString *)filename; @end

YYAudioTool.m文件

// //  YYAudioTool.m //  17-多个音乐文件的播放 // //  Created by apple on 14-8-9. //  Copyright (c) 2014年 yangyong. All rights reserved. //

#import "YYAudioTool.h"

@implementation YYAudioTool /**  *存放所有的音乐播放器  */ static NSMutableDictionary *_musicPlayers; +(NSMutableDictionary *)musicPlayers {     if (_musicPlayers==nil) {         _musicPlayers=[NSMutableDictionary dictionary];     }     return _musicPlayers; }

/**  *存放所有的音效ID  */ static NSMutableDictionary *_soundIDs; +(NSMutableDictionary *)soundIDs {     if (_soundIDs==nil) {         _soundIDs=[NSMutableDictionary dictionary];     }     return _soundIDs; }

/**  *播放音乐  */ +(BOOL)playMusic:(NSString *)filename {     if (!filename) return NO;//如果没有传入文件名,那么直接返回     //1.取出对应的播放器     AVAudioPlayer *player=[self musicPlayers][filename];         //2.如果播放器没有创建,那么就进行初始化     if (!player) {         //2.1音频文件的URL         NSURL *url=[[NSBundle mainBundle]URLForResource:filename withExtension:nil];         if (!url) return NO;//如果url为空,那么直接返回                 //2.2创建播放器         player=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:nil];                 //2.3缓冲         if (![player prepareToPlay]) return NO;//如果缓冲失败,那么就直接返回                 //2.4存入字典         [self musicPlayers][filename]=player;     }         //3.播放     if (![player isPlaying]) {         //如果当前没处于播放状态,那么就播放         return [player play];     }

    return YES;//正在播放,那么就返回YES }

+(void)pauseMusic:(NSString *)filename {     if (!filename) return;//如果没有传入文件名,那么就直接返回         //1.取出对应的播放器     AVAudioPlayer *player=[self musicPlayers][filename];         //2.暂停     [player pause];//如果palyer为空,那相当于[nil pause],因此这里可以不用做处理

}

+(void)stopMusic:(NSString *)filename {     if (!filename) return;//如果没有传入文件名,那么就直接返回         //1.取出对应的播放器     AVAudioPlayer *player=[self musicPlayers][filename];         //2.停止     [player stop];         //3.将播放器从字典中移除     [[self musicPlayers] removeObjectForKey:filename]; }

//播放音效 +(void)playSound:(NSString *)filename {     if (!filename) return;     //1.取出对应的音效     SystemSoundID soundID=[[self soundIDs][filename] unsignedIntegerValue];         //2.播放音效     //2.1如果音效ID不存在,那么就创建     if (!soundID) {                 //音效文件的URL         NSURL *url=[[NSBundle mainBundle]URLForResource:filename withExtension:nil];         if (!url) return;//如果URL不存在,那么就直接返回                 OSStatus status = AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url), &soundID);         NSLog(@"%ld",status);         //存入到字典中         [self soundIDs][filename]=@(soundID);     }         //2.2有音效ID后,播放音效     AudioServicesPlaySystemSound(soundID); }

//销毁音效 +(void)disposeSound:(NSString *)filename {     //如果传入的文件名为空,那么就直接返回     if (!filename) return;         //1.取出对应的音效     SystemSoundID soundID=[[self soundIDs][filename] unsignedIntegerValue];         //2.销毁     if (soundID) {         AudioServicesDisposeSystemSoundID(soundID);                 //2.1销毁后,从字典中移除         [[self soundIDs]removeObjectForKey:filename];     } } @end


代码测试:

代码说明:

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

声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:notice#nhooo.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。