自定义 BMPlayer 控制 UI

已废弃 2017.5.3

前段时间使用 Swift 封装 AVPlayer, 发布了BMPlayer, 大家反馈还不错。骗到了 100 多个 Star。今天就继续优化一下,增加自定义 UI 的功能。

思路

自定义 UI 的实现方法主要用一下两种:

  1. 自定义一个基类 UIView,通过继承这个基类并重写方法来实现。
  2. 定义一个协议,通过遵循这个协议来实现。

我选择方法2,定义了协议 BMPlayerCustomControlView

用法

更换 pod 地址

自定义 UI 还处于试验阶段,请修改 pod 文件为

1
pod 'BMPlayer', :git => 'https://github.com/BrikerMan/BMPlayer.git'

运行命令 pod update

创建View

按照自己习惯初始化一个 UIView,绘制UI。例如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class CustomControlView: UIView {
/// 主体
var mainMaskView = UIView()
var topMaskView = UIView()
var bottomMaskView = UIView()
var maskImageView = UIImageView()

/// 顶部
var backButton = UIButton(type: UIButtonType.Custom)
var titleLabel = UILabel()
var chooseDefitionView = UIView()

/// 底部
var currentTimeLabel = UILabel()
var totalTimeLabel = UILabel()

var timeSlider = BMTimeSlider()
var progressView = UIProgressView()

var playButton = UIButton(type: UIButtonType.Custom)
var fullScreenButton = UIButton(type: UIButtonType.Custom)

...
}

关联 UI 元素

使当前的 View 遵循协议 BMPlayerCustomControlView,并把关键 UI 元素表明,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class CustomControlView: UIView, BMPlayerCustomControlView {
...
weak var delegate: BMPlayerControlViewDelegate?
var playerTitleLabel : UILabel? { get { return titleLabel } }
var playerCurrentTimeLabel : UILabel? { get { return currentTimeLabel } }
var playerTotalTimeLabel : UILabel? { get { return totalTimeLabel } }

var playerPlayButton : UIButton? { get { return playButton } }
var playerFullScreenButton : UIButton? { get { return fullScreenButton } }
var playerBackButton : UIButton? { get { return backButton } }

var playerTimeSlider : UISlider? { get { return timeSlider } }
var playerProgressView : UIProgressView? { get { return progressView } }

// 若不存在,则直接返回 nil
var playerSlowButton : UIButton? { get { return nil } }
var playerMirrorButton : UIButton? { get { return nil } }

...
}

实现方法

实现协议方法,方法比较多,如果不需要则只需写出方法,内容留空即可。Player 会根据播放器状态调用这些方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
class CustomControlView: UIView, BMPlayerCustomControlView {
...

/**
初始化播放器后调用,用于根据分辨率list绘制UI。
*/
func prepareChooseDefinitionView(items:[BMPlayerItemDefinitionProtocol], index: Int) { }

/**
用于更新UI,横竖屏切换时候调用,需要根据传入参数 isForFullScreen 来调整 UI

- parameter isForFullScreen: is fullscreen
*/
func updateUI(isForFullScreen: Bool) { }

/**
正在缓冲状态,播放器在缓冲时调用该方法
*/
func showLoader() { }

/**
缓冲结束状态,播放器在缓冲结束时用该方法
*/
func hideLoader() { }

/**
用于显示UI元素,当用户点击以显示 UI 元素时候调用
*/
func showPlayerUIComponents() { }

/**
用于隐藏UI元素,当用户点击以隐藏 UI 元素时候调用
*/
func hidePlayerUIComponents() { }

/**
播放器播放结束后调用,用于展示重播按钮等。
*/
func showPlayToTheEndView() { }

/**
当用户在播放器滑动快进快退时调用来显示快进信息 view

- parameter to: 目标时间
- parameter isAdd: 是否快进
*/
func showSeekToView(to:NSTimeInterval, isAdd: Bool) { }

/**
用于隐藏上述快进信息 view
*/
func hideSeekToView() { }

/**
当需要显示视频封面时调用

- parameter cover: cover url
*/
func showCoverWithLink(cover:String) { }

/**
当需要隐藏视频封面时调用
*/
func hideCoverImageView() { }

...
}

初始化播放器

需要按一下方法初始化。

1
2
3
// 先初始化自定义控制 View,然后初始化播放器
let customView = CustomControlView()
let player = BMPlayer(customControllView: customView)

More

更多细节可以看播放器 BMPlayerControlView 的实现,完全使用该协议实现了本UI。
其他问题欢迎评论讨论。