// AVAudioPlayer是AVFoundation.framework里面最基本的一个音频播放器的类。它与MPMediaPlayerController在一些基本操作功能上是类同的,比如play,pause,volume等等。不一样的地方在于AVAudioPlayer没有队列这个东西,也就是说它只能播放一个指定路径的音频。要播放多个音频,可以通过创建多个AVAudioPlayer来实现。在AVFoundation里面,有另外一个功能强大的类AVQueuePlayer,基本上要做音乐播放器要靠它,什么QQ音乐,酷狗应该都是使用AVQueuePlayer。
// 要记住,使用AVFoundation的东西播放音频,肯定要先对Audio Session进行设置,除非你使用默认的设置
// AVAudioPlayer能实现的功能类似于System Audio Services,播放单一音频,但它不同的地方在于它可以控制播放的次数,播放的时间。比如用它可以很方便的实现重复播放。另外,它还有一个很强大的功能,就是可以很方便的调节左右声道的音量,从而实现很酷的立体声效果。从这个角度看,AVAudioPlayer很适用于游戏中的音频播放。
// AVAudioPlayer有一个重要的property就是pan,用它可以来调节音频播放时左右声道的大小,如果值是-1.0为完全左声道发生,如果是1.0则为完全右声道发音。另外,还有一个很强大的功能,就是可以测量音频播放时实时声道的功率大小,这个功能可以用于辅助显示声音的波浪,很多电脑上的播放器都有的。当然,如果用它来进行声波的分析,我想也是可以的
/* // audioPlayerOne 为一个AVAudioPlayer的对象
self.audioPlayerOne.meteringEnabled = YES; // 允许测量
[self.audioPlayerOne updateMeters]; // 更新数据
[self.averagePowerChannelOne setValue:[self.audioPlayerOne averagePowerForChannel:0] animated:YES]; //将获取的数据赋予相关的控件
[self.averagePowerChannelTwo setValue:[self.audioPlayerOne averagePowerForChannel:1] animated:YES];
*/
#import "MainViewController.h"
#import <AVFoundation/AVFoundation.h>
@interface MainViewController ()
@property(nonatomic,retain)AVAudioPlayer * audioPlayer;//音频播放器
@property(nonatomic,retain)UISlider * volumeSlider;//声音控制slider
@property(nonatomic,retain)UISlider * progrssSlider;//音频进度sliser
@property(nonatomic,retain)NSTimer * timer;// 用NSTimer监控音频播放进度
@property(nonatomic,retain)UIProgressView * audioProgressView;// 播放进度条
@property(nonatomic,retain)UILabel * progressLabel;// 进度显示框
@property(nonatomic,retain)UISegmentedControl * segmentControl;// 播放选择segmentControl
@property(nonatomic,retain)UISwitch * swich;// 静音开关
@end
@implementation MainViewController
- (void)dealloc
{
self.audioPlayer =nil;
self.volumeSlider =nil;
self.progrssSlider =nil;
self.audioProgressView =nil;
self.progressLabel =nil;
self.segmentControl =nil;
self.swich =nil;
[superdealloc];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [superinitWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[superviewDidLoad];
self.navigationItem.title =@"AVAudioPlayer";
// 初始化一个audioplayer
[selfcreatAnAudioPlayer];
// 视图布局
[selfsetUpView];
// 初始化NSTimer 监控音频播放进度
self.timer = [NSTimerscheduledTimerWithTimeInterval:0.1 target:selfselector:@selector(playProgress)userInfo:nilrepeats:YES];
}
// 创建视图
- (void)setUpView
{
// UISegmentedControl自己的初始化方法
self.segmentControl =[[[UISegmentedControlalloc] initWithItems:@[@"play",@"pause",@"stop"]]autorelease];
// UISegmentedControl在UIControlEventValueChanged触发响应事件
[_segmentControladdTarget:selfaction:@selector(didClickSegmentControlAction:)forControlEvents:(UIControlEventValueChanged)];
_segmentControl.frame =CGRectMake(10, 80, 300, 40);
[self.viewaddSubview:_segmentControl];
// 创建UIProgressView 自己的初始化方法
self.audioProgressView = [[[UIProgressViewalloc] initWithProgressViewStyle:(UIProgressViewStyleBar)]autorelease];
//进度条显示的数据由NSTimer监督显示(实时变化)
_audioProgressView.frame =CGRectMake(10, 180, 300, 40);
_audioProgressView.backgroundColor = [UIColoryellowColor];
[self.viewaddSubview:_audioProgressView];
// 播放进度显示框
self.progressLabel = [[[UILabelalloc] initWithFrame:CGRectMake(10, 130, 300, 40)]autorelease];
//显示的数据由NSTimer监督显示(实时变化)
_progressLabel.backgroundColor = [UIColorcyanColor];
_progressLabel.textAlignment =NSTextAlignmentCenter;
[self.viewaddSubview:_progressLabel];
// 声音调控UISlider
self.volumeSlider = [[[[UISlideralloc] initWithFrame:CGRectMake(10, 200, 300, 30)]autorelease] autorelease];
_volumeSlider.minimumValue = 0;
_volumeSlider.maximumValue = 1.0;
_volumeSlider.value = 0.5;
[_volumeSlideraddTarget:selfaction:@selector(handleVolumeSlider:)forControlEvents:(UIControlEventValueChanged)];
[self.viewaddSubview:_volumeSlider];
// 音频播放进度调控UISlider
self.progrssSlider = [[[UISlideralloc] initWithFrame:CGRectMake(10, 230, 300, 30)]autorelease];
_progrssSlider.minimumValue = 0;
_progrssSlider.maximumValue = 1.0;
[_progrssSlideraddTarget:selfaction:@selector(handleProgreeSlider:)forControlEvents:(UIControlEventValueChanged)];
[self.viewaddSubview:_progrssSlider];
// 声音开关控件
self.swich = [[[UISwitchalloc] initWithFrame:CGRectMake(10, 280, 60, 30)]autorelease];
[_swich addTarget:selfaction:@selector(onOrOff:)forControlEvents:UIControlEventValueChanged];
// 默认状态为开
_swich.on =YES;
[self.viewaddSubview:_swich];
}
- (void)playProgress
{
// 实时数据显示
_audioProgressView.progress = [selfaudioPlayerProgress];
_progressLabel.text = [NSStringstringWithFormat:@"进度 :%.2f",[selfaudioPlayerProgress]];
}
// 声音开关(是否静音)
- (void)onOrOff:(UISwitch *)sender{
_audioPlayer.volume = sender.on;
}
// 设置播放进度
- (void)handleProgreeSlider:(UISlider *)slider
{
// pause the Player
[_audioPlayer pause];
// 计算新的时间
_audioPlayer.currentTime= slider.value *_audioPlayer.duration;
_segmentControl.selectedSegmentIndex = 1;
}
// 设置音量
- (void)handleVolumeSlider:(UISlider *)slider
{
if (_swich.on ==YES) {
_audioPlayer.volume = slider.value;
}else{
_audioPlayer.volume = 0;
}
}
// 音频播放进度
- (CGFloat)audioPlayerProgress
{
CGFloat progress =_audioPlayer.currentTime/_audioPlayer.duration;
return progress;
}
// 点击segmentControl的响应时间
- (void)didClickSegmentControlAction:(UISegmentedControl *)segmentControl
{
if (0 == segmentControl.selectedSegmentIndex) {
[_audioPlayerplay];
}elseif (1 == segmentControl.selectedSegmentIndex){
[_audioPlayerpause];
}else{
[_audioPlayerstop];
_audioPlayer.currentTime = 0;
_progrssSlider.value = 0;
}
}
// 初始化一个audioPlayer
- (void)creatAnAudioPlayer
{ // 异步加载音频
dispatch_queue_t dispatchQueue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
dispatch_async(dispatchQueue, ^{
// 在本地读取
NSString * path = [[NSBundlemainBundle] pathForResource:@"谈何容易" ofType:@"mp3"];
NSError * error;
NSData * data = [NSDatadataWithContentsOfFile:path];
self.audioPlayer = [[AVAudioPlayeralloc] initWithData:dataerror:&error];
/*
// initWithData:error:他使用一个指向内存中一些音频数据的NSData对象.这种形式对于已经把音频数据下载到缓冲区的情形很有用.
// initWithContentsOfURL:error NSURL 它只能从file://格式的URL装入音频数据不支持流式音频及HTTP流和网络流
NSURL * url = [[NSURL alloc] initFileURLWithPath:path];
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
*/
if (error) {
NSLog(@"error = %@",[errorlocalizedDescription]);
}
[_audioPlayerprepareToPlay];
// delegate
_audioPlayer.delegate =self;
// -1为循环播放
_audioPlayer.numberOfLoops = -1;
[_audioPlayersetRate:2.0]; //设置播放速度
[_audioPlayersetPan:0.5]; //设置左右声道
});
}
- (void)didReceiveMemoryWarning
{
[superdidReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - AVAudioPlayerDelegate
// 音频播放完成时
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
//音频播放完成时,调用该方法。
//参数flag:如果音频播放无法解码时,该参数为NO。
// 当音频被终端时,该方法不被调用。而会调用audioPlayerBeginInterruption方法
// 和audioPlayerEndInterruption方法
[_timer invalidate]; // NSTimer暂停
}
// 解码错误
- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error
{
NSLog(@"解码错误!");
}
// 当音频播放过程中被中断时
- (void)audioPlayerBeginInterruption:(AVAudioPlayer *)player
{
//当音频播放过程中被中断时,执行该方法。比如:播放音频时,电话来了!
//这时候,音频播放将会被暂停。
}
// 当中断结束时
- (void)audioPlayerEndInterruption:(AVAudioPlayer *)player withOptions:(NSUInteger)flags{
NSLog(@"中断结束,恢复播放");
if (flags ==AVAudioSessionInterruptionOptionShouldResume && player !=nil){
[playerplay];
}
}
联系客服