Swift 封裝一個視頻播放器 VGPlayer

Banners.png

# 前言

之前學(xué)習(xí)了 Swift 一直想做一個項目霹娄,這次下定決心花了近1個月的空閑時間基于 AVPlayer 封裝了一個視頻播放器娩贷。

# 源代碼

  • GitHub地址:VGPlayer
  • 有什么意見建議可以提 issues,在博文下留言芭碍,如果覺得不錯牺汤,歡迎點star帽借。

# 更新列表

  • 2017-6-13 v0.0.1
  • 2017-6-17 v0.0.2 支持外掛字幕 格式 srt & ass 兩種都支持
  • 2017-7-1 邊播邊緩存 v0.1.0
  • 2017-7-11 修復(fù)所有編譯??. v0.1.2
  • 2017-7-16 修復(fù)緩存視頻時URL解析錯誤導(dǎo)致的crash. v0.1.3
  • 2017-8-10 修復(fù)退出全屏后的播放視圖frame error問題姐浮,修復(fù)iOS9播放卡住問題,增加example 嵌入在cell中的播放模式. v0.1.4
  • 2017-9-6 v0.1.5 修復(fù)URL 解析問題 修復(fù)暫停播放問題
  • 2017-9-21 v0.2.0 整理代碼谷遂、轉(zhuǎn)換成Swift 4

# 演示

demo1.gif
demo2.gif
vgplayer_embed_in_cell.gif

# 功能

  • 集成了視頻播放器常有的手勢,包括單擊顯示控制視圖单料,雙擊暫停埋凯,水平滑動快進、后退扫尖,豎直滑動亮度和音量調(diào)節(jié)白对。
  • 全屏播放,自適應(yīng)手機屏幕旋轉(zhuǎn)方向换怖。
  • 自定義控制視圖

# 實現(xiàn)思路

流程圖.png

VGPlayer

VGPlayer是一個對AVPlayer封裝提供播放功能甩恼,displayView為播放器畫面繪制。
主要是使用了以下幾個類:

  • AVURLAsset是 AVAsset的子類沉颂,用來本地或者網(wǎng)絡(luò)視頻地址的初始化網(wǎng)絡(luò)請求条摸,也可以用來獲取視頻每一幀的畫面來實現(xiàn)滑動提前預(yù)覽圖的功能(后續(xù)應(yīng)該會版本迭代加上此功能)
  • AVPlayerItem 是對AVPlayer播放的視頻數(shù)據(jù)管理,對播放的Asset資源進行記錄铸屉,提供或者視頻的時間钉蒲,播放狀態(tài)等。
  • AVPlayer 調(diào)控數(shù)據(jù)和視圖
  • AVPlayerLayer 進行視頻視圖繪制

VGPlayer封裝AVPlayer提供給調(diào)用者可選代理方法

// player delegate
    // play state
    func vgPlayer(_ player: VGPlayer, stateDidChange state: VGPlayerState)
    // playe Duration
    func vgPlayer(_ player: VGPlayer, playerDurationDidChange currentDuration: TimeInterval, totalDuration: TimeInterval)
    // buffer state
    func vgPlayer(_ player: VGPlayer, bufferStateDidChange state: VGPlayerBufferstate)
    // buffered Duration
    func vgPlayer(_ player: VGPlayer, bufferedDidChange bufferedDuration: TimeInterval, totalDuration: TimeInterval)
    // play error
    func vgPlayer(_ player: VGPlayer, playerFailed error: VGPlayerError)

VGPlayerView

  • VGPlayerView負責畫面的展示,彻坛,只作為展示顷啼,而繪制層則是AVPlayerLayer提供,可繼承此類進行控制視圖的自定義
  • VGPlayerView封裝AVPlayerLayer提供可選代理方法
// player view delegate
    /// fullscreen
    func vgPlayerView(_ playerView: VGPlayerView, willFullscreen fullscreen: Bool)
    /// close play view
    func vgPlayerView(didTappedClose playerView: VGPlayerView)
    /// displaye control
    func vgPlayerView(didDisplayControl playerView: VGPlayerView)

VGPlayerError

  • VGPlayerError一個 struct 用來播放出現(xiàn)Error時返回

# 細節(jié)調(diào)整

  • 后臺播放的實現(xiàn)
    設(shè)置工程
backgroundModes.png
// AppDelegate settings
 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        do
        {
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
        }
        catch let error as NSError
        {
            print(error)
        }
        return true
    }

設(shè)置VGPlayer的Background mode

self.player.backgroundMode = .proceed
  • VGPlayerUtils 提供判斷視頻類型方法和一些通用的方法
  • UIButton+VGPlayer 擴展按鈕點擊范圍
  • Timer+VGPlayer 解決Timer的 retain cycle問題

邊播邊緩存 (參考: VIMediaCache)

  • 使用AVAssetResourceLoader 來控制視頻緩存

  • 使用Range請求數(shù)據(jù)昌屉,可取消下載钙蒙,分段緩存

  • 在 Simulator debugging, 可以看到緩存的文件


    test
  • 使用:

// Settings maxCacheSize
VGPlayerCacheManager.shared.cacheConfig.maxCacheSize = 160000000

// Setting maxCacheAge   default one weak
VGPlayerCacheManager.shared.cacheConfig.maxCacheAge = 60 * 60 * 24 * 7

// clean all cache
VGPlayerCacheManager.shared.cleanAllCache()

// clean old disk cache. 
// This is an async operation.
VGPlayerCacheManager.shared.cleanOldFiles { }

# 參考

# 總結(jié)

  • 了解了AVPlayer的整體結(jié)構(gòu),對播放過程完整的思路和一些遇到的問題间驮。
  • 踩了屏幕旋轉(zhuǎn)細節(jié)躬厌、按鈕點擊范圍調(diào)整的一些交互細節(jié)的坑
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市竞帽,隨后出現(xiàn)的幾起案子扛施,更是在濱河造成了極大的恐慌,老刑警劉巖屹篓,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件疙渣,死亡現(xiàn)場離奇詭異,居然都是意外死亡抱虐,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門饥脑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來恳邀,“玉大人懦冰,你說我怎么就攤上這事∫シ校” “怎么了刷钢?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長乳附。 經(jīng)常有香客問我内地,道長,這世上最難降的妖魔是什么赋除? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任阱缓,我火速辦了婚禮,結(jié)果婚禮上举农,老公的妹妹穿的比我還像新娘荆针。我一直安慰自己,他們只是感情好颁糟,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布航背。 她就那樣靜靜地躺著,像睡著了一般棱貌。 火紅的嫁衣襯著肌膚如雪玖媚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天婚脱,我揣著相機與錄音今魔,去河邊找鬼。 笑死起惕,一個胖子當著我的面吹牛涡贱,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播惹想,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼问词,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了嘀粱?” 一聲冷哼從身側(cè)響起激挪,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎锋叨,沒想到半個月后垄分,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡娃磺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年薄湿,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡豺瘤,死狀恐怖吆倦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情坐求,我是刑警寧澤蚕泽,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站桥嗤,受9級特大地震影響须妻,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜泛领,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一荒吏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧师逸,春花似錦司倚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至员辩,卻和暖如春盒粮,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背奠滑。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工丹皱, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人宋税。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓摊崭,卻偏偏與公主長得像,于是被迫代替她去往敵國和親杰赛。 傳聞我的和親對象是個殘疾皇子呢簸,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容