過去一年一直在搞視頻相關的產品,可遇見的未來估計也是。下面是我總結的一些內容以備忘,會不定期更新。同時有不對的地方,以及如果有更好的補充,歡迎在下方留言。
備忘
- 想知道 AVPlayer 是否在播放中,最簡單的方法是判斷 rate 是否為0(注意同時 error 為 nil)。但是最精確的方法是判斷 timeControlStatus 的值。
- 接上一條,在弱網情況下,我注意到在視頻剛開始播放的時候,無論是 timeControlStatus 還是 rate 都告訴你視頻在播放了。但是實際上這種時候,我曾經碰到連續好幾秒都沒有開始播放。不過在開始播放之后,timeControlStatus 和 rate 都能正確反映視頻是否正在播放。
- AVPlayer 可以播放音頻和視頻,可以是網絡的也可以是本地的,AVAudioPlayer 只能播放本地音頻。
- AVPlayer 播放的文件如果傳 URL 的話,需要注意該 URL 需要帶指定文件類型的擴展名。比如說如果是 mp3 文件,這個 URL 就要帶上 “.mp3” 的后綴,不然 AVPlayer 會播放失敗,error 信息提示說不支持當前的文件類型。
- AVPlayer 默認情況下會加載足夠多的數據才開始播放,如果你希望它盡早開始播放的話,需要設置 automaticallyWaitsToMinimizeStalling 為 true
- 記得持有 addPeriodicTimeObserver 返回的 token,在不需要的時候 使用
removeTimeObserver 這個 token。 - GitHub 上大部分的關于視頻播放的框架其實就是基于 AVFoundation(主要是 AVPlayer)的 UI 框架。所以如果你們公司準備長期搞一個視頻相關的項目,沒必要使用這些框架,自己自定義就好了。一個原因是熟悉 AVFoundation,另一個原因是大部分情況下產品經理和設計師對 UI 作出很多改動。而且簡單的自定義一點不難。
- 關于 AVPlayer 最經常需要的操作可能就是緩存視頻,這需要一些代碼,不過基本上就是一些樣本代碼。
- 手動加載視頻最常見的操作是將視頻地址的 scheme 修改成任意不是 http 或者 https 的值。然后將該修改過的地址傳給 AVURLAsset,同時設置 AVURLAsset 的 resourceLoader 的代理。在代理里面手動發起網絡請求加載視頻數據。這樣 AVFoundation 在解析到它不支持的 scheme 時候會代理給你設置的 delegate。
- 接上一條,雖然這種方式可以手動加載視頻,但實際上要加載的具體視頻的片段是 AVFoundation 在代理給你的 request 里面已經設置好了的。所以這個層面來說,靈活性不是很好。但是這種方式其實是使用人數最多的。大部分 GitHub 上的視頻框架就是這么做的。可以參考一下。
- 還有一種手動加載視頻的方式是本地起一個服務器,不過這個我暫時沒有嘗試過。
- AVPlayer 默認的 seek 精度不是很高,不過 seek 的時候可以設置。
- 我曾經碰到一個問題 AVPlayerItem 的 cancelPendingSeeks 和相應的 AVAsset 的 cancelLoading 都不能阻止它繼續加載,所以用了
player.replaceCurrentItem(with: nil)
這種方式,情況好一些了,但是不能徹底解決問題。可能是我姿勢不對?我能確認的是我的代碼沒有引用循環和延遲釋放的問題。