播放视频的界面现在只剩下视频的功能了,对于这种播放视频的应该属于功能块。我们可以单独把这个功能提取出来。
我们新建一个包Plugins
专门放置各种功能,我称作为插件。因为要封装的功能是被其他人一键调用,别人无需知道实现,只要知道接口即可,在其他人眼中也就是Manger
功能。
我们在Plugins
包里面新建一个Video
的包。
对于播放视频的功能只在2013年做过,貌似叫做MP开头的类,差不多忘记了。我们可以谷歌一下,不怕不会,只怕不会搜索。
我们轻松的搜到播放视频需要这个类MPMoviePlayerController
,我们导入试一下。
import MediaPlayer
我们新建一个类VideoPlugin
先做一个叫做playVideo
方法试一下是否能播放。
func playVideo() {
let videoFile = Bundle.main.path(forResource: "app_splash_movie", ofType: "mp4")
assert((videoFile != nil),"视频地址不能为空!")
let videoUrl = URL(fileURLWithPath:videoFile!)
let videoPlay = MPMoviePlayerViewController(contentURL: videoUrl)
}
当我去查看怎么播放时候,发现MPMoviePlayerViewController
已经在iOS9
之后过时。系统提示用Use AVPlayerViewController in AVKit.
既然MPMoviePlayerViewController
这个类已经过时了,我们就导入AVKit
使用最新的类AVPlayerViewController
如果这个类是9.0之后出的,我们就做兼容模式,如果8.0就出现了,我们就可以直接使用最新的,因为我们是从iOS8.0开始的。
@available(iOS 8.0, *)
open class AVPlayerViewController : UIViewController {
果然和我们预想的一样,果然是兼容iOS8.0的。我们把代码改成下面的样子。
let videoPlay = AVPlayerViewController()
发现AVPlayerViewController
已经不像MPMoviePlayerViewController
这样的初始化,应该有其他的方法。
open var player: AVPlayer?
我们第一眼就看到这个属性,看名字很像。点进入发现类方法需要传入我们刚才的文件地址,并且有播放和暂停等功能。这个应该是我们所需要的。
let videoPlay = AVPlayer(url: videoUrl)
let videoPlayController = AVPlayerViewController()
我们需要放置在我们播放视频界面的模板上面,我们就写一个初始化方法让外部把父试图传进来。
init(contentView:UIView) {
videoView = contentView
super.init()
}
再次修改我们的代码
func playVideo() {
let videoFile = Bundle.main.path(forResource: "app_splash_movie", ofType: "mp4")
assert((videoFile != nil),"视频地址不能为空!")
let videoUrl = URL(fileURLWithPath:videoFile!)
let videoPlay = AVPlayer(url: videoUrl)
let videoPlayController = AVPlayerViewController()
videoPlayController.view.frame = videoView.frame
videoPlay.play()
}
在我们的播放界面测试一下。
/// 进入页面自动播放视频
func autoPlayVideo() {
let videoPlay = VideoPlugin(contentView: videoView)
videoPlay.playVideo()
}
我们在viewDidLoad
方法里面调用autoPlayVideo
发现并没有播放,原来是忘记addSubView
了,犯了低级错了。
黑乎乎的,应该界面是出来了,但是播放不了。
仔细的查看了代码,忘记给属性赋值。
open var player: AVPlayer?
我们赋值一下。再次试一下看看。
videoPlayController.player = videoPlay
播放的界面总算是出来了,但是点击按钮会崩溃,崩溃信息如下。
2016-11-07 10:57:13.541 BaiSiBuDeJie[14481:162524] 10:57:13.541 ERROR: 98: Error '!obj' trying to fetch default input device's sample rate
2016-11-07 10:57:13.541 BaiSiBuDeJie[14481:162524] 10:57:13.541 ERROR: 100: Error getting audio input device sample rate: '!obj'
2016-11-07 10:57:13.541 BaiSiBuDeJie[14481:162524] 10:57:13.541 WARNING: 230: The input device is 0x0; '(null)'
2016-11-07 10:57:13.541 BaiSiBuDeJie[14481:162524] 10:57:13.541 WARNING: 234: The output device is 0x27; 'AppleHDAEngineOutput:1B,0,1,2:0'
2016-11-07 10:57:13.542 BaiSiBuDeJie[14481:162524] 10:57:13.542 ERROR: 296: error '!obj'
2016-11-07 10:57:13.542 BaiSiBuDeJie[14481:162524] 10:57:13.542 ERROR: 113: * * * NULL AQIONode object
2016-11-07 10:57:13.542 BaiSiBuDeJie[14481:162344] 10:57:13.542 ERROR: 296: error -66680
2016-11-07 10:57:13.542 BaiSiBuDeJie[14481:162524] 10:57:13.542 ERROR: 703: Can't make UISound Renderer
2016-11-07 10:57:13.542 BaiSiBuDeJie[14481:162344] 10:57:13.542 ERROR: 296: error -66680
2016-11-07 10:57:13.543 BaiSiBuDeJie[14481:162344] 10:57:13.542 ERROR: 296: error -66680
2016-11-07 10:57:13.543 BaiSiBuDeJie[14481:162344] 10:57:13.543 ERROR: 296: error -66680
这错误信息看得我一头雾水,我们搜一下错误码试一下。
谷歌的意思,iOS模拟器要使用输入设备和输出设备,但是Mac电脑没有,会造成这样的结果。因为AVPlayer
造成这些错误的信息。
再次从AVPlayer
找到一个叫做Error
的属性,输入一下看看有什么错误的信息。然并卵,这个属性为nil,看来我们初始化也没有什么问题。
我们测试一下真机,看看问题是否解决。
经过测试视频可以正常的播放,但是一直悬浮功能栏,我们看看能不能去掉,有什么属性没有。
open var showsPlaybackControls: Bool
这个属性有点像,而且属性的默认值是true
,我们设置false
试一下。
经过测试也是可以的,界面看着有点丑 我们把按钮距离底部约束为40,删除之前的上约束。
这是最后的界面。
对应的工程文件下载下载