Swift 封裝一個視頻播放器 VGPlayer

Banners.png

# 前言

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

# 源代碼

  • GitHub地址:VGPlayer
  • 有什么意見建議可以提 issues,在博文下留言,如果覺得不錯,歡迎點(diǎn)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

# 功能

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

# 實(shí)現(xiàn)思路

流程圖.png

VGPlayer

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

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

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負(fù)責(zé)畫面的展示,,只作為展示,而繪制層則是AVPlayerLayer提供,可繼承此類進(jìn)行控制視圖的自定義
  • 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時返回

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

  • 后臺播放的實(shí)現(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 擴(kuò)展按鈕點(diǎn)擊范圍
  • 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)細(xì)節(jié)、按鈕點(diǎn)擊范圍調(diào)整的一些交互細(xì)節(jié)的坑
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容