基于AVPlayer的音乐播放器

1,最近写了一个关于音乐播放器的demo,查阅资料的过程中,学会不少新东西。简单记录一下写的过程中遇到问题,备忘。

2,为了方便使用,将播放器写成单例  .h

先导入需要的库

#import <AudioToolbox/AudioToolbox.h>

#import <AVFoundation/AVFoundation.h>

#import <objc/runtime.h>

生成一个播放器的实例

@property (nonatomic,strong) AVPlayer *AVplay;

@property (nonatomic,strong) AVPlayerItem *AVItem;

3, 在.m文件中实现方法

AVplay = [[AVPlayer alloc] init];

添加播放完成的通知

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:AVplay.currentItem];

-(void)playbackFinished:(NSNotification *)notification{

    /*

  播放完成后的操作在这里进行,比如播放下一曲

  */

}

4,初始化播放的链接

    AVItem = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:url]];

    [AVplay replaceCurrentItemWithPlayerItem:AVItem];

5,点击播放按钮,控制播放和暂停

    _isPlaying = !_isPlaying;

    if (_isPlaying) {

        [self resume]; // 开始/继续 播放

    }else{

        [self pause]; // 暂停

   }

- (void)resume{

    [AVplay play];

}

- (void)pause{

    [AVplay pause];

 }

6,上一曲、下一曲 调用4的方法,AVItem重新赋值

7,获得当前播放的进度,赋值给进度条

-(float)progress{

    float percentage = (CMTimeGetSeconds(AVplay.currentItem.currentTime)/CMTimeGetSeconds(AVplay.currentItem.duration));

    return percentage;

}

8,获得进度条移动后的值,调整播放的进度

-(void)moveToSection:(CGFloat)section{

    int32_t timeScale = AVplay.currentItem.asset.duration.timescale;

    Float64 playerSection = CMTimeGetSeconds(AVplay.currentItem.duration) * section;

    [AVplay seekToTime:CMTimeMakeWithSeconds(playerSection, timeScale) toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];

}

9,为了实现后台播放

    // 后台播放 设置 音频会话类型

//需要 导入头文件  #import <AVFoundation/AVFoundation.h>

    AVAudioSession *session = [AVAudioSession sharedInstance];

    NSError *setCategoryError = nil;

    BOOL success = [session setCategory:AVAudioSessionCategoryPlayback error:&setCategoryError];

    if (!success)

    {

        return;

    }

    NSError *activationError = nil;

    success = [session setActive:YES error:&activationError];

    if (!success)

    {

        return;

    }

同时还要再info.plist文件中找到 Required background modes 这一行,添加key值 选择App plays audio or streams audio/video using AirPlay

10,为了实现锁屏时显示播放信息

- (void)applicationDidEnterBackground:(UIApplication *)application {

    // 让应用在后台运行

    [application beginBackgroundTaskWithExpirationHandler:nil];

    // 为了显示锁屏状态下的内容

    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

    [self becomeFirstResponder]; // 相应事件 

    //刚进入后台时刷新一下锁屏内容

    [[PlayManager sharedInstance] configPlayingInfo];

}

//判断时间类型

- (void)remoteControlReceivedWithEvent:(UIEvent *)event

{

    if (event.type == UIEventTypeRemoteControl) {

        switch (event.subtype) {

            case UIEventSubtypeRemoteControlPlay:

                [[PlayManager sharedInstance] resume]; // 播放

                break;

                

            case UIEventSubtypeRemoteControlPause:

                [[PlayManager sharedInstance] pause];//暂停

                break;

                

            case UIEventSubtypeRemoteControlPreviousTrack:

                [[PlayManager sharedInstance] last]; // 播放上一曲按钮

                break;

                

            case UIEventSubtypeRemoteControlNextTrack:

                [[PlayManager sharedInstance] next]; // 播放下一曲按钮

                break;

                

            default:

                break;

        }

    }

}

//进入前台后取消相应

- (void)applicationWillEnterForeground:(UIApplication *)application {

   [[UIApplication sharedApplication] endReceivingRemoteControlEvents];

    [self resignFirstResponder];

}

11,锁屏显示的内容的方法

- (void)configPlayingInfo{

    if (_currentModel!=nil) {

        if (NSClassFromString(@"MPNowPlayingInfoCenter")) {

            NSMutableDictionary *dict = [[NSMutableDictionary alloc]init];

            [dict setObject:_currentModel.title forKey:MPMediaItemPropertyTitle];//歌曲名设置

            [dict setObject:_currentModel.source_name forKey:MPMediaItemPropertyArtist];//歌手名设置

            [dict setObject:[[MPMediaItemArtwork alloc] initWithImage:[UIImage imageNamed:@"car"]]  forKey:MPMediaItemPropertyArtwork];//专辑图片设置

            [dict setObject:[NSNumber numberWithDouble:CMTimeGetSeconds(AVplay.currentItem.currentTime)] forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime]; //音乐当前已经播放时间

            [dict setObject:[NSNumber numberWithFloat:1.0] forKey:MPNowPlayingInfoPropertyPlaybackRate];//进度光标的速度 (这个随 自己的播放速率调整,我默认是原速播放)

            [dict setObject:[NSNumber numberWithDouble:CMTimeGetSeconds(AVplay.currentItem.duration)] forKey:MPMediaItemPropertyPlaybackDuration];//歌曲总时间设置

            [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:dict];

        }

        [atWorkImg sd_setImageWithURL:[NSURL URLWithString:_currentModel.cover_url] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {

  //锁屏状态下显示的图片是网络的,下载完再切换,否则会出现问题

            NSDictionary *dic = [[MPNowPlayingInfoCenter defaultCenter] nowPlayingInfo];

            NSMutableDictionary *muDic = [[NSMutableDictionary alloc] initWithDictionary:dic];

            [muDic setObject:[[MPMediaItemArtwork alloc] initWithImage:atWorkImg.image]  forKey:MPMediaItemPropertyArtwork];

            [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:muDic];

        }];

    }

}

// 暂时没有对打断事件的处理

原文地址:https://www.cnblogs.com/GaoSir/p/4466516.html