IOS AVAudioPlayer 音频播放的使用

通过这个文章可以实现长音频的播放、音量、播放进度控制,以及中断事件的处理和线路切换的响应

一、配置音频会话

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    AVAudioSession *session = [AVAudioSession sharedInstance];
    NSError *error;
    if ( ![session setCategory:AVAudioSessionCategoryPlayback error:&error] ) {//设置任务类型
        NSLog(@"category error log : %@",error.localizedDescription);
    }
    if ( ![session setActive:YES error:&error] ) {//设置活跃状态
        NSLog(@"active error log : %@",error.localizedDescription);
    }
    return YES;
}

setCategory 说明:

  • AVAudioSessionCategoryAmbient 游戏、效率应用程序类型
  • AVAudioSessionCategorySoloAmbient 游戏、效率应用程序类型(默认类型)
  • AVAudioSessionCategoryPlayback 音频和视频播放器类型
  • AVAudioSessionCategoryRecord 录音机、音频捕捉类型
  • AVAudioSessionCategoryPlayAndRecord VoIP、语音聊天类型
  • AVAudioSessionCategoryAudioProcessing 离线会话和处理类型
  • AVAudioSessionCategoryMultiRoute 使用外部硬件的高级A/V应用程序

这里我们使用的是AVAudioSessionCategoryPlayback 类型

二、创建并使用AVAudioPlayer

有两种方法可以创建 AVAudioPlayer,通过NSData创建或者通过本地音频文件的NSURL创建,通过NSURL创建必须是本地路径。这里直接贴代码,功能简单就不做封装了。。。

#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
#import <QuartzCore/QuartzCore.h>

#define  SCREEN_WIDTH  [UIScreen mainScreen].bounds.size.width
#define  SCREEN_HEIGHT   [UIScreen mainScreen].bounds.size.height


@interface ViewController ()<AVAudioPlayerDelegate>

@property(nonatomic,strong)AVAudioPlayer *audioPlayer;
@property(nonatomic,strong)UIButton *playButton;
@property(nonatomic,strong)UISlider *volumeControl;
@property(nonatomic,strong)UISlider *progressControl;
@property(nonatomic,strong)NSTimer *timer;
@end

@implementation ViewController
@synthesize audioPlayer = __audioPlayer;
@synthesize playButton = __playButton;

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    NSError *error;
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"晴天" withExtension:@"mp3"];
    __audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
    if ( __audioPlayer ) {
        __audioPlayer.delegate = self;//设置代理
        __audioPlayer.volume = 1.0f;//设置音量
        [__audioPlayer prepareToPlay];//初始化准备工作
        NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
        //注册facetime 电话呼入等中断事件监听
        [notificationCenter addObserver:self selector:@selector(handleInterruption:) name:AVAudioSessionInterruptionNotification object:[AVAudioSession sharedInstance]];
        //注册线路变化 监听
        [notificationCenter addObserver:self selector:@selector(handleRouteChange:) name:AVAudioSessionRouteChangeNotification object:[AVAudioSession sharedInstance]];
    }else{
        NSLog(@"player init error log %@",error.localizedDescription);
    }
    [self configView];
}

- (void)configView{
    //播放/暂停控制按钮
    [self controlButton];
    //音量控制
    [self volumeControlView];
    //进度控制
    [self progressControlView];
}

//控制按钮
- (void)controlButton{
    __playButton = [UIButton buttonWithType:UIButtonTypeCustom];
   __playButton.frame = CGRectMake((SCREEN_WIDTH - 100)/2, 500, 100, 40);
    [__playButton setTitle:@"播放" forState:UIControlStateNormal];
    [__playButton setTitle:@"停止" forState:UIControlStateSelected];
    [__playButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    __playButton.backgroundColor = [UIColor blueColor];
    [__playButton addTarget:self action:@selector(audioPlay) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:__playButton];
}

//音量控制
- (void)volumeControlView{
    UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake((SCREEN_WIDTH - 300)/2, 370, 80, 20)];
    label.text = @"音量控制";
    label.textAlignment  = NSTextAlignmentCenter;
    label.textColor = [UIColor blackColor];
    [self.view addSubview:label];
    
    self.volumeControl = [[UISlider alloc]initWithFrame:CGRectMake((SCREEN_WIDTH - 300)/2+100, 375, 200, 10)];
    self.volumeControl.maximumValue = 1.0f;
    self.volumeControl.minimumValue = 0.0f;
    self.volumeControl.value =__audioPlayer.volume;
    [self.volumeControl addTarget:self action:@selector(volumeChange:) forControlEvents:UIControlEventValueChanged];
    [self.view addSubview:self.volumeControl];
    
}

//进度控制
- (void)progressControlView{
    UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake((SCREEN_WIDTH - 300)/2, 420, 80, 20)];
    label.text = @"进度控制";
    label.textAlignment  = NSTextAlignmentCenter;
    label.textColor = [UIColor blackColor];
    [self.view addSubview:label];
    
    self.progressControl = [[UISlider alloc]initWithFrame:CGRectMake((SCREEN_WIDTH - 300)/2+100, 425, 200, 10)];
    self.progressControl.maximumValue = __audioPlayer.duration;
    self.progressControl.minimumValue = 0.0f;
    self.progressControl.value = __audioPlayer.currentTime;
    [self.progressControl addTarget:self action:@selector(timeChange:) forControlEvents:UIControlEventValueChanged];
    [self.view addSubview:self.progressControl];
}

#pragma mark -- ACTION
//监听通知回调事件
- (void)handleInterruption:(NSNotification *)notification{
    NSDictionary *info = notification.userInfo;
//    NSLog(@"handleInterruption info %@",info);
    AVAudioSessionInterruptionType type = 
unsignedIntegerValue]; if ( type == AVAudioSessionInterruptionTypeBegan ) { //任务中断 [self stopPlay]; }else{ //任务开始 AVAudioSessionInterruptionOptions options =
unsignedIntegerValue]; if ( options == AVAudioSessionInterruptionOptionShouldResume ) {//状态恢复 [self startPlay]; } } } //线路变化回调事件 - (void)handleRouteChange:(NSNotification *)notification{ NSDictionary *info = notification.userInfo; AVAudioSessionRouteChangeReason reason =
unsignedIntegerValue]; if ( reason == AVAudioSessionRouteChangeReasonOldDeviceUnavailable ) {//之前播放的设备不能使用 AVAudioSessionRouteDescription *previousRoute = info [AVAudioSessionRouteChangePreviousRouteKey];//获取以前的播放线路 AVAudioSessionPortDescription *previousOutput = previousRoute.outputs[0];//获取线路输出设备 NSString *portType = previousOutput.portType;//线路接口类型 if ( [portType isEqualToString:AVAudioSessionPortHeadphones] ) {//耳机或者耳机输出类型 [self stopPlay];//断开耳机,停止播放 } } if ( reason == AVAudioSessionRouteChangeReasonNewDeviceAvailable ) {//新的设备接入 [self startPlay];//开始播放 } } //更新播放进度条 - (void)updateProgress{ __block typeof(*&self) wself = self; dispatch_async(dispatch_get_main_queue(), ^{ [wself.progressControl setValue:wself->__audioPlayer.currentTime animated:YES]; }); } //音量控制事件 - (void)volumeChange:(UISlider *)slider{ __audioPlayer.volume = slider.value; } //播放时间控制事件 - (void)timeChange:(UISlider *)slider{ __audioPlayer.currentTime = slider.value; } //按钮点击事件 - (void)audioPlay{ if ( !__audioPlayer.isPlaying && !__playButton.selected ) { [self startPlay]; }else{ [self stopPlay]; } } //开始播放 - (void)startPlay{ __block typeof(*&self) wself = self; dispatch_async(dispatch_get_main_queue(), ^{ wself->__playButton.selected = YES; }); [__audioPlayer play]; if ( !self.timer ) { __weak typeof(*&self) wself = self; //设置1s 调用一次,cpu 占用率最低 self.timer = [NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) { [wself updateProgress]; }]; } } //停止播放 - (void)stopPlay{ __block typeof(*&self) wself = self; dispatch_async(dispatch_get_main_queue(), ^{ wself->__playButton.selected = NO; }); [__audioPlayer pause];//暂停 if ( self.timer ) { [self.timer invalidate]; self.timer = nil; } } #pragma mark -- AVAudioPlayerDelegate //播放完成 - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{ if ( flag ) { __playButton.selected = NO; } } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; [[NSNotificationCenter defaultCenter] removeObserver:self]; // Dispose of any resources that can be recreated. } @end
    原文作者:deney
    原文地址: https://segmentfault.com/a/1190000013583816
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞