ios-播放器开发-锁屏、循环播放

#import<AVFoundation/AVFoundation.h>
#import <Foundation/Foundation.h>

@interface AudioTool : NSObject
/**
 *  播放音效
 *
 *  @param filename <#filename description#>
 */
+(void)playSound:(NSString *)filename;
/**
 *  销毁音效
 *
 *  @param filename <#filename description#>
 */
+(void)disposeSound:(NSString *)filename;


/**
 *
 *  播放音乐
 *  @param filename
 */
+(AVAudioPlayer *)playMusic:(NSString *)filename;

/**
 *
 *  暂停音乐
 *  @param filename
 */
+(void)pauseMusic:(NSString *)filename;
/**
 *
 *  停止音乐
 *  @param filename
 */
+(void)stopMusic:(NSString *)filename;

/**
 *  <#Description#>
 */
+(AVAudioPlayer *)currentPlayingAudioPlayer;

@end

#import "AudioTool.h"

//工具类

@implementation AudioTool

//字典 filename:key soudID 作为value

static  NSMutableDictionary *_soundIDDict;

//字典 存放所有的文件的播放器
//filename 作为key audioPlay作为value
static  NSMutableDictionary *_audioPlayDict;

+(void)initialize
{
    _soundIDDict = [NSMutableDictionary dictionary];
    _audioPlayDict = [NSMutableDictionary dictionary];
    
    //设置音频会话类型
    AVAudioSession *session = [AVAudioSession sharedInstance];
    [session setCategory:AVAudioSessionCategorySoloAmbient  error:nil];
    [session setActive:YES error:nil];
}

+(void)playSound:(NSString *)filename
{
   //1.从字典中取出soundID
    if(!filename)return;
    
    SystemSoundID soundID = [_soundIDDict[filename] unsignedIntValue];
    if (!soundID) {
    //加载音效文件
            NSURL *url = [[NSBundle mainBundle]URLForResource:filename withExtension:nil];
        if (!url) {
            return;
        }
        //创建音效ID
        AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url),&soundID);
        _soundIDDict[filename] = @(soundID);
    }
    //播放
    AudioServicesPlaySystemSound(soundID);

}


+(void)disposeSound:(NSString *)filename
{
    if(!filename)return;
    SystemSoundID soundID = [_soundIDDict[filename] unsignedIntValue];
    if (soundID) {
        //销毁音效ID
        AudioServicesDisposeSystemSoundID(soundID);
        //从字典中移除
        [_soundIDDict removeObjectForKey:filename];
    }
}

/**
 *
 *  播放音乐
 *  @param filename
 */
+(AVAudioPlayer *)playMusic:(NSString *)filename
{
    //1.从字典中取出audioPlayer
    if(!filename)return nil;
    
    AVAudioPlayer *audioPlayer  = _audioPlayDict[filename];
    if (!audioPlayer) {
        //加载音乐文件
        NSURL *url = [[NSBundle mainBundle]URLForResource:filename withExtension:nil];
        if (!url) {
            return nil;
        }
        //创建audioPlayer
        audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:nil];
        //缓冲
        [audioPlayer prepareToPlay];
        
        //属性
//        audioPlayer.enableRate = YES;
//        audioPlayer.rate = 20;
        //放入字典
        _audioPlayDict[filename] = audioPlayer;
    }
    //播放
    //[audioPlayer play];
    
    if (!audioPlayer.isPlaying) {
        [audioPlayer play];
    }
    return audioPlayer;
}

/**
 *
 *  暂停音乐
 *  @param filename
 */
+(void)pauseMusic:(NSString *)filename
{
    //1.从字典中取出audioPlayer
    if(!filename)return;
    AVAudioPlayer *audioPlayer  = _audioPlayDict[filename];
    //2.暂停
    if(audioPlayer.isPlaying){
        [audioPlayer pause];
    }
}
/**
 *
 *  停止音乐
 *  @param filename
 */
+(void)stopMusic:(NSString *)filename
{
    //1.从字典中取出audioPlayer
    if(!filename)return;
    AVAudioPlayer *audioPlayer  = _audioPlayDict[filename];
    //2.暂停
    if(audioPlayer.isPlaying){
        [audioPlayer stop];
        
        //直接销毁
        [_audioPlayDict removeObjectForKey:filename];
    }
}

/**
 *  返回当前正在播放的音乐播放器
 */
+(AVAudioPlayer *)currentPlayingAudioPlayer
{
    for(NSString *filename in _audioPlayDict)
    {
        AVAudioPlayer *audioPlayer = _audioPlayDict[filename];
        if(audioPlayer.isPlaying){
            return audioPlayer;
        }

    }
     return nil;
}
@end

//lrc 文件 有时间戳 解析歌词文件

#import "QHMusicViewController.h"
#import "QHMusic.h"
#import <AVFoundation/AVFoundation.h>
#import "AudioTool.h"
#import <MediaPlayer/MediaPlayer.h>

@interface QHMusicViewController ()<AVAudioPlayerDelegate>

@property(nonatomic,strong)NSArray *musicArray;
@property (strong, nonatomic) IBOutlet UITableView *tableView;
@property(nonatomic,strong)AVAudioPlayer *audioPlayer;
@property(nonatomic,strong)CADisplayLink *link;
@property(nonatomic,strong)AVAudioPlayer *currentPlayingAudioPlayer;

@property (strong, nonatomic) IBOutlet UIProgressView *progressView;

- (IBAction)skip:(id)sender;


@end

@implementation QHMusicViewController


- (IBAction)skip:(id)sender
{
    self.currentPlayingAudioPlayer.currentTime = 100;
}
-(NSArray *)musicArray
{
    if (!_musicArray) {
        NSString *path = [[NSBundle mainBundle]pathForResource:@"Musics.plist" ofType:nil];
        NSArray *array = [NSArray arrayWithContentsOfFile:path];
        
        NSMutableArray *objs = [NSMutableArray array];
        
        for(NSDictionary * dict in array)
        {
            QHMusic *music = [QHMusic musicWithDict:dict];
            [objs addObject:music];
        }
        _musicArray = objs;
    }
    return _musicArray;
}

//定时器创建
-(CADisplayLink *)link
{
    if (!_link) {
        self.link = [CADisplayLink displayLinkWithTarget:self selector:@selector(update)];
        
    }
    return _link;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //self.progressView.progress =self.currentPlayingAudioPlayer.currentTime;
}

/**
 *  实时更新(1秒钟60次)
 */
-(void)update{
    //可以在这里更新歌词
    
    //存在问题 一开就调用
    NSLog(@"%f %f",self.currentPlayingAudioPlayer.duration,self.currentPlayingAudioPlayer.currentTime);
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    // Return the number of rows in the section.
    return self.musicArray.count;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    QHMusic *music = self.musicArray[indexPath.row];
    static NSString *cellName = @"cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellName];
    if (!cell) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellName];
    }
    
    cell.imageView.image = [UIImage imageNamed:music.singerIcon];
    cell.textLabel.text = music.name;
    cell.detailTextLabel.text = music.singer;
    
    // Configure the cell...
    
    return cell;
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 100;
}

-(BOOL)prefersStatusBarHidden
{
    return YES;
}

-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
    QHMusic *music = self.musicArray[indexPath.row];
    [AudioTool stopMusic:music.filename];
    NSLog(@"didDeselectRowAtIndexPath:%ld",indexPath.row);
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    //播放音乐
    
    NSLog(@"didSelectRowAtIndexPath:%ld",indexPath.row);
    QHMusic *music = self.musicArray[indexPath.row];
    
    /*
    //创建播放器
    
    NSURL *url = [[NSBundle mainBundle]URLForResource:music.filename withExtension:nil];
    
    //注意这里必须使用全局变量
    AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:nil];
    
    //缓冲(以便后面播放比较流畅)
    
    [audioPlayer prepareToPlay];
    
    //开始播放
    [audioPlayer play];
    
    self.audioPlayer = audioPlayer;
    */
    
    
    AVAudioPlayer *audioPlay = [AudioTool playMusic:music.filename];
    audioPlay.delegate = self;
    self.currentPlayingAudioPlayer =  audioPlay;
    NSLog(@"%@-------",music.filename);
    
//    if (NSClassFromString(@"MPNowPlayingInfoCenter")) {
    
    //只能显示图片 
    //在锁屏界面显示歌曲信息 单例

    
//}

    //在锁屏界面显示歌曲信息
    [self showInfoInLockedScreen:music];
    //在主线程执行
    //开始工作
    [self.link invalidate];//将以前的定时器给停掉
    self.link = nil;//清空 调用get方法 创建
    [self.link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

}

-(void)showInfoInLockedScreen:(QHMusic *)music
{
    NSMutableDictionary *info = [NSMutableDictionary dictionary];
    //标题
    info[MPMediaItemPropertyTitle] = music.name;
    
    //作者
    
    info[MPMediaItemPropertyArtist] = music.singer;
    
    //专辑
    info[MPMediaItemPropertyAlbumArtist] = music.singer;
    //图片
    info[MPMediaItemPropertyArtwork]= [[MPMediaItemArtwork alloc]initWithImage:[UIImage imageNamed:music.icon]];
    
    [MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = info;
}

#pragma mark - AVAudioPlayerDeleagate

-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
    //计算下一行
    NSIndexPath * selectedPath = [self.tableView indexPathForSelectedRow];
    int nextRow = selectedPath.row +1;
    if (nextRow == self.musicArray.count) {
        nextRow = 0;
    }

    NSIndexPath *currentpath = [NSIndexPath indexPathForRow:nextRow inSection:selectedPath.section];
    
    //播放下一首
    [self.tableView selectRowAtIndexPath:currentpath animated:YES scrollPosition:UITableViewScrollPositionTop];
    [self tableView:self.tableView didSelectRowAtIndexPath:currentpath];
    
}


#pragma mark -AVAudioPlayerDelegate
/**
 *  音乐播放器被打断(打电话 接电话)
 *
 *  @param player <#player description#>
 */
-(void)audioPlayerBeginInterruption:(AVAudioPlayer *)player
{
    NSLog(@"audioPlayerBeginInterruption-被打断");
}
/**
 *  音乐播放器停止打断
 *
 *  @param player <#player description#>
 */
-(void)audioPlayerEndInterruption:(AVAudioPlayer *)player
{
    //真机调试
    NSLog(@"audioPlayerEndInterruption-停止打断");
    [player play];
}

@end

你可能感兴趣的:(定时器,delegate,音乐,循环播放,锁屏)