本文计划使用AVPlayer
和AVPlayerLayer
播放视频格式
m4v:MP4的特殊类型,MP4格式的高清;可包含字幕
mp4:音频、视频信息的压缩编码标准。
srt:字幕文件格式
一.播放m4v格式
可通过MP4格式的文件+字幕文件合成m4v格式,可用Subler 工具合成
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
func playMovieFromLocalFile ( fileFullName: String ) -> Bool {
guard FileManager . default . fileExists ( atPath: fileFullName ) else {
debugPrint ( "\(fileFullName) not Found" )
return false
}
//加载视频文件资源(包括视频与所有字幕)
let asset = AVAsset ( url: URL ( fileURLWithPath: fileFullName ))
let playerItem = AVPlayerItem ( asset: asset )
//视频文件中所有支持的字幕
for characteristic in asset . availableMediaCharacteristicsWithMediaSelectionOptions {
debugPrint ( "\(characteristic)" )
if let group = asset . mediaSelectionGroup ( forMediaCharacteristic: characteristic ) {
for option in group . options {
debugPrint ( " Option: \(option.displayName)" )
}
}
}
if let group = asset . mediaSelectionGroup ( forMediaCharacteristic: AVMediaCharacteristic . legible ) {
let locale = Locale ( identifier: "zh" )
let options =
AVMediaSelectionGroup . mediaSelectionOptions ( from: group . options , with: locale )
if let option = options . first {
// 如果支持中文,默认选中中文字幕
playerItem . select ( option , in : group )
}
}
player = AVPlayer ( playerItem: playerItem )
player ? . appliesMediaSelectionCriteriaAutomatically = false
if playerLayer == nil {
playerLayer = AVPlayerLayer ( player: player )
playerLayer ? . videoGravity = AVLayerVideoGravity . resizeAspectFill
playerContainerView ? . layer . addSublayer ( playerLayer ! )
}
setupPlayerObserverEvent ()
return true
}
override func viewDidAppear ( _ animated: Bool ) {
playerLayer ? . frame = playerContainerView ! . bounds
}
效果图如下:
二.播放mp4格式带srt字幕
mp4
文件和字幕srt
文件通过时间軕实现当前播放进度展示相应文本。
srt格式解析可参考AVPlayerViewController-Subtitles
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
func playMovie ( movieFile: String , captionFile: String ) -> Bool {
let fileManage = FileManager . default
guard fileManage . fileExists ( atPath: movieFile ) && fileManage . fileExists ( atPath: captionFile ) else {
debugPrint ( "movie:\(movieFile)/ or captionFile:\(captionFile)not found" )
return false
}
//加载视频文件
player = AVPlayer ( url: URL ( fileURLWithPath: movieFile ))
//加载视频文件对应字幕文件
parser = Subtitles ( file: URL ( fileURLWithPath: captionFile ))
//创建AVPlayerLayer并加入到视图层中
playerLayer = AVPlayerLayer ( player: player )
playerLayer ! . videoGravity = AVLayerVideoGravity . resizeAspectFill
playerContainerView ? . layer . addSublayer ( playerLayer ! )
setupPlayerObserverEvent ()
return true
}
效果图如下:
三.两种方式需要手动播放或暂停
1
2
3
4
5
6
7
8
9
10
11
12
13
@ IBAction func handleStartPlayerEvent ( sender: AnyObject ) {
isPlaying = true
player ? . play ()
}
@ IBAction func handlePausePlayerEvent ( sender: AnyObject ) {
if isPlaying {
player ? . pause ()
}
}
详细参考源代码