ios开发之--AVAudioPlayer的应用

时间:2022-06-15 03:26:18

项目当中用到了音频播放器,所以就参考官方文档,写了一个,代码如下:

.h

#import <UIKit/UIKit.h>

@interface hAudioPlayViewController : UIViewController
@property(nonatomic,strong)NSString *titleStr;//音乐名字
@property(nonatomic,strong)NSString *kMusicFile;//音乐文件
@property(nonatomic,strong)NSString *nameStr;//演唱者
@end

.m

#import "hAudioPlayViewController.h"
#import <AVFoundation/AVFoundation.h>

@interface hAudioPlayViewController ()<CustomNavigationBarDelegate,AVAudioPlayerDelegate>

@property (nonatomic,strong) AVAudioPlayer *audioPlayer;//播放器
@property (weak, nonatomic) IBOutlet UIImageView *bgImg;
@property (weak, nonatomic) IBOutlet UILabel *nameLab;
@property (weak, nonatomic) IBOutlet UIButton *playBtn;
@property (weak, nonatomic) IBOutlet UIProgressView *progressV;
@property (weak ,nonatomic) NSTimer *timer;//进度更新定时器
@property (weak, nonatomic) IBOutlet UILabel *timeLab;
@property (assign, nonatomic) BOOL isPlay;

@end

@implementation hAudioPlayViewController


- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    
    self.view.backgroundColor =BackgroundColor;
    CustomNavigationBar *nav  = [[CustomNavigationBar alloc]initWithFrame:CGRectMake(0, 0, KscreenW, NavHeight) withTitle:[NSString stringWithFormat:@"%@",self.titleStr] withLeftBtnHidden:NO withRightBtn:YES];
    nav.delegate = self;
    [self.view addSubview:nav];
    
    self.isPlay = NO;
    [self creatUI];
}

-(void)leftBtnAction:(id)sender
{
    [self.navigationController popViewControllerAnimated:YES];
    [self.audioPlayer pause];
}

-(void)creatUI
{
    self.nameLab.text = self.nameStr;
    [self play];
    self.playBtn.selected = YES;
}

-(NSTimer *)timer{
    if (!_timer) {
        _timer=[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(updateProgress) userInfo:nil repeats:true];
    }
    return _timer;
}

/**
 *  创建播放器
 *
 *  @return 音频播放器
 */
-(AVAudioPlayer *)audioPlayer{
    if (!_audioPlayer) {

        //这段代码是设置声道,防止设备在扬声器的状态下没有声音
        AVAudioSession *audioSession = [AVAudioSession sharedInstance];
        [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
        [audioSession setActive:YES error:nil];  
        
        NSURL *url = [NSURL URLWithString:self.kMusicFile];
        
        //将文件先下载到本地,然后再播放
        NSData *audioData = [NSData dataWithContentsOfURL:url];
        NSString *docDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
        NSString *filePath = [NSString stringWithFormat:@"%@/%@.mp3",docDirPath,@"temp"];
        [audioData writeToFile:filePath atomically:YES];
        
        NSError *error=nil;
        //初始化播放器,注意这里的Url参数只能时文件路径,不支持HTTP Url
        _audioPlayer=[[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL URLWithString:filePath] error:&error];
        //设置播放器属性
        _audioPlayer.numberOfLoops=0;//设置为0不循环
        _audioPlayer.delegate=self;
        [_audioPlayer prepareToPlay];//加载音频文件到缓存
        if(error){
            NSLog(@"初始化播放器过程发生错误,错误信息:%@",error.localizedDescription);
            return nil;
        }
    }
    return _audioPlayer;
}

/**
 *  播放音频
 */
-(void)play{
    if (![self.audioPlayer isPlaying]) {
        [self.audioPlayer play];
        self.timer.fireDate=[NSDate distantPast];//恢复定时器
    }
}

/**
 *  暂停播放
 */
-(void)pause{
    if ([self.audioPlayer isPlaying]) {
        [self.audioPlayer pause];
        self.timer.fireDate=[NSDate distantFuture];//暂停定时器,注意不能调用invalidate方法,此方法会取消,之后无法恢复
        
    }
}

/**
 *  点击播放/暂停按钮
 *
 *  @param sender 播放/暂停按钮
 */
- (IBAction)playClick:(UIButton *)sender {
    sender.selected = !sender.selected;
    
    if (sender.selected==self.isPlay) {
        [self pause];
    }else
    {
        [self play];
    }
}

/**
 *  更新播放进度
 */
-(void)updateProgress{
    float progress= self.audioPlayer.currentTime /self.audioPlayer.duration;
    [self.progressV setProgress:progress animated:true];
    int current = (int)self.audioPlayer.currentTime;
    int duration = (int)self.audioPlayer.duration;
    self.timeLab.text = [NSString stringWithFormat:@"%@/%@",[self timeFormatted:current],[self timeFormatted:duration]];
}

/**
 *  把秒转换为时间格式
 */

-(NSString *)timeFormatted:(int)totalSeconds
{
    int seconds = totalSeconds % 60;
    int minutes = (totalSeconds / 60) % 60;
//    int hours = totalSeconds / 3600;
    
    return [NSString stringWithFormat:@"%02d:%02d",minutes, seconds];
}

#pragma mark - 播放器代理方法
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
    NSLog(@"音乐播放完成...");
}

相关的时间转化,暂停与播放等基本功能已完善,不过没有做其他更精细化的操作,譬如保存进度,第二次进来继续上次的进度播放;快进等操作!

 

附 

官方文档地址:

https://developer.apple.com/documentation/avfoundation/avaudioplayer?language=objc

 

碰到问题,设备在扬声器下没有声音:

1,原因:

没有设置声道;

AVAudioSession是一个单例,无需实例化即可直接使用。AVAudioSession在各种音频环境中起着非常重要的作用

针对不同的音频应用场景,需要设置不同的音频回话分类

2,解决方法:

在初始化AVAudioPlayer之前,设置声道,代码如下:

AVAudioSession *audioSession = [AVAudioSession sharedInstance];
        [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
        [audioSession setActive:YES error:nil];  

 

效果如下:

ios开发之--AVAudioPlayer的应用