目標:
實現(xiàn)網(wǎng)易云音樂播放音樂時提供給鎖屏的媒體資源信息以及控制中心中對音樂的控制。
實現(xiàn)過程使用到的工具接口(MediaPlayer)
1刃永、MPNowPlayingInfoCenter
2徐许、MPRemoteCommandCenter
Untitled.gif
MPNowPlayingInfoCenter:
是什么:
一個可用于設(shè)置并顯示APP中當前播放的媒體信息的對象
做什么:
1、在設(shè)備鎖屏界面和控制中心中(in the multimedia controls in the multitasking UI)顯示媒體信息
2替裆、通過AirPlay將媒體資源在AppleTV中播放時,播放信息將會出現(xiàn)在電視屏幕上窘问。
3辆童、當前設(shè)備連接到一個iPod附件上,附件上也會顯示當前正在播放的媒體信息
怎么做:(Demo有更詳細的實現(xiàn))
1惠赫、直接使用MPNowPlayingInfoCenter提供的單例根據(jù)需求的鍵值配置nowPlayingInfo屬性 把鉴。
如:
var info : [String : Any] = Dictionary()
//作者
info[MPMediaItemPropertyArtist] = "wizet"
MPNowPlayingInfoCenter.default().nowPlayingInfo = info
蹩腳英文翻譯系列:(未標注版本的鍵均為iOS8及以下可用)
Name | Type | meaning |
---|---|---|
MPMediaItemPropertyAlbumTitle | NSString | 專輯歌曲數(shù) |
MPMediaItemPropertyAlbumTrackCount | NSNumber of NSUInteger | 專輯歌曲數(shù) |
MPMediaItemPropertyAlbumTrackNumber | NSNumber of NSUInteger | 藝術(shù)家/歌手 |
MPMediaItemPropertyArtist | NSString | 藝術(shù)家/歌手 |
MPMediaItemPropertyArtwork | MPMediaItemArtwork | 封面圖片 MPMediaItemArtwork類型 |
MPMediaItemPropertyComposer | NSString | 作曲 |
MPMediaItemPropertyDiscCount | NSNumber of NSUInteger | 專輯數(shù) |
MPMediaItemPropertyDiscNumber NSNumber of NSUInteger | 專輯編號 | |
MPMediaItemPropertyGenre | NSString | 類型/流派 |
MPMediaItemPropertyPersistentID | NSNumber of uint64_t | 唯一標識符 |
MPMediaItemPropertyPlaybackDuration | NSNumber of NSTimeInterval | 歌曲時長 NSNumber類型 |
MPMediaItemPropertyTitle | NSString | 歌曲名稱 |
MPNowPlayingInfoPropertyElapsedPlaybackTime | NSNumber (double) | 在播資源的時間流逝,s為單位儿咱。流逝時間會從播放時間和播放速率中自動計算庭砍,不合適頻繁得更新 |
MPNowPlayingInfoPropertyPlaybackRate | NSNumber (double) | 在播資源的速率(保持與APP內(nèi)播放器的速率一致) |
MPNowPlayingInfoPropertyDefaultPlaybackRate | NSNumber (double) | 在播資源的“默認”播放速率,當你的APP需要播放資源的播放速率默認都是大于1的混埠,那么就應(yīng)該使用這屬性 |
MPNowPlayingInfoPropertyPlaybackQueueIndex | NSNumber (NSUInteger) | 應(yīng)用重放隊列中怠缸,當前播放項的索引。注意索引值從0開始 |
MPNowPlayingInfoPropertyPlaybackQueueCount | NSNumber (NSUInteger) | 應(yīng)用重放隊列的總資源數(shù)目 |
MPNowPlayingInfoPropertyChapterNumber | NSNumber (NSUInteger) | 這在播放的部分岔冀,索引值從0開始 |
MPNowPlayingInfoPropertyChapterCount | NSNumber (NSUInteger) | 在播資源的總章節(jié)數(shù)目 |
MPNowPlayingInfoPropertyIsLiveStream(iOS 10.0) | NSNumber (BOOL) | 表示當前的資源是不是實時流 |
MPNowPlayingInfoPropertyAvailableLanguageOptions(iOS 9.0) | NSArrayRef of MPNowPlayingInfoLanguageOptionGroup | 在播資源的一組可用的語言類型凯旭。在給定組中一次只能播放一種語言類型的資源 |
MPNowPlayingInfoPropertyCurrentLanguageOptions(iOS 9.0) | NSArray of MPNowPlayingInfoLanguageOption | 當前播放項目的語言選項列表 |
MPNowPlayingInfoCollectionIdentifier(iOS 9.3) | NSString | 表示當前播放資源所歸屬的那個集合的標識符,可指作者使套、專輯罐呼、播放列表等≌旄撸可用于請求重新播放這個集合嫉柴。 |
MPNowPlayingInfoPropertyExternalContentIdentifier(iOS 10.0) | NSString | 一個不暴露的唯一標志符,標志當前正在播放的item奉呛,貫穿APP重啟计螺。可使用任何格式瞧壮,僅用于引用這個item和返回到正在播放資源的APP中 |
MPNowPlayingInfoPropertyExternalUserProfileIdentifier(iOS 10.0) | NSString | 一個可選型的不暴露的標志登馒,標志當前正在播放的資源的配置文件,貫穿APP重啟咆槽〕陆危可使用任何格式,僅用于返回到這個配置文件對應(yīng)的正在播放視頻的APP |
MPNowPlayingInfoPropertyServiceIdentifier(iOS 11.0) | NSString | 服務(wù)商的唯一標志。如果當前播放的資源屬于一個頻道或者是定于的服務(wù)類型麦射,這個ID可以用于區(qū)分和協(xié)調(diào)特定服務(wù)商的多種資源類型 |
MPNowPlayingInfoPropertyPlaybackProgress(iOS 10.0) | NSNumber (float) | 表示當前播放資源的播放進度蛾娶,0.0表示未開始,1.0表示完全瀏覽完潜秋。區(qū)分于ElapsedPlaybackTime贮配,無需更高的精度要求饼煞。如:當字幕開始滾動時,這個電影可能被用戶期望開始播放(由字幕驅(qū)動播放進度) |
MPNowPlayingInfoPropertyMediaType | NSNumber (MPNowPlayingInfoMediaType) | 指定當前媒體類型宠页,用于確定系統(tǒng)顯示的用戶界面類型 |
MPNowPlayingInfoPropertyAssetURL(iOS 10.3) | NSURL | 指向當前正播放的視頻或音頻資源的URL夫植≡艹郏可將視頻縮略圖或者音頻的波普圖使用于系統(tǒng)的UI上 |
遠程控制:
iOS7.1前使用的方法(remote control event)
處理流程:(不建議使用)
1系吭、開啟接收遠程控制事件(- (void)beginReceivingRemoteControlEvents)
2咙鞍、配置相應(yīng)的信息(圖片,進度切距,下一首,上一首惨远,或者自定義處理事件)谜悟,以及對應(yīng)事件的處理
(- (void)remoteControlReceivedWithEvent:(UIEvent *)event)
3、結(jié)束接收遠程控制事件(釋放前處理 - (void)endReceivingRemoteControlEvents)
例子:
在APPDelegate中的didFinishLaunching中調(diào)用 UIApplication.shared.beginReceivingRemoteControlEvents()//開始接收遠程控制
并且重寫接收遠程控制信息的接口
override func remoteControlReceived(with event: UIEvent?) {
if event != nil {
if event!.subtype == UIEventSubtype.remoteControlPlay {
WZMusicHub.share.play()
} else if event!.subtype == UIEventSubtype.remoteControlPause {
WZMusicHub.share.pause()
} else if event!.subtype == UIEventSubtype.remoteControlNextTrack {
WZMusicHub.share.next()
} else if event!.subtype == UIEventSubtype.remoteControlPreviousTrack {
WZMusicHub.share.last()
} else if event!.subtype == UIEventSubtype.remoteControlTogglePlayPause {
//耳機的播放暫停
}
}
}
iOS7.1后使用MPRemoteCommandCenter
是什么:
一個可響應(yīng)系統(tǒng)外部附件(耳機等)以及系統(tǒng)控件發(fā)出的遠程控制事件的對象北秽。
做什么:
獲取到這個單例對象后葡幸,使用共享的MPRemoteCommand對象,用于響應(yīng)各種遠程控制事件配置自己的需求贺氓。
如:像網(wǎng)易云音樂一樣蔚叨,在鎖屏以及多媒體系統(tǒng)UI界面配置滑動播放進度(seekTime),下一曲辙培,上一曲蔑水,喜歡,不喜歡等配置
怎么做:(Demo有更詳細的實現(xiàn))
一般的使用流程:
1扬蕊、使用MPNowPlayingInfoCenter提供的單例搀别,可獲得若干個command對象
2、需要使用到的command設(shè)置對應(yīng)isEnable屬性為true尾抑,即開啟了對應(yīng)系統(tǒng)控件的可使用權(quán)
(部分command之間存在沖突歇父,因為都位于同一位置,沖突的command部分UI最后顯示的是最后開啟的command)
3再愈、最后是進行command事件回調(diào)處理
另外有個別的command由于類型的多樣化榜苫,具有獨立特性的(如:MPFeedbackComman等)需要額外配置特定的接口
關(guān)于一些需求和實現(xiàn)過程的問題
1、鎖屏顯示歌詞的處理:瀏覽了一些想法翎冲,都是繪制歌詞到圖片處
這個功能個人認為比較雞肋垂睬,畢竟我覺得挺少人會面向鎖屏去看歌詞了,
而且iOS11的鎖屏UI還改了,圖變得更小了羔飞,那么這個功能估計會被砍掉肺樟。
2、使用changePlaybackPositionCommand進行seekTime時候逻淌,控制中心的播放進度條停止了下來
使用帶handler的回調(diào),在回調(diào)處再次對info進行進度條的更新
3卡儒、布局時UI的位置錯誤
self.navigationController?.navigationBar.bounds.size.height ?? 0 + UIApplication.shared.statusBarFrame.size.height
這個寫法系統(tǒng)會把0 + UIApplication.shared.statusBarFrame.size.height歸為一個整體,
這就告訴了我們括號了重要性了??
(self.navigationController?.navigationBar.bounds.size.height ?? 0) + UIApplication.shared.statusBarFrame.size.height
4硬爆、調(diào)節(jié)系統(tǒng)音量時,隱藏系統(tǒng)音量控制界面(系統(tǒng)音量box)
觸發(fā)條件:add到View上并設(shè)置frame位于視圖層顯示區(qū)域之外擎鸠,想要恢復(fù)顯示只要從圖層中remove就可以了
///實現(xiàn)處
static func getSystemVolumeView() -> MPVolumeView {
//frame位于視圖之外時實現(xiàn)“隱藏”系統(tǒng)音量控件效果
let mpView : MPVolumeView = MPVolumeView(frame: CGRect(x: -1000, y: -1000, width: 40, height: 40))
mpView.isHidden = false
return mpView
}
///調(diào)用處
self.volumeView = WZEnsemble.getSystemVolumeView()
self.addSubview(self.volumeView!)