zoukankan      html  css  js  c++  java
  • ios开发之--AVAudioPlayer/AVPlayer的应用

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

    .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];  

    效果如下:

    上面描述的是AudioPlayer的用法,下面说下AVPlayer的用法,他们两直接的区别如果同时播放音频的话,AudioPlayer比较适合播放本地的文件,而AVPlayer则可以播放在线的音频文件,当然也可以播放视频文件,这里先不说,比较简单,代码如下:

    #import "hAVPlayerViewController.h"
    #import <AVFoundation/AVFoundation.h>
    
    @interface hAVPlayerViewController ()<CustomNavigationBarDelegate>
    @property (weak, nonatomic) IBOutlet UILabel *titleLab;
    @property (weak, nonatomic) IBOutlet UIButton *playBtn;
    @property (weak, nonatomic) IBOutlet UILabel *timeLab;
    @property (assign, nonatomic) BOOL isPlay;//用来标记是否播放
    @property (weak, nonatomic) IBOutlet UIProgressView *progress;
    
    //播放器
    @property (nonatomic,strong)AVPlayer *avPlayer;
    
    //监控进度
    @property (nonatomic,strong)NSTimer *avTimer;
    
    @property (weak, nonatomic) IBOutlet NSLayoutConstraint *imgTop;
    
    @end
    
    @implementation hAVPlayerViewController
    
    - (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.model.title] withLeftBtnHidden:NO withRightBtn:YES];
        nav.delegate = self;
        [self.view addSubview:nav];
        
        self.imgTop.constant = NavHeight;
        
        self.isPlay = NO;
        
        //mp3播放网址
        NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@",self.model.music_url]];
        
        //播放器初始化
        self.avPlayer = [[AVPlayer alloc]initWithURL:url];
       /*
        //设置播放器初始音量
        self.avPlayer.volume =1;
        
        //初始0音量
        self.volume.value =5.0f;
        
        //设置最大值最小值音量
        self.volume.maximumValue =10.0f;
        
        self.volume.minimumValue =0.0f;
    */
        
        //监控播放进度
        self.avTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(timer) userInfo:nil repeats:YES];
    
        self.titleLab.text = [NSString stringWithFormat:@"%@",self.model.title];
        self.playBtn.selected = YES;
        
        [self.avPlayer play];
    }
    
    -(void)leftBtnAction:(id)sender
    {
        [self.avPlayer pause];
        [self.navigationController popViewControllerAnimated:YES];
    }
    
    //监控播放进度方法
    - (void)timer
    {
        float progress= CMTimeGetSeconds(self.avPlayer.currentItem.currentTime) / CMTimeGetSeconds(self.avPlayer.currentItem.duration);
        [self.progress setProgress:progress animated:true];
        int current = (int)CMTimeGetSeconds(self.avPlayer.currentItem.currentTime);
        int duration = CMTimeGetSeconds(self.avPlayer.currentItem.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];
    }
    
    
    //播放/暂停
    - (IBAction)play:(id)sender {
        
        UIButton *btn = (UIButton *)sender;
        
        btn.selected = !btn.selected;
        
        if (btn.selected == self.isPlay) {
            [self.avPlayer pause];
        }else{
            [self.avPlayer play];
        }
    }

    仅做记录!

  • 相关阅读:
    java.lang.NoSuchMethodError: org.json.JSONArray.iterator()Ljava/util/Iterator 阿里云短信
    iframe高度自适应
    jQuery中的事件——《锋利的JQuery》
    jQuery中的DOM操作——《锋利的JQuery》
    JQuery选择器——《锋利的JQuery》
    JS的从理解对象到创建对象
    JS键盘事件对象之keyCode、charCode、which属性对比
    JS事件及其兼容用法
    JS中函数参数值传递和引用传递
    JS之DOM那些事
  • 原文地址:https://www.cnblogs.com/hero11223/p/9157316.html
Copyright © 2011-2022 走看看