# 前言
之前學(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
# 演示
# 功能
- 集成了視頻播放器常有的手勢,包括單擊顯示控制視圖单料,雙擊暫停埋凯,水平滑動快進、后退扫尖,豎直滑動亮度和音量調(diào)節(jié)白对。
- 全屏播放,自適應(yīng)手機屏幕旋轉(zhuǎn)方向换怖。
- 自定義控制視圖
# 實現(xiàn)思路
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è)置工程
// 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, 可以看到緩存的文件
使用:
// 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 { }
# 參考
- https://techblog.toutiao.com/2017/03/28/fullscreen/
- https://developer.apple.com/library/content/qa/qa1668/_index.html
- https://developer.apple.com/documentation/avfoundation
- https://stackoverflow.com/questions/808503/uibutton-making-the-hit-area-larger-than-the-default-hit-area/13977921
- https://gist.github.com/onevcat/2d1ceff1c657591eebde
- Media Cache VIMediaCache
- https://mp.weixin.qq.com/s/v1sw_Sb8oKeZ8sWyjBUXGA
# 總結(jié)
- 了解了AVPlayer的整體結(jié)構(gòu),對播放過程完整的思路和一些遇到的問題间驮。
- 踩了屏幕旋轉(zhuǎn)細節(jié)躬厌、按鈕點擊范圍調(diào)整的一些交互細節(jié)的坑