iOS播放音乐

http://www.jianshu.com/p/ce279bc773dd

iOS播放音乐、后台播放、控制台控制相关的一些TIPS,基于StreamingKit

字数963 阅读595 评论0 喜欢9

首先给大家放一个StreamingKit的链接

简单的播放使用例子,可以看开源作者的演示demo。

由于整个播放器涉及到UI啊数据啊比较多,所以就不全抠下来当demo了,就在这里列一点TIPS,希望能帮助到大家。

歌曲播放形式我是这么写的:

.h里:
/**
 歌曲播放形式
 */
typedef enum : NSUInteger {
    MBAudioPlayTypeCircle,  //循环播放
    MBAudioPlayTypeRandom,  //随机播放
    MBAudioPlayTypeOneMusic,//单曲循环
    MBAudioPlayTypeNoNext,  //播完就不播了
} MBAudioPlayType;

.m里:

/**
 *  下一首
 */
- (void)playNextMusic
{
 switch (self.playType) {
        case MBAudioPlayTypeCircle:
        {
            //循环播放
            _nowMusicLocal++;
            if (_nowMusicLocal >= [self allLocal]) {
                _nowMusicLocal = 0;
            }
            [self playMusic];

        }
            break;
        case MBAudioPlayTypeRandom:
        {
            //随机播放
            [self randomWithTimes:5];

            if (_nowMusicLocal >= [self allLocal]) {
                _nowMusicLocal = 0;
            }
            [self playMusic];

        }
            break;
        case MBAudioPlayTypeOneMusic:
        {
            //单曲循环
            [self playMusicWithInfo];
        }
            break;
        case MBAudioPlayTypeNoNext:
        {
            //播完就不播了

        }
            break;
        default:
            break;
    }

}

#pragma mark - 随机播放随机数
/**
 *  随机递归
 *
 *  @param num 递归次数
 */
-(void)randomWithTimes:(NSInteger)num
{
    NSInteger randomMusic = arc4random() % [self allLocal];

    DLog(@"随机值为:%ld",(long)randomMusic);

    if (_nowMusicLocal == randomMusic && [self allLocal] != 1) {
        //防止递归死循环
        if (num != 0) {
            num--;
            [self randomWithTimes:num];
            return;
        }else
        {
            randomMusic++;
            //递归多次还一样,就强行设一个了(低概率事件)
            _nowMusicLocal = randomMusic;
        }
    }
    else
    {
        //正常情况
        _nowMusicLocal = randomMusic;
    }
}

这个随机算法写的其实挺搓的,不过勉强能用吧。。。

获取后台播放权限

在target-capabilities-background modes 开启 audio and airplay

在AppDelegate中

#import
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    xxxxx;

NSError* error;
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&error];
}

###漏掉最重要的了,在程序挂起的时候,要手动加权限的,

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

    DLog(@"\n\n倔强的打出一行字告诉你我要挂起了。。\n\n");

//MBAudioPlayer是我为播放器写的单例,这段就是当音乐还在播放状态的时候,给后台权限,不在播放状态的时候,收回后台权限
    if ([MBAudioPlayer shareInstance].audioPlayer.state == STKAudioPlayerStatePlaying||[MBAudioPlayer shareInstance].audioPlayer.state == STKAudioPlayerStateBuffering||[MBAudioPlayer shareInstance].audioPlayer.state == STKAudioPlayerStatePaused ||[MBAudioPlayer shareInstance].audioPlayer.state == STKAudioPlayerStateStopped) {
        //有音乐播放时,才给后台权限,不做流氓应用。
        [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
        [self becomeFirstResponder];
        //开启定时器
        [[MBAudioPlayer shareInstance] decideTimerWithType:MBAudioTimerStartBackground andBeginState:YES];
        [[MBAudioPlayer shareInstance] configNowPlayingInfoCenter];
    }
    else
    {
        [[UIApplication sharedApplication] endReceivingRemoteControlEvents];
        [self resignFirstResponder];
        //检测是都关闭定时器
        [[MBAudioPlayer shareInstance] decideTimerWithType:MBAudioTimerStartBackground andBeginState:NO];
    }
}

锁屏时,更新控制台、锁屏信息(定时器调用)

#pragma mark - 锁屏控制

/**
 *  设置锁屏信息
 */
-(void)configNowPlayingInfoCenter
{

    if (self.nowPlayingMusicInfo == nil) {
        return;
    }

    @autoreleasepool {

        NSDictionary *info = self.nowPlayingMusicInfo;

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

        //歌曲名称
        [dict setObject:[info ObjectNullForKey:@"title"] forKey:MPMediaItemPropertyTitle];

        //演唱者
        [dict setObject:[info ObjectNullForKey:@"author"] forKey:MPMediaItemPropertyArtist];

        //专辑名
        //[dict setObject:[info ObjectNullForKey:@"album"] forKey:MPMediaItemPropertyAlbumTitle];

        //专辑缩略图
        NSString *imagePath = [info ObjectNullForKey:@"thumb"];
        imagePath = [NSString stringWithFormat:@"EGOImageLoader-%lu", (unsigned long)[[imagePath description] hash]];
        NSString *imageLocalPath = [NSString stringWithFormat:@"%@/%@", EGOCacheDirectory(),imagePath];

        NSData * thumbData = [NSData dataWithContentsOfFile:imageLocalPath];

        if (thumbData != nil) {
            UIImage *image = [UIImage imageWithData:thumbData];
            MPMediaItemArtwork *artwork = [[MPMediaItemArtwork alloc] initWithImage:image];
            [dict setObject:artwork forKey:MPMediaItemPropertyArtwork];
        }else
        {
            // FIXME: 无图的时候,读取图

        }
        //音乐剩余时长
        [dict setObject:[NSNumber numberWithDouble:self.audioPlayer.duration] forKey:MPMediaItemPropertyPlaybackDuration];

        //音乐当前播放时间 在计时器中修改
        [dict setObject:[NSNumber numberWithDouble:self.audioPlayer.progress] forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime];

        //设置锁屏状态下屏幕显示播放音乐信息
        //DLog(@"显示播放音乐信息:%@\n%@",dict,[info ObjectNullForKey:@"title"]);

        [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:dict];

    }

}

/**
 *  响应远程音乐播放控制消息
 *
 *  @param receivedEvent
 */
- (void)remoteControlReceivedWithEvent:(UIEvent *)receivedEvent {

    if (receivedEvent.type == UIEventTypeRemoteControl) {

        switch (receivedEvent.subtype) {

            case UIEventSubtypeRemoteControlPause:
                //点击了暂停
                [self pauseStreamer];
                break;
            case UIEventSubtypeRemoteControlNextTrack:
                //点击了下一首
                [self playNextMusic];
                break;
            case UIEventSubtypeRemoteControlPreviousTrack:
                //点击了上一首
                [self playPreMusic];
                //此时需要更改歌曲信息
                break;
            case UIEventSubtypeRemoteControlPlay:
                //点击了播放
                [self pauseStreamer];
                break;
            default:
                break;
        }
    }
}

最后,那些在锁屏中带歌词的产品么,据说是不停的的把歌词和专辑图片结合在一起,然后根据歌词时间刷新图片。。。如果有这个产品需求,可以按这个思路来做。。

推荐拓展阅读

喜欢

9

时间: 2024-11-05 14:48:05

iOS播放音乐的相关文章

IOS播放音乐和音效

1.播放音效 1.1 首先获取到音效文件路径 1 NSString *path = [[NSBundle mainBundle] pathForResource:soundFileName ofType:nil]; 1.2 将音效文件路径转换为NSURL NSURL *url = [NSURL fileURLWithPath:path]; 1.3 加载音效文件,并返回SystemSoundID(用于播放此音效) SystemSoundID soundId ; //如下方式是C语言的框架,是将音频

iOS开发-音乐播放

现在的各种App大行其道,其实常用也就是围绕着吃喝玩乐基本的需求,视频,音乐在智能手机出现之前更是必不可少的功能,每个手机都会有一个自带的音乐播放器,当然公众也有自己的需求所以也就造就了各种音乐播放软件,自己下午闲来无事简单的写了一个随机播放音乐的Demo,iOS中有三种播放音频的方式AVAudioPlayer.音频服务.音频队列.另外两种暂时没有用到,就简单的练手了一下AVAudioPlayer,还是开始正题吧: 1.新建项目或者在原有项目重新弄一个页面,先看页面: 2.导入几首自己喜欢的歌曲

ios 视频音乐播放

IOS开发小技巧(视频和音乐播放)1.IOS视频播放代码(添加MediaPlayer.framework和#import) -(void)playMovie:(NSString *)fileName{ //视频文件路径 NSString *path = [[NSBundle mainBundle] pathForResource:fileName ofType:@"mp4"]; //视频URL NSURL *url = [NSURL fileURLWithPath:path]; //视

Android 4.3实现类似iOS在音乐播放过程中如果有来电则音乐声音渐小铃声渐大的效果

目前Android的实现是:有来电时,音乐声音直接停止,铃声直接直接使用设置的铃声音量进行铃声播放. Android 4.3实现类似iOS在音乐播放过程中如果有来电则音乐声音渐小铃声渐大的效果. 如果要实现这个效果,首先要搞清楚两大问题: 1.来电时的代码主要实现流程. 2.主流音乐播放器在播放过程中,如果有来电,到底在收到了什么事件后将音乐暂停了? 一:来电时的代码主要实现流程 我不是第一研究来电代码的人,网上已经有高手对这个流程剖析过,不是不完全符合我的要求,我参考过的比较有价值的是如下两个

IOS后台播放音乐

IOS后台播放音乐 博客分类: IOS http://www.apple.com.cn/developer/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/AudioandVideoTechnologies/AudioandVideoTechnologies.html#//apple_ref/doc/uid/TP40007072-CH19-SW32 1.首先在工程中导入播放音乐所使用的框架:AV Fo

IOS 后台运行 播放音乐

iOS 4开始引入的multitask,我们可以实现像ipod程序那样在后台播放音频了.如果音频操作是用苹果官方的AVFoundation.framework实现,像用AvAudioPlayer,AvPlayer播放的话,要实现完美的后台音频播放,依据app的功能需要,可能需要实现几个关键的功能. 首先,播放音频之前先要设置AVAudioSession模式,通常只用来播放的App可以设为AVAudioSessionCategoryPlayback即可.模式意义及其他模式请参考文档. 1 //后台

iOS开发—音乐的播放

iOS开发—音乐的播放 一.简单说明 音乐播放用到一个叫做AVAudioPlayer的类,这个类可以用于播放手机本地的音乐文件. 注意: (1)该类(AVAudioPlayer)只能用于播放本地音频. (2)时间比较短的(称之为音效)使用AudioServicesCreateSystemSoundID来创建,而本地时间较长(称之为音乐)使用AVAudioPlayer类. 二.代码示例 AVAudioPlayer类依赖于AVFoundation框架,因此使用该类必须先导入AVFoundation框

ios设置音乐audio自动播放

因为audio标签的自动播放:autoplay.在ios系统中不能自动播放,此时需要设置,在进入页面自动播放音乐. 第一步,先引入js微信 <script src="js/jweixin-1.2.0.js?ver=222"></script> 第二步,在wx.ready中进行默认播放,这个时候wx.config配置可以不用正确,但是后边的ready也可以用,所以默认播放了. //ios中音乐默认不能播放,配置在wx.ready中进行默认播放, function

iOS 后台播放音乐

//后台播放音乐 -(void)playAudio{ dispatch_queue_t dispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(dispatchQueue, ^(void) { NSError *audioSessionError = nil; AVAudioSession *audioSession = [AVAudioSession shared