需求:在后台播放音频,特别是在直播间或录歌模式下播放音频的时候,只希望后台播放,并不希望后台控制。这里主要是针对这一问题的解决。
代码部分:
.h文件
//控制中心
//在后台播放音频文件,特别是在直播间或录歌模式下播放音频的时候,只希望后台播放,并不希望后台控制
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
typedef enum : NSUInteger {
NoneEnabled, //没有可用
OnlyCenterButton, //仅中间按钮显示
AllEnabled, //所有按钮都可用
} BackstageCtrlType;
typedef enum : NSUInteger {
CenterButtonPlay, //播放按钮 ▶️
CenterButtonPause, //暂停按钮 ⏸
PreviousButton, //左边按钮 ⏮
NextButton, //右边按钮 ⏭
} BackstageButtonType;
/**
后台按钮点击回调
@param buttonType 按钮类型
*/
typedef void(^BackstageButtonBlock)(BackstageButtonType buttonType);
@interface ControlCenter : NSObject
/**
控制中心
@return 控制中心单例
*/
+(instancetype)shareControlCenter;
/**
开启后台对音频的控制
*/
-(void)openBackstageControlAudio;
/**
配置后台按钮
@param type 后台按钮类型
*/
-(void)configBackstageAudioButtons:(BackstageCtrlType)type;
/**
本地音频文件时长
@param fileUrl 路径
@return 时长
*/
-(float)audioSoundDuration:(NSURL *)fileUrl;
/**
配置控制中心歌曲信息
@param title 歌曲名
@param artist 歌手
@param duration 播放时长
@param artwork 图片
*/
-(void)configControlCenterSongInfo:(NSString *)title artist:(NSString *)artist playbackDuration:(double)duration artwork:(UIImage *)artwork;
/**
后台按钮点击回调
*/
@property(nonatomic,copy)BackstageButtonBlock buttonCilckBlock;
@end
.m文件
#import "ControlCenter.h"
#import <AVFoundation/AVFoundation.h>
#import <MediaPlayer/MediaPlayer.h>
@implementation ControlCenter
static ControlCenter *_instance; //创建静态对象,防止外界访问
#pragma mark - system method
+(instancetype)allocWithZone:(struct _NSZone *)zone{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (_instance == nil) {
_instance = [super allocWithZone:zone];
}
});
return _instance;
}
#pragma mark - public method
+(instancetype)shareControlCenter{
return [[self alloc]init];
}
-(void)openBackstageControlAudio{
//设置后台播放音频
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setActive:YES error:nil];
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
//开启响应后台控制
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
}
-(void)configBackstageAudioButtons:(BackstageCtrlType)type{
//注意:只有添加响应事件之后,在控制中心才会显示按钮;中间按钮暂停和播放都要添加事件
MPRemoteCommand *playButton = [[MPRemoteCommandCenter sharedCommandCenter] playCommand]; //播放
MPRemoteCommand *pauseButton = [[MPRemoteCommandCenter sharedCommandCenter] pauseCommand]; //暂停
MPRemoteCommand *nextButton = [[MPRemoteCommandCenter sharedCommandCenter] nextTrackCommand]; //下一首
MPRemoteCommand *previousButton = [[MPRemoteCommandCenter sharedCommandCenter] previousTrackCommand]; //上一首
playButton.enabled = YES;
pauseButton.enabled = YES;
nextButton.enabled = YES;
previousButton.enabled = YES;
[playButton removeTarget:self action:@selector(playAction:)];
[pauseButton removeTarget:self action:@selector(pauseAction:)];
[nextButton removeTarget:self action:@selector(nextAction:)];
[previousButton removeTarget:self action:@selector(previousAction:)];
switch (type) {
case NoneEnabled:
playButton.enabled = NO;
pauseButton.enabled = NO;
[playButton addTarget:self action:@selector(playAction:)];
[pauseButton addTarget:self action:@selector(pauseAction:)];
break;
case OnlyCenterButton:
playButton.enabled = YES;
pauseButton.enabled = YES;
[playButton addTarget:self action:@selector(playAction:)];
[pauseButton addTarget:self action:@selector(pauseAction:)];
break;
case AllEnabled:
[playButton addTarget:self action:@selector(playAction:)];
[pauseButton addTarget:self action:@selector(pauseAction:)];
[nextButton addTarget:self action:@selector(nextAction:)];
[previousButton addTarget:self action:@selector(previousAction:)];
break;
default:
break;
}
}
-(float)audioSoundDuration:(NSURL *)fileUrl{
NSDictionary *options = @{AVURLAssetPreferPreciseDurationAndTimingKey: @YES};
AVURLAsset *audioAsset = [AVURLAsset URLAssetWithURL:fileUrl options:options];
CMTime audioDuration = audioAsset.duration;
float audioDurationSeconds = CMTimeGetSeconds(audioDuration);
return audioDurationSeconds;
}
-(void)configControlCenterSongInfo:(NSString *)title artist:(NSString *)artist playbackDuration:(double)duration artwork:(UIImage *)artwork{
//注意: 如果你没配置歌曲信息,点击暂停,锁屏状态下的控制中心界面消失
NSMutableDictionary *infoDic = [NSMutableDictionary dictionary];
if (title.length) { //设置歌曲题目
[infoDic setObject:title forKey:MPMediaItemPropertyTitle];
}
if (artist.length) { //设置歌手名
[infoDic setObject:artist forKey:MPMediaItemPropertyArtist];
}
if (duration) { //设置播放时间
[infoDic setObject:[NSNumber numberWithDouble:duration] forKey:MPMediaItemPropertyPlaybackDuration];
}
if (artwork) { //设置显示的图片
[infoDic setObject:artwork forKey:MPMediaItemPropertyArtwork];
}
[[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:infoDic];
}
#pragma mark - private method
-(void)playAction:(MPRemoteCommandEvent *)event{
if (_buttonCilckBlock) {
_buttonCilckBlock(CenterButtonPlay);
}
}
-(void)pauseAction:(MPRemoteCommandEvent *)event{
if (_buttonCilckBlock) {
_buttonCilckBlock(CenterButtonPause);
}
}
-(void)previousAction:(MPRemoteCommandEvent *)event{
if (_buttonCilckBlock) {
_buttonCilckBlock(PreviousButton);
}
}
-(void)nextAction:(MPRemoteCommandEvent *)event{
if (_buttonCilckBlock) {
_buttonCilckBlock(NextButton);
}
}
@end
调用:
[[ControlCenter shareControlCenter]openBackstageControlAudio];
[[ControlCenter shareControlCenter]configBackstageAudioButtons:NoneEnabled];
[ControlCenter shareControlCenter].buttonCilckBlock = ^(BackstageButtonType type){
switch (type) {
case CenterButtonPlay:
[self playOrParseMusic:YES];
break;
case CenterButtonPause:
[self playOrParseMusic:NO];
break;
case PreviousButton:
_playerIndex--;
if (_playerIndex<0) {
_playerIndex = _playerDataArr.count-1;
}
[self prepareAndPlayMusic:_playerDataArr[_playerIndex]];
break;
case NextButton:
_playerIndex++;
if (_playerIndex>(_playerDataArr.count-1)) {
_playerIndex = 0;
}
[self prepareAndPlayMusic:_playerDataArr[_playerIndex]];
break;
default:
break;
}
};
期待你的评论建议O(∩_∩)O~