禁止自動橫屏下的視訊播放強制旋轉
這個標題有點繞,所以我來解釋一下。
之前專案開發的時候需要用到一個視訊播放的第三方庫,但是這個第三方庫在從小螢幕播放切換到大螢幕播放的時候,是需要開啟專案的自動旋轉支援的。也就是

ofollow,noindex">第三方視訊播放庫 BMPlayer 這個庫中有許多細節的部分無法滿足實際使用,因此我下了原始碼後自己根據需求修改。
然而實際應用中,許多的 App 的要求是需要禁止橫屏的。因為大多數 App(竊以為除了遊戲以外的)即使寫好了約束,也都不會針對橫屏下的 UI 作對應的優化。 因此我們需要自己針對 工程禁用橫屏情況下,播放視訊時切換到全屏做自己的優化
問題的擴充套件
之前搜尋播放框架的時候沒有找到適當的,因此最後決定自己把 BMPlayer
的原始碼 down
下來自己修改。雖然最後解決了(這也是本篇文章下面主要闡述的內容),但是解決方案是在 AppDelegate
中增加一個變數來控制當前 App
的方向。實際上還是增加了庫和工程之間的耦合度。暫時還未找到更好的解決方案。
實現的效果

程式碼和說明( Swift
為例)
下面的原始碼中略去了不必要的程式碼
AppDelegate.swift 中
let appDelegate = UIApplication.shared.delegate as! AppDelegate class AppDelegate: UIResponder, UIApplicationDelegate, WXApiDelegate { var deviceOrientation = UIInterfaceOrientationMask.portrait // 去實現這個回撥代理 func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { return deviceOrientation } } 複製程式碼
在視訊播放庫中控制它的方向
點選全屏播放和恢復小螢幕時候兩個按鈕的對應方法
private func forceToPlayOnFullScreen() { let currentOrientation = UIDevice.current.orientation print("向右旋轉前 當前的方向 = ", currentOrientation.rawValue) appDelegate.deviceOrientation = .landscapeRight // 如果防止使用者在進入當前頁面時手機橫置,那麼當前的 device orientation 是 landscapeRight // 這時候,我們再去設定 landscapeRight,是不會引起廣播 "UIDeviceOrientationDidChangeNotification",因此手動呼叫一次 let portraitValue = UIInterfaceOrientation.portrait.rawValue UIDevice.current.setValue(portraitValue, forKey: "orientation") let rightValue = UIInterfaceOrientation.landscapeRight.rawValue UIDevice.current.setValue(rightValue, forKey: "orientation") } private func forceToPlayOnOriginScreen() { let currentOrientation = UIDevice.current.orientation print("恢復垂直前當前的方向 = ", currentOrientation.rawValue) // 這裡為什麼要寫兩遍,在下面說明 appDelegate.deviceOrientation = .portrait let rightValue = UIInterfaceOrientation.landscapeRight.rawValue UIDevice.current.setValue(rightValue, forKey: "orientation") let portraitValue = UIInterfaceOrientation.portrait.rawValue UIDevice.current.setValue(portraitValue, forKey: "orientation") } 複製程式碼
關於程式碼設定了兩次方向的說明
一定很奇怪,為什麼兩次程式碼的呼叫中,設定方向的程式碼要寫兩遍呢
UIDevice.current.setValue
這是因為,視訊播放庫,這裡需要去獲取一個系統的廣播 UIDeviceOrientationDidChangeNotification
.
說明
假設我們當前的螢幕是橫屏的情況

此時系統會利用陀螺儀,雖然我們視覺上看上去,他並沒有向右旋轉,但是當前的方向 UIDevice.current.orientation
會變成 landScapeRight
.
因此我們如果這時候去呼叫
let rightValue = UIInterfaceOrientation.landscapeRight.rawValue UIDevice.current.setValue(rightValue, forKey: "orientation") 複製程式碼
這個函式的時候,不會觸發廣播,因為系統會認為,其實我的方向沒有變化啊!
這也就是為什麼上面我們會先讓他的方向設為預設的 portrait
再切回 landscapeRight
. 我曾經誤以為介面會不會旋轉回去一次再賺回來,但是實際測試發現倒是沒有出現類似的情景。