返回

深度解析:如何使用 AVPlayer 自定义全屏播放器(Swift 重构版)

IOS

在 iOS 开发中,AVPlayer 是一个强大的工具,可用于创建视频播放器应用程序。然而,如果您需要对默认播放器界面进行更多的控制,自定义 AVPlayer 是一个不错的选择。在本教程中,我们将深入研究如何使用 Swift 重新创建支持全屏的自定义 AVPlayer。

自定义 UI

自定义 AVPlayer 的第一步是自定义 UI。我们通过创建一个自定义 UIView 来实现这一点,该 UIView 将包含播放器控件。为了支持全屏,我们需要使用 Auto Layout 将视图约束到父视图。

class CustomPlayerView: UIView {

    // 创建播放器控件
    let playPauseButton = UIButton()
    let currentTimeLabel = UILabel()
    let durationLabel = UILabel()
    let progressSlider = UISlider()

    override init(frame: CGRect) {
        super.init(frame: frame)

        // 设置播放器控件
        playPauseButton.setImage(UIImage(systemName: "play"), for: .normal)
        playPauseButton.setImage(UIImage(systemName: "pause"), for: .selected)
        playPauseButton.addTarget(self, action: #selector(playPause), for: .touchUpInside)

        currentTimeLabel.text = "00:00"
        durationLabel.text = "00:00"

        progressSlider.minimumValue = 0
        progressSlider.maximumValue = 1
        progressSlider.addTarget(self, action: #selector(seek), for: .valueChanged)

        // 添加约束
        addSubview(playPauseButton)
        addSubview(currentTimeLabel)
        addSubview(durationLabel)
        addSubview(progressSlider)

        NSLayoutConstraint.activate([
            // 将按钮约束到父视图
            playPauseButton.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
            playPauseButton.topAnchor.constraint(equalTo: topAnchor, constant: 16),

            // 将当前时间标签约束到播放按钮旁边
            currentTimeLabel.leadingAnchor.constraint(equalTo: playPauseButton.trailingAnchor, constant: 8),
            currentTimeLabel.centerYAnchor.constraint(equalTo: playPauseButton.centerYAnchor),

            // 将持续时间标签约束到进度条旁边
            durationLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
            durationLabel.centerYAnchor.constraint(equalTo: currentTimeLabel.centerYAnchor),

            // 将进度条约束到按钮和标签之间
            progressSlider.leadingAnchor.constraint(equalTo: currentTimeLabel.trailingAnchor, constant: 8),
            progressSlider.trailingAnchor.constraint(equalTo: durationLabel.leadingAnchor, constant: -8),
            progressSlider.centerYAnchor.constraint(equalTo: playPauseButton.centerYAnchor)
        ])
    }

    // 播放/暂停按钮点击事件
    @objc func playPause() {
        // 根据按钮状态播放或暂停视频
        if playPauseButton.isSelected {
            player.pause()
            playPauseButton.isSelected = false
        } else {
            player.play()
            playPauseButton.isSelected = true
        }
    }

    // 进度条更改事件
    @objc func seek() {
        // 根据进度条值设置播放器时间
        player.seek(to: CMTime(seconds: Double(progressSlider.value), preferredTimescale: 1))
    }
}

支持全屏

接下来,我们需要支持全屏播放。为此,我们将响应设备旋转通知并相应调整播放器视图的约束。

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)

    // 如果设备横向旋转,进入全屏模式
    if UIDevice.current.orientation.isLandscape {
        // 更新播放器视图约束以填充屏幕
        playerView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        playerView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
        playerView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        playerView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    } else {
        // 如果设备竖向旋转,退出全屏模式
        // 重置播放器视图约束以恢复原始大小
        playerView.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor).isActive = true
        playerView.bottomAnchor.constraint(equalTo: bottomLayoutGuide.topAnchor).isActive = true
        playerView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        playerView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    }

    // 激活约束并强制布局
    view.layoutIfNeeded()
}

使用自定义播放器

有了自定义播放器视图,现在我们可以将其用于播放视频。为此,我们将创建一个 AVPlayer 对象并将其添加到自定义播放器视图中。

class ViewController: UIViewController {

    private var player: AVPlayer!
    private var playerView: CustomPlayerView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // 创建 AVPlayer 对象
        let url = URL(string: "path/to/video.mp4")!
        player = AVPlayer(url: url)

        // 创建自定义播放器视图并添加到视图层次结构
        playerView = CustomPlayerView(frame: view.bounds)
        view.addSubview(playerView)

        // 设置播放器视图的 AVPlayer
        playerView.player = player

        // 开始播放视频
        player.play()
    }
}

结论

通过使用 Swift 重新创建 AVPlayer,我们可以获得对播放器界面和功能的完全控制。自定义 UI 使我们能够创建独特的播放器体验,而全屏支持则为用户提供了更沉浸式的观看体验。通过遵循本教程中的步骤,您可以创建自己的自定义 AVPlayer 并将其集成到 iOS 应用程序中。