承上篇,本篇文章主要介紹iOS視頻播放需要用到的類
MPMoviePlayerController
MP簡介
iOS提供MPMoviePlayerController類進(jìn)行播放,支持流媒體和文件播放。MPMoviePlayerController足夠強(qiáng)大,幾乎不用寫幾行代碼就能完成一個播放器。視頻內(nèi)容會渲染到他的View上,這個View可以移動、縮放,放在任何用戶想放的地方,而在縮放移動的過程中視頻都可以正常的播放,完全不受影響。
通常我們在ipad上會做這樣的小窗播放功能,讓用戶可以邊看視頻邊看電子書或者瀏覽網(wǎng)頁。
MP支持的格式
- MPMoviePlayerController既支持本地視頻文件的播放也支持流媒體(HTTP Live Streaming)
- MPMoviePlayerController因?yàn)槭褂玫氖怯步獯a,所以支持的文件格式只有以H264為編碼格式的MP4、MOV、M4V、M2V、3GP等。
- MPMoviePlayerController支持大多數(shù)音頻編碼。
- 其他格式的解碼比如rmvb,可以考慮第三方解碼框架ffmpeg。ffmpeg等第三方解碼框架使用的是軟解碼,所以手機(jī)的發(fā)熱和耗電非常的恐怖,如非必要,不要使用。
- 視頻格式的相關(guān)知識的詳細(xì)介紹:iOS視頻流開發(fā)(1)— 基礎(chǔ)概念
MP開發(fā)注意事項(xiàng)
由于MPMoviePlayerController的初始化方法做了大量工作,例如設(shè)置URL、自動播放、添加點(diǎn)擊Done完成的監(jiān)控等。所以盡可能重用,而不要頻繁的銷毀重新創(chuàng)建,重用一個MPMoviePlayerController非常簡單,將新的播放地址設(shè)置過去就可以了。注意,要先stop。
MPMoviePlayerController進(jìn)入全屏播放模式的時候,一定要監(jiān)聽他的stop狀態(tài),并進(jìn)行處理,繼續(xù)播放或者退出全屏。否則一直停在全屏模式下。
MPMoviePlayerController是一個很復(fù)雜的視圖結(jié)構(gòu),我們有時候需要對播放器添加一些控件。我建議不要在MPMoviePlayerController上修改,因?yàn)镸P在iOS4、5、6、7上的視圖結(jié)構(gòu)都不一樣,添加自定義控件非常容易出問題。那需求又必須讓我們加入自定義的控件怎么辦呢?這個時候我們就需要用到AVPlayer了。
MPMoviePlayerController支持播放m3u8格式資源,這個資源一般是在云端。如果我們想把m3u8緩存在本地播放。直接播放是不支持的,需要在本地啟動一個server,通過http://localhost/的方式播放本地的m3u8文件。在使用AirPlay的時候要把播放地址切成終端的IP地址,否則會播放失敗。
AVPlayer
AVPlayer簡介
當(dāng)需要自定義播放器的樣式時,我們可以使用AVPlayer。AVPlayer在AVFoundation框架中,相比MPMoviePlayerController它更加接近于底層。由于AVPlayer是作用在layer上,效率會比MP高一些。
AVPlayer播放
AVPlayer本身并不能顯示視頻。他通過創(chuàng)建一個播放器層AVPlayerLayer用于展示視頻,播放器層繼承于CALayer,有了AVPlayerLayer之后,將AVPlayerLayer添加到控制器視圖的layer中即可。相比MP直接傳入一個URL,AVPlayer播放的時候略微復(fù)雜一些,需要用到以下數(shù)據(jù)結(jié)構(gòu):
AVURLAsset:AVAsset的子類,可以根據(jù)一個URL路徑創(chuàng)建一個包含媒體信息的AVURLAsset對象。
AVPlayerItem:一個媒體資源管理對象,管理者視頻的一些基本信息和狀態(tài),一個AVPlayerItem對應(yīng)著一個視頻資源。
AVPlayer獲取播放狀態(tài)
-
視頻加載狀態(tài)
通過KVO監(jiān)聽AVPlayerItem的status屬性來獲得。當(dāng)AVPlayerItem的status屬性為AVPlayerStatusReadyToPlay時,表明視頻加載完成。 -
視頻緩沖狀態(tài)
同樣,通過KVO監(jiān)聽AVPlayerItem的loadedTimeRanges屬性來獲得。視頻每緩沖一部分這個屬性數(shù)據(jù)就會被更新,當(dāng)loadedTimeRanges的值改變時可以獲得本次緩沖加載的視頻范圍,包含起始時間、本次加載時長),這樣一來就可以實(shí)時獲得緩沖情況。 -
播放進(jìn)度狀態(tài)
通過AVPlayer的- (id)addPeriodicTimeObserverForInterval:(CMTime)interval queue:(dispatch_queue_t)queue usingBlock:(void (^)(CMTime time))block方法獲得播放進(jìn)度,這個方法會在設(shè)定的時間間隔內(nèi)定時更新播放進(jìn)度。
AVQueuePlayer
AVQueuePlayer用于列表播放,雖然AVPlayer通過監(jiān)聽播放狀態(tài)也可以做到視頻結(jié)束后的自動切換,但是使用AVQueuePlayer加載會快很多。應(yīng)該是AVFoundation框架對AVQueuePlayer進(jìn)行了優(yōu)化,排隊(duì)的視頻會進(jìn)行預(yù)加載。
iOS視頻播放總結(jié):
iOS提供MPMoviePlayerController這個類有個非常難用的點(diǎn),就是他的頻播放狀態(tài)和視頻加載狀態(tài)都是通過Notification通知狀態(tài)變化,而不是通過block或者delegate。在實(shí)際使用中稍微不注意就會出問題,尤其是在視頻列表中。如果蘋果的工程師不是腦子進(jìn)水的話,為什么這樣設(shè)計(jì)呢?
我認(rèn)為之所以這樣設(shè)計(jì)的原因是,無論MPMoviePlayerController還是AVPlayer,都只是一個外殼,他們內(nèi)部都是用了一個同一個CoreMedia的播放組件,這個播放組件是全局單例。包括iOS瀏覽器使用的播放器(瀏覽器的播放器以plugin的形式嵌入)都是使用的這個播放內(nèi)核。所以理論上也就不可能在一部iOS設(shè)備上同時播放兩個視頻,一個播放另一個必然停止,無論它是網(wǎng)頁還是本地。那么Notification這樣的應(yīng)用程序級的通知方式似乎比block或者delegate這樣類級別的方式更合理。
大家可以試試,看看用原生播放器能否做到一個iOS設(shè)備上同時播放兩個視頻。
下一篇將介紹視頻流的采集,iOS視頻流開發(fā)(3)— 錄制