使用AVPlayer自定義支援全螢幕的播放器(五)—Swift重構版本

前言

很早之前開源了一個簡單的影片播放器,由於年久失修,效果慘目忍睹,最近特意花時間對其進行了深度重構。舊版本後期不再維護,新版本使用Swift實現,後續會增加更多功能。不想看文字的請自行下載程式碼——>>>CLPlayer

舊版本 VS 重構版本

1.新版本使用Swift,舊版本使用Objective-C

2.新版本採用自定義轉場實現全螢幕,舊版本使用旋轉螢幕

3.新版本不需要手動銷毀播放器

4.新版本修復了老版本遺留bug

5.新版本降低了程式碼耦合性

6.新版本增加了倍數播放,切換填充模式

7.新版本提供更豐富的API

8.新版本適配了iPhone X

9.新版本移除了狀態欄相關配置

效果

效果圖

全螢幕

控制面板

3.png

4.png

功能

  • [x] 支援全螢幕模式、小屏模式
  • [x] 支援跟隨手機自動旋轉
  • [x] 支援本地影片、網路URL
  • [x] 支援UITableView
  • [x] 支援UICollectionView
  • [x] 支援手勢改變螢幕的亮度(螢幕左半邊)
  • [x] 支援手勢改變音量大小(螢幕右半邊)
  • [x] 支援拖動UISlider快進快退
  • [x] 支援iPhone X留海屏
  • [x] 支援倍速播放(0.5X、1.0X、1.25X、1.5X、1.75X、2X
  • [x] 支援動態改變播放器的填充模式(適應、拉伸、填充
  • [x] 支援cocoapods

接入指南

項目必須支援全螢幕,建議將螢幕支援方向交由當前顯示的控制器自行管理。

項目支援全螢幕方案

1.先勾選支援方向,只保留portrait,保證APP啟動不會橫屏

5.png

2.AppDelegate中重寫func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {}方法

func application(_: UIApplication, supportedInterfaceOrientationsFor _: UIWindow?) -> UIInterfaceOrientationMask {
        return .allButUpsideDown
}

3.在父類中重寫螢幕控制相關方法

UITabBarController

// 是否支援自動轉屏
override var shouldAutorotate: Bool {
    guard let navigationController = selectedViewController as? UINavigationController else { return selectedViewController?.shouldAutorotate ?? false }
    return navigationController.topViewController?.shouldAutorotate ?? false
}

// 支援哪些螢幕方向
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    guard let navigationController = selectedViewController as? UINavigationController else { return selectedViewController?.supportedInterfaceOrientations ?? .portrait }
    return navigationController.topViewController?.supportedInterfaceOrientations ?? .portrait
}

// 默認的螢幕方向(當前ViewController必須是通過模態出來的UIViewController(模態帶導航的無效)方式展現出來的,才會調用這個方法)
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
    guard let navigationController = selectedViewController as? UINavigationController else { return selectedViewController?.preferredInterfaceOrientationForPresentation ?? .portrait }
    return navigationController.topViewController?.preferredInterfaceOrientationForPresentation ?? .portrait
}

UINavigationController

// 是否支援自動轉屏
override var shouldAutorotate: Bool {
    return topViewController?.shouldAutorotate ?? false
}

// 支援哪些螢幕方向
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return topViewController?.supportedInterfaceOrientations ?? .portrait
}

// 默認的螢幕方向(當前ViewController必須是通過模態出來的UIViewController(模態帶導航的無效)方式展現出來的,才會調用這個方法)
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
    return topViewController?.preferredInterfaceOrientationForPresentation ?? .portrait
}

UIViewController

// 是否支援自動轉屏
override var shouldAutorotate: Bool {
    return true
}

// 支援哪些螢幕方向
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return .portrait
}

// 默認的螢幕方向(當前ViewController必須是通過模態出來的UIViewController(模態帶導航的無效)方式展現出來的,才會調用這個方法)
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
    return .portrait
}

4.部分頁面需要支援多方向

在對應控制器中重寫以下方法

override var shouldAutorotate: Bool {
    return true
}

// 支援哪些螢幕方向
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return .allButUpsideDown
}

基礎配置

public struct CLPlayerConfigure {
    /// 頂部工具條隱藏風格
    public enum CLPlayerTopBarHiddenStyle {
        /// 小屏和全螢幕都不隱藏
        case never
        /// 小屏和全螢幕都隱藏
        case always
        /// 小屏隱藏,全螢幕不隱藏
        case onlySmall
    }

    /// 自動旋轉
    public var isAutoRotate = true
    /// 手勢控制
    public var isGestureInteractionEnabled = true
    /// 是否顯示更多面板
    public var isShowMorePanel = true
    /// 頂部工具條隱藏風格
    public var topBarHiddenStyle: CLPlayerTopBarHiddenStyle = .onlySmall
    /// 工具條自動消失時間
    public var autoFadeOut: TimeInterval = 5
    /// 默認拉伸方式
    public var videoGravity: AVLayerVideoGravity = .resizeAspectFill
    /// 頂部工具條背景顏色
    public var topToobarBackgroundColor: UIColor = .black.withAlphaComponent(0.6)
    /// 底部工具條背景顏色
    public var bottomToolbarBackgroundColor: UIColor = .black.withAlphaComponent(0.6)
    /// 進度條背景顏色
    public var progressBackgroundColor: UIColor = .white.withAlphaComponent(0.35)
    /// 緩衝條緩衝進度顏色
    public var progressBufferColor: UIColor = .white.withAlphaComponent(0.5)
    /// 進度條播放完成顏色
    public var progressFinishedColor: UIColor = .white
    /// 轉子背景顏色
    public var loadingBackgroundColor: UIColor = .white
    /// 返回按鈕圖片
    public var backImage: UIImage?
    /// 更多按鈕圖片
    public var moreImage: UIImage?
    /// 播放按鈕圖片
    public var playImage: UIImage?
    /// 暫停按鈕圖片
    public var pauseImage: UIImage?
    /// 進度滑塊圖片
    public var sliderImage: UIImage?
    /// 最大化按鈕圖片
    public var maxImage: UIImage?
    /// 最小化按鈕圖片
    public var minImage: UIImage?
    /// 封面圖片
    public var maskImage: UIImage?
}

總結

本次重構為Swift第一版,後續會持續更新,訂製化開發請自行參考CLPlayer修改 , 如果喜歡,歡迎star。

參考資料

  1. iOS播放器全螢幕方案

  2. iOS狀態欄

  3. iOS播放器全螢幕旋轉實現

  4. iOS橫豎屏旋轉解決方案 – Swift

  5. iOS影片旋轉探究

  6. iOS螢幕旋轉的解決方案