#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