项目当中用到了音频播放器,所以就参考官方文档,写了一个,代码如下:
.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];
效果如下: