swift:基于MPMoviePlayerController的視頻播放器

前言

高仿網易新聞遇到視頻播放的問題,以前很少做多媒體這一塊,我一向的邏輯就是想弄清楚就從零開始寫。所以出于學習的目的,自己又制造了一個輪子。項目地址WLVideoPlayer-MP-, 花很大的心思加強復用性。具體效果如下。

準備

為了方便新同學學習多媒體視頻播放的相關內容,已經把每一個步驟都打包成一個單獨的工程

當然,你也完全可以從Github上clone整個項目。

WLVideoPlayer的使用

        playingPlayerView = WLVideoPlayerView(url: NSURL(string: urlStr)!)
        playingPlayerView?.customControlView = controlView //你需要的控制面板
        playingPlayerView?.placeholderView = UIImageView(image: UIImage(named: "placeholder")) // 視頻加載時的等待圖片
        playingPlayerView?.playInView(inView) // 播放

WLVideoPlayer提供了默認的視頻控制面板,如果你想使用自己的,只需要繼承自WLBasePlayerControlView并根據WLPlayerControlViewDelegate協議調用你想實現功能的相應代理方法即可。你所做的只有布局你的自定義控制面板。

功能分析

蘋果提供的MPMoviePlayerController功能已經很完善了,那為什么還要要自定義視頻播放器?弄清這一點,我們才能知道我們自定義視頻播放器的的目的。

  • 最直接的無非就是控制面板的問題,視頻控制面板太丑,上面很多控件是用不著的。
  • 支持的播放格式少

而又因為播放格式的問題涉及到視頻文件的解碼,這個對于不是學習視頻算法的我們太過于牽強(雖然有VLC)。所以我們自定義視頻播放器的的任務已經很明顯了。

  • 能支持自定義視頻控制面板
  • 視頻播放\停止\拖拽快進等基本功能
  • 視頻全屏與屏幕旋轉問題的解決

其中我認為最重要的便是能支持自定義視頻控制面板,它決定了你的這個小播放器能不能重復使用

代碼簡析

這是播放器主體代碼,其他的部分都是測試用的數據源,是從作者另外一個開源項目高仿網易新聞中分離出來。具體實現不需要太過于關心。因為代碼中加了大量的注釋,所以只簡單介紹一下重要的一些代碼片段。

WLVideoPlayerView.swift

外接都是通過直接操作這個類來控制視頻播放器的行為。


    var contentURL: NSURL? 
    var placeholderView: UIView?
    /// 用戶自定義控制界面
    var customControlView: WLBasePlayerControlView? 
    /// 用戶自定義視頻控制面板自動隱藏的時間
    var customControlViewAutoHiddenInterval: NSTimeInterval 
    /// 進入全屏的模式
    var fullscreenModel: WLVideoPlayerViewFullscreenModel 
    

這些都是暴露出來提供外部來設置播放器的一些屬性,其中值得一提的便是customControlView這個的屬性。這便是我們的視頻控制器視圖了,當初在設計的時候十分頭疼,原本應該是這樣,這個customControlView必須是UIView的子類,而且他也必須遵守我設置的一系列協議規范。但是很可惜我沒有發現swift中有類似于oc這樣的寫法

UIView<someProtocol> *customControlView

于是我在妥協之下,只能使用繼承這種不太優雅的方式解決。設計了一個類似于抽象類的WLBasePlayerControlView

接下來是一堆私有屬性,其中需要主要的是

lazy var playerControlHandler: WLPlayerHandler = WLPlayerHandler()

這個對象的功能是處理視頻控制器的事件,比如暫停、快進、全屏等事件。設計這樣一個對象的目的是為了將視頻控制器的事件于播放事件進行分離,減少WLVideoPlayerView.swift的代碼量。

然后值得一提的便是幾個全屏\旋轉的控制方法

func toLandscape(angle: CGFloat)
func toPortrait()
func enterFullscreen
func exitFullscreen()
func changePlayerScreenState

因為iPhone手機應用一般都會禁止項目的旋轉,一般只會支持Portrait這一個方向,然而我們往往是希望當手機橫屏播放視頻的時候,視頻內容能夠鋪滿全屏。在這樣的需求下,系統自帶的setFullscreen方法是不好使的。所以只能自己實現放大、縮小、旋轉的方法。當發生全屏、退出全屏、旋轉等事件時,對播放器視圖、控制面板視圖進行處理。因為視頻控制面板又是用戶自定義的,幾乎都是使用autolayout進行布局,所以在必須更新相應的約束。

WLPlayerHandler.swift

這個文件主要是WLPlayerHandler類的實現,之間也解釋了,WLPlayerHandler是為了將視頻控制面板的邏輯與視頻播放本身邏輯進行分離而設計的一個類。WLPlayerHandler主要處理用戶自定義控制面板的一些事件,比如:暫停按鈕點擊、全屏按鈕的點擊、進度條拖拽等

    weak var player: MPMoviePlayerController!
    weak var customControlView: WLBasePlayerControlView!

這里使用weak關鍵字是為了防止WLVideoPlayerView的實例對象與WLPlayerHandler實例對象造成循環引用。

WLBasePlayerControlView.swift

這個文件里面定義了WLPlayerControlViewDelegate代理協議與WLBasePlayerControlView類,這樣是妥協的設計辦法,暫時因為作者能力有限沒找到更加優雅實現方式。WLBasePlayerControlView類是所有自定義視頻控制面板的基類,如果想實現你自己的播放面板,你得繼承自這個類,并通過delegate屬性調用WLPlayerControlViewDelegate協議提供的方法來處理你面板上的事件。

PlayerControlView.swift和PlayerDemoControlView.swift

這兩個文件是提供給大家參考的視頻控制面板的實現方式,PlayerControlView是用xib進行布局,而PlayerDemoControlView.swift是使用SnapKit進行布局。參照這兩個的實現方式,完全可以自定義你專屬的視頻控制面板。

PlayerControlViewAuxiliary.swift

這里面定義的是UpdateProgressProtocol協議以及提供的默認實現,也是提供給自定義視頻控制面板使用的

總結

在實現WLVideoPlayer這個輪子的過程中,發現如果不涉及對視頻的解碼,自定義一個播放器的過程也就是自定義它的視頻控制面板的過程。而對于視頻播放的邏輯處理(如快進、全屏等)各個播放器基本都是一樣的。不同的僅僅在于視頻控制面板的樣式不同。正因為這一特征,我才將視頻控制面板邏輯處理與視圖布局分離。這樣,我只需要寫一次通用的邏輯處理方式,以后再根據不同的需求設計不同控制面板即可。這樣這個輪子造的才有意義。如果你是新手,您根據我開發工程的步驟,對代碼重構的過程,應該會有理解。如果您有更好的建議或者意見,歡迎您的指出。

后續工作

這個輪子已經具備的一個簡單播放器的基本功能,但任然有很多的功能可以添加,日后將不斷對這個項目進行完善、對代碼質量進行提高。不過MPMoviePlayerController這個類蘋果已經不建議我們使用了,所以以后應該還會使用AVPlayer開發一個類似的播放器。最后再次附上本項目地址WLVideoPlayer-MP-

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,321評論 6 543
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,559評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,442評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,835評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,581評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,922評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,931評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,096評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,639評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,374評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,591評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,104評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,789評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,196評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,524評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,322評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,554評論 2 379

推薦閱讀更多精彩內容