美文网首页
音乐播放学习

音乐播放学习

作者: 冷武橘 | 来源:发表于2020-04-19 21:28 被阅读0次

    一、常见音频格式

    WAV文件,WAV文件格式是一种由微软和IBM联合开发的用于音频 数字存储的标准,WAV文件的格式灵活,可以储存多种类型的音频数据。由于文件较大不太适合于移动设备这些存储容量小的设备。

    MP3(MPEG Audio Layer 3)文件,是现在非常流行,MP3是一种有损压缩格式,它尽可能地去掉人耳无法感觉的部分和不敏感的部分。

    CAFF(Core Audio File Format)文件,是苹果开发的专门用于Mac OSX和iOS系统无压缩音频格式。它被设计来替换老的WAV格式。

    AIFF(Audio Interchange File Format)文件,是苹果开发的专门用于Mac OS X系统,是专业的音频文件格式。AIFF的压缩格式是AIFF-C(或AIFC),将数据以4:1压缩率进行压缩,应用于Mac OS X和iOS系统。

    硬件解码器一次只能对一个音频文件解码。在实际应用中通常使用非压缩的音频格式(AIFF)或者CAF音频格式,从而减低系统在音频解码上的消耗,达到省电的目的

    二、播放基本音效

      {
    // 1.获得音效文件的路径
        NSURL *url = [[NSBundle mainBundle] URLForResource:@"m_03.aff" withExtension:nil];
        SystemSoundID soundID = 0;
    
        //2.创建一个sourceID
        AudioServicesCreateSystemSoundID((__bridge CFURLRef _Nonnull)(url), &soundID);
    
    //如果需要在播放完之后执行某些操作,可以调用如下方法注册一个播放完成回调函数
        AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, soundCompleteCallback, NULL);
    
        //3.播放音效
        AudioServicesPlaySystemSound(soundID);
    注意:一个SoundID对应一个音频文件,如果你想播放多个音频文件,需要多个SoundID
    }
    void soundCompleteCallback(SystemSoundID soundID,void * clientData){
        NSLog(@"播放完成...");
    }
    
    //封装一个音效播放工具
    - (void)playSoundWithSoundname:(NSString *)soundname{
        SystemSoundID soundID = 0;
        soundID=[[self.soundIDdictionry objectForKey:soundname]unsignedIntValue];
        if (soundID==0) {
        NSURL *url = [[NSBundle mainBundle] URLForResource:soundname withExtension:nil];
            AudioServicesCreateSystemSoundID(CFBridgingRetain(url), &soundID);
            [self.soundIDdictionry setObject:@(soundID) forKey:soundname];
        }
        // 3.播放音效
        AudioServicesPlaySystemSound(soundID);
    }
    

    使用AudioServicesPlaySystemSound时需要注意:

    1、No longer than 30 seconds in duration
    音频不要超过30s

    2、In linear PCM or IMA4 (IMA/ADPCM) format
    数据必须是PCM或者IMA4格式

    3、Packaged in a .caf, .aif, or .wav file
    音频文件必须打包成.caf、.aif、.wav中的一种

    三、播放音乐

    AVAudioPlayer 是 AVFoundation.framework 中定义的一个类,所以使用要先在工程中引入AVFoundation.framework。我们可以把 AVAudioPlayer看作是一个高级的播放器,它支持广泛的音频格式,主要是以下这些格式:
    AAC、AMR(AdaptiveMulti-Rate, aformatforspeech)、ALAC(AppleLossless)、iLBC(internetLowBitrateCodec, anotherformatforspeech)、 IMA4(IMA/ADPCM)、linearPCM(uncompressed)、 µ-lawanda-law、 MP3(MPEG-1audiolayer3

    //01加载播放路径
        NSURL *url=[[NSBundle mainBundle]URLForResource:@"1201111234.mp3" withExtension:nil];
        NSError *erron=nil;
    //02创建播放器
       self.audionplayer=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:&erron];
    //注意:audioPlayer一定要设置成全局变量,局部变量会被释放
    
       // 03准备播放(缓冲,提高播放的流畅性)
        [self.audionplayer prepareToPlay];
    
       // 04播放音乐
        [self.audionplayer play];
    
     //[self.audioPlayer stop];停止播放  [self.audioPlayer pause];暂停播放
    
        NSLog(@"%@",erron);
    

    1、AVAudioPlayer一次只能播放一个音频文件,所有上一曲、下一曲其实可以通过创建多个播放器对象来完成。
    2、AVAudioPlayer对象需要作为属性或成员变量,要不然会被释放掉。
    3、 [self.audioPlayer stop];停止后,再播放不会从头开始播放。因此需要[self.audioPlayer=nil;手动清空一下
    4、AVAudioPlayer只能播放本地音乐,不能播放网络音乐。

    //封装音乐播放器
    #pragma mark - 播放音乐
    - (void)playMusicWithMusicName:(NSString *)musicName{
        AVAudioPlayer *player=[self.audiodictionry objectForKey:musicName];
        if (player==nil) {//如果取出出来是空,则对应创建对应的播放器
            NSURL *url=[[NSBundle mainBundle]URLForResource:@"1201111234.mp3" withExtension:nil];
            if (url==nil)return;
            NSError *erron=nil;
            //02创建播放器
            player=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:&erron];
            [self.audiodictionry setObject:player forKey:musicName];
        }
        // 03准备播放(缓冲,提高播放的流畅性)
        [player prepareToPlay];
        
        // 04播放音乐
        [player play];
    }
    
    #pragma mark - 暂停音乐
    - (void)pauseMusicWithMusicName:(NSString *)musicName{
         AVAudioPlayer *player=[self.audiodictionry objectForKey:musicName];
        if (player) {
         [player pause];
        }
    }
    #pragma mark - 停止音乐
    - (void)stopMusicWithMusicName:(NSString *)musicName{
         AVAudioPlayer *player=[self.audiodictionry objectForKey:musicName];
        if (player) {
            [player stop];
            player=nil;
            [self.audiodictionry removeObjectForKey:musicName];
        }
    }
    

    四、简单音乐播放器的实现(关键代码)

    @interface AVAudioPlayer: NSObject
    @property(readonly) NSTimeInterval duration; //声音的总时长
    @property NSTimeInterval currentTime;//已播放过的声音时长

    • 1 、播放的进度控制
        UISlider *slider=[[UISlider alloc]init];
        [self.view addSubview:slider];
        self.progressSlider=slider;
        //设置滑块的背景图
        [slider setThumbImage:[UIImage imageNamed:@"player_slider_playback_thumb"] forState:UIControlStateNormal];
        //监听开始拖动
        [slider addTarget:self action:@selector(startchange) forControlEvents:UIControlEventTouchDown];
    
        //监听拖动
        [slider addTarget:self action:@selector(valuechange) forControlEvents:UIControlEventValueChanged];
        
        //监听结束拖动
        [slider addTarget:self action:@selector(endchange:) forControlEvents:UIControlEventTouchUpInside];
    
    #pragma mark - 开始拖动
    - (void)startchange{
        //让之前的定时器失效
        [self.progressTimer invalidate];
        self.progressTimer=nil;
    }
    
    #pragma mark - 拖动滑块调节歌曲进度
    - (void)valuechange{
        // 设置当前播放文字显示的内容
        self.currentTimeLabel.text = [self stringWithTime:self.progressSlider.value * self.currentplayer.duration];
    }
    
    #pragma mark - 结束拖动
    - (void)endchange:(UISlider *)slider{
      //更新播放的时间
      self.currentplayer.currentTime=slider.value*self.currentplayer.duration;
        
       //更新滑块的位置和当前的播放时间显示
      [self updateProgressInfo];
        
      //添加定时器
      [self addProgressTimer];
    }
    
    
    #pragma mark - 添加定时器
    - (void)addProgressTimer
    {
        self.progressTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateProgressInfo) userInfo:nil repeats:YES];
        [[NSRunLoop mainRunLoop] addTimer:self.progressTimer forMode:NSRunLoopCommonModes];
    }
    
    #pragma mark - 更新进度信息
    - (void)updateProgressInfo
    {
        // 1.更新当前时间的Label
        self.currentTimeLabel.text = [self stringWithTime:self.currentplayer.currentTime];
        
        // 2.更新滑块的位置
        self.progressSlider.value = self.currentplayer.currentTime / self.currentplayer.duration;
    }
    
    #pragma mark - 时间格式处理
    -(NSString*)stringWithTime:(NSTimeInterval)time
    {
        NSInteger min = time / 60;
        NSInteger second = (NSInteger)time % 60;
        
        return [NSString stringWithFormat:@"%02ld:%02ld", min, second];
    }
    
    • 2、后台播放
    #pragma mark - 后台播放
    - (void)applicationWillResignActive:(UIApplication *)application {
        
        // 1.获取音频回话
        AVAudioSession *session = [AVAudioSession sharedInstance];
        
        // 2.设置后台播放类别
        [session setCategory:AVAudioSessionCategoryPlayback error:nil];
        
        // 3.激活回话
        [session setActive:YES error:nil];
    }
    
    
    • 3、锁屏播放
    //开始接收远程事件
     [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    
    #pragma mark - 实现远程事件的方法
    // 监听远程事件
    - (void)remoteControlReceivedWithEvent:(UIEvent *)event
    {
        switch (event.subtype) {
            case UIEventSubtypeRemoteControlPlay:
            case UIEventSubtypeRemoteControlPause:
                [self playorpause];
                break;
                
            case UIEventSubtypeRemoteControlNextTrack:
                [self nextmusic];
                break;
                
            case UIEventSubtypeRemoteControlPreviousTrack:
                [self lastmusic];
                break;
                
            default:
                break;
        }
    }
    
    #pragma mark - 设置锁屏界面的信息
     - (void)setupLockScreenInfo
     {
     // 1.获取锁屏界面中心
     MPNowPlayingInfoCenter *playingInfoCenter = [MPNowPlayingInfoCenter defaultCenter];
     
     // 2.设置展示的信息
     NSMutableDictionary *playingInfo = [NSMutableDictionary dictionary];
     [playingInfo setObject:_playingMusic.name forKey:MPMediaItemPropertyAlbumTitle];
     [playingInfo setObject:_playingMusic.singer forKey:MPMediaItemPropertyArtist];
     MPMediaItemArtwork *artWork = [[MPMediaItemArtwork alloc] initWithImage:[UIImage imageNamed:_playingMusic.icon]];
     [playingInfo setObject:artWork forKey:MPMediaItemPropertyArtwork];
         [playingInfo setObject:@(self.currentplayer.duration) forKey:MPMediaItemPropertyPlaybackDuration];
     playingInfoCenter.nowPlayingInfo = playingInfo;
    
     }
    
    • 4、电话中断后播放
    • 5、耳机线控

    相关文章

      网友评论

          本文标题:音乐播放学习

          本文链接:https://www.haomeiwen.com/subject/srnibhtx.html