天天看點

iOS視訊流開發(2)—視訊播放

承上篇,本篇文章主要介紹iOS視訊播放需要用到的類。以及他們的使用場景和開發中遇到的問題。

MPMoviePlayerViewController

MP簡介

iOS提供MPMoviePlayerController類進行播放,支援流媒體和檔案播放。MPMoviePlayerController足夠強大,幾乎不用寫幾行代碼就能完成一個播放器。視訊内容會渲染到他的View上,這個View可以移動、縮放,放在任何使用者想放的地方,而在縮放移動的過程中視訊都可以正常的播放,完全不受影響。

通常我們在ipad上會做這樣的小窗播放功能,讓使用者可以邊看視訊邊看電子書或者浏覽網頁。

MP支援的格式

  • MPMoviePlayerController既支援本地視訊檔案的播放也支援流媒體(HTTP Live Streaming)
  • MPMoviePlayerController因為使用的是硬解碼,是以支援的檔案格式隻有以H264為編碼格式的MP4、MOV、M4V、M2V、3GP等。
  • MPMoviePlayerController支援大多數音頻編碼。
  • 其他格式的解碼比如rmvb,可以考慮第三方解碼架構ffmpeg。ffmpeg等第三方解碼架構使用的是軟解碼,是以手機的發熱和耗電非常的恐怖,如非必要,不要使用。
  • 視訊格式的相關知識的詳細介紹:iOS視訊流開發(1)—視訊基礎知識

MP開發注意事項

  • 由于MPMoviePlayerViewController的初始化方法做了大量工作,例如設定URL、自動播放、添加點選Done完成的監控等。是以盡可能重用,而不要頻繁的銷毀重新建立,重用一個MPMoviePlayerViewController非常簡單,将新的播放位址設定過去就可以了
  • MPMoviePlayerViewController進入全屏播放模式的時候,一定要監聽他的stop狀态,并進行處理,繼續播放或者退出全屏。否則一直停在全屏模式下。
  • MPMoviePlayerViewController是一個很複雜的視圖結構,我們有時候需要對播放器添加一些控件。我建議不要在MPMoviePlayerViewController上修改,因為MP在iOS4、5、6、7上的視圖結構都不一樣,添加自定義控件非常容易出問題。那需求又必須讓我們加入自定義的控件怎麼辦呢?這個時候我們就需要用到AVPlayer了。

AVPlayer

AVPlayer簡介

當需要自定義播放器的樣式時,我們可以使用AVPlayer。AVPlayer在AVFoundation架構中,相比MPMoviePlayerController它更加接近于底層。由于AVPlayer是作用在layer上,效率會比MP高一些。

AVPlayer播放

AVPlayer本身并不能顯示視訊。他通過建立一個播放器層AVPlayerLayer用于展示視訊,播放器層繼承于CALayer,有了AVPlayerLayer之後,将AVPlayerLayer添加到控制器視圖的layer中即可。相比MP直接傳入一個URL,AVPlayer播放的時候略微複雜一些,需要用到以下資料結構:

  • AVURLAsset:AVAsset的子類,可以根據一個URL路徑建立一個包含媒體資訊的AVURLAsset對象。
  • AVPlayerItem:一個媒體資源管理對象,管理者視訊的一些基本資訊和狀态,一個AVPlayerItem對應着一個視訊資源。

AVPlayer擷取播放狀态

  • 視訊加載狀态

    通過KVO監聽AVPlayerItem的status屬性來獲得。當AVPlayerItem的status屬性為AVPlayerStatusReadyToPlay時,表明視訊加載完成。

  • 視訊緩沖狀态

    同樣,通過KVO監聽AVPlayerItem的loadedTimeRanges屬性來獲得。視訊每緩沖一部分這個屬性資料就會被更新,當loadedTimeRanges的值改變時可以獲得本次緩沖加載的視訊範圍,包含起始時間、本次加載時長),這樣一來就可以實時獲得緩沖情況。

  • 播放進度狀态

    通過AVPlayer的- (id)addPeriodicTimeObserverForInterval:(CMTime)interval queue:(dispatch_queue_t)queue usingBlock:(void (^)(CMTime time))block方法獲得播放進度,這個方法會在設定的時間間隔内定時更新播放進度。

AVQueuePlayer

AVQueuePlayer用于清單播放,雖然AVPlayer通過監聽播放狀态也可以做到視訊結束後的自動切換,但是使用AVQueuePlayer加載會快很多。應該是AVFoundation架構對AVQueuePlayer進行了優化,排隊的視訊會進行預加載。

iOS視訊播放:

iOS提供MPMoviePlayerController這個類有個非常難用的點,就是他的頻播放狀态和視訊加載狀态都是通過Notification通知狀态變化,而不是通過block或者delegate。在實際使用中稍微不注意就會出問題,尤其是在視訊清單中。如果蘋果的工程師不是腦子進水的話,為什麼這樣設計呢?

我認為之是以這樣設計的原因是,無論MPMoviePlayerController還是AVPlayer,都隻是一個外殼,他們内部都是用了一個同一個CoreMedia的播放元件,這個播放元件是全局單例。包括iOS浏覽器使用的播放器(浏覽器的播放器以plugin的形式嵌入)都是使用的這個播放核心。是以理論上也就不可能在一部iOS裝置上同時播放兩個視訊,一個播放另一個必然停止,無論它是網頁還是本地。那麼Notification這樣的應用程式級的通知方式似乎比block或者delegate這樣類級别的方式更合理。

大家可以試試,看看用原生播放器能否做到一個iOS裝置上同時播放兩個視訊。