原文位址:https://www.zybuluo.com/kezhen/note/136614
一、使用AVAudioPlayer播放音樂
1. Background Modes
打開背景模式的音樂播放,或者在info.plist檔案中添加
Required Background Modes
鍵,其值是
App plays audio or streams audio/video using AirPlay
2. 添加背景播放代碼
- AVAudioSession *session = [AVAudioSession sharedInstance];
-
- [session setActive:YES error:nil];
-
- [session setCategory:AVAudioSessionCategoryPlayback error:nil];
3. 播放指定的音頻檔案
- // 1.擷取要播放音頻檔案的URL
- NSURL *fileURL = [[NSBundle mainBundle]URLForResource:@"王力宏-流淚手心" withExtension:@".mp3"];
-
- // 2.建立 AVAudioPlayer 對象
- self.audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:fileURL error:nil];
-
- // 3.列印歌曲資訊
- NSString *msg = [NSString stringWithFormat:@"音頻檔案聲道數:%ld\n 音頻檔案持續時間:%g",self.audioPlayer.numberOfChannels,self.audioPlayer.duration];
- NSLog(@"%@",msg);
-
- // 4.設定循環播放
- self.audioPlayer.numberOfLoops = -1;
- self.audioPlayer.delegate = self;
-
- // 5.開始播放
- [self.audioplayer play];
二、使用System Sound Services播放音頻
利用 System Sound Services
隻能播放一些很小的提示或警告音頻,它存在諸多限制,例如:聲音長度不能超過30秒,不能控制進度,格式支援少等。
1. 注冊音頻檔案
調用
AudioServicesCreateSystemSoundID(CFURLRef inFileURL,SystemSoundID *outSystemSoundID)
該函數的第一個參數代表音頻檔案的URL(可通過NSURL轉換成CFURLRef),第二個參數代表注冊音頻檔案的SystemSoundID。
2. 在音頻播放完執行某些操作
調用
AudioServicesAddSystemSoundCompletion()
函數為制定SystemSoundID注冊Callback函數。
3. 播放音頻
調用
AudioServicePlaySystemSound
函數或者
AudioServicePlayAlertSound
(調用系統振動功能)。
4. 實戰
- #import "FKViewController.h"
- static void completionCallback(SystemSoundID mySSID)
- {
- // Play again after sound play completion
- AudioServicesPlaySystemSound(mySSID);
- }
- @implementation ViewController
- // 音頻檔案的ID
- SystemSoundID ditaVoice;
-
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- // 1. 定義要播放的音頻檔案的URL
- NSURL *voiceURL = [[NSBundle mainBundle]URLForResource:@"CleanDidFinish" withExtension:@"aiff"];
-
- // 2. 注冊音頻檔案(第一個參數是音頻檔案的URL 第二個參數是音頻檔案的SystemSoundID)
- AudioServicesCreateSystemSoundID((__bridge CFURLRef)(voiceURL),&ditaVoice);
-
- // 3. 為crash播放完成綁定回調函數
- AudioServicesAddSystemSoundCompletion(ditaVoice,NULL,NULL,(void*)completionCallback,NULL);
-
- // 4. 播放 ditaVoice 注冊的音頻 并控制手機震動
- AudioServicesPlayAlertSound(ditaVoice);
-
- // AudioServicesPlaySystemSound(ditaVoice);
- // AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); // 控制手機振動
- }
使用需要
System Sound Services
架構的支援,需要導入其主頭檔案:
AudioToolbox
#import<AudioToolbox/AudioToolbox.h>
三、使用 MPMusicPlayerController
控制本機音樂播放
MPMusicPlayerController
對控制内置音樂庫播放狀态以及媒體資訊的擷取進行了封裝,主要用于公司手環端藍牙發送指令控制手機音樂播放以及在手環熒幕上顯示歌曲名稱。
下面介紹一下用法:
1. 包含我封裝的頭檔案
2. 遵守協定:
#import "BackgroundMusic.h"
3. 初始化:
achieveMusicInfoDelegate
- @property (nonatomic,strong) BackgroundMusic *musicController;
- self.musicController = [[BackgroundMusic alloc]init];
- self.musicController.delegate = self; // 設定目前控制器為代理
4. 監聽媒體曲目的改變:
- // 在 - (void)viewDidLoad 方法中調用以下方面
- [self.musicController monitorMediaItem];
-
- // 實作代理方法
- - (void)achieveachieveMusicInfo:(NSString *)songName andPlaybackStatus:(int)playStatus
- {
- if (1 == playStatus) {
- NSLog(@"正在播放音樂中...");
- }else if(0 == playStatus){
- NSLog(@"音樂暫停中...");
- }else{
- NSLog(@"播放狀态未知...");
- }
-
- NSLog(@"歌曲資訊:%@",songName);
- }
5. 播放控制
- // 控制音樂播放、暫停
- [self playOrPause];
-
- // 下一曲
- [self next];
- 使用
執行個體化對象來播放内置音樂庫的媒體檔案,有以下兩種類方法來執行個體化對象:MPMusicPlayerController
-
說明:播放内置媒體庫項目取代使用者目前播放狀态(如果是用網易雲音樂或QQQ音樂在播放歌曲)MPMusicPlayerController *playController = [MPMusicPlayerController systemMusicPlayer];
-
說明:播放該應用内的歌曲,不影響本機自帶音樂播放器的狀态。MPMusicPlayerController *playController = [MPMusicPlayerController applicationMusicPlayer];
1. 判斷有沒有正在播放的媒體項目
- 傳回
表示NSNotFound
empty queue or an infinite playlist
- if ([self.playController indexOfNowPlayingItem] == NSNotFound) {
- return YES;
- }else{
- return NO;
- }
2. 建立媒體隊列
- 根據
建立媒體隊列,建立成功後可以條用query
來播放(預設播放第 index = 0 首曲目)play
- /**
- * 設定媒體播放隊列
- */
- - (void)createMediaQuery
- {
- // Creates a media query that matches music items and that groups and sorts collections by song name.
- self.query = [MPMediaQuery songsQuery];
-
- // Sets a music player’s playback queue based on a media query.
- [self.playController setQueueWithQuery:self.query];
- }
3. 擷取正在播放的媒體曲目的資訊
- 可以由
取得一系列正在播放的曲目的詳細資訊:nowPlayingItem
- @property (nonatomic, readonly) MPMediaEntityPersistentID
- @property (nonatomic, readonly) MPMediaType mediaType
- @property (nonatomic, readonly) NSString *title
- @property (nonatomic, readonly) NSString *albumTitle
- @property (nonatomic, readonly) MPMediaEntityPersistentID
- @property (nonatomic, readonly) NSString *artist
- @property (nonatomic, readonly) MPMediaEntityPersistentID
- @property (nonatomic, readonly) NSString *albumArtist
- ...
- /**
- * 擷取媒體資訊
- */
- - (void)obtainMusicInfo
- {
- MPMediaItem *currentItem = [self.playController nowPlayingItem];
- NSString *artist = [currentItem valueForProperty:MPMediaItemPropertyArtist];
- NSString *songName = [currentItem valueForProperty:MPMediaItemPropertyTitle];
-
- self.musicInfo = [NSString stringWithFormat:@"%@-%@",artist,songName];
- }
4. 監聽播放媒體項目的通知
- 監聽此通知可以在播放曲目發生改變時(如:下一曲、上一曲)作出動作。
- NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
- [notificationCenter addObserver:self
- selector:@selector(updateMusicInfo)
- name:MPMusicPlayerControllerNowPlayingItemDidChangeNotification
- object:nil];
-
- [self.playController beginGeneratingPlaybackNotifications];