AVPlayer是用于管理媒体资产的播放和定时控制器对象它提供了控制播放器的接口,如它可以在媒体的时限内播放,暂停,和改变播放的速度,并有定位各个动态点的能力。可以使用AVPlayer来播放本地和远程的视频媒体文件,如QuickTime影片和MP3音频文件,以及视听媒体使用HTTP流媒体直播服务。
import AVFoundation
internal class VedioPlayerView : UIView {
....
}
playerLayer = AVPlayerLayer.init(player: self.playerPub)
playerLayer.frame = self.bounds
self.layer.addSublayer(playerLayer)
internal var playerLayer: AVPlayerLayer! //播放层可添加其到指定的View,这里添加到self.layer
internal var playerPub: AVPlayer! //播放的视频,苹果原生播放控件
internal var url: String! //播放的网络地址
internal var fatherView: UIView! //放置playerPub的View
internal var holdImage: UIImage! //播放前显示的图片
internal var playSeekTimeDic: NSMutableDictionary! //记录播放时间的字典
NotificationCenter.default.addObserver(self, selector: #selector(appWillResignActive), name: .UIApplicationWillResignActive, object: nil) //播放退到后台通知
NotificationCenter.default.addObserver(self, selector: #selector(appDidBecomeActive), name: .UIApplicationDidBecomeActive, object: nil) //播放进入前台通知
NotificationCenter.default.addObserver(self, selector: #selector(deviceDidRotate(notification:)), name: .UIDeviceOrientationDidChange, object: nil) //屏幕旋转通知
NotificationCenter.default.addObserver(self, selector: #selector(videoPlayEnd), name: .AVPlayerItemDidPlayToEndTime, object: nil) //播放结束通知
internal class ControlView: UIView {
}
@IBOutlet weak internal var timelabel: UILabel! //记录播放时间的字典
@IBOutlet weak internal var fullScreenButton: UIButton! //记录播放时间的字典
@IBOutlet weak internal var progressView: UIProgressView! //记录播放时间的字典
@IBOutlet weak internal var videoPlaySlider: UISlider! //记录播放时间的字典
@IBOutlet weak internal var lightSlider: UISlider! //记录播放时间的字典
playerPub = AVPlayer.init(url: URL.init(string: url)!) //初始化一个播放URL地址的播放器
let seconds = playSeekTimeDic.value(forKey: video_idLog) as? Float ?? 0.0 //取出上次播放的时间位置
let cmTime = CMTime.init(seconds: Double(seconds), preferredTimescale: 1) //类型转换
playerPub.seek(to: cmTime) //播放上次记录的位置
playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
let item = playerPub.currentItem
let asset = item?.asset
let group = asset?.mediaSelectionGroup(forMediaCharacteristic: AVMediaCharacteristicLegible)
let locale = Locale.init(identifier: "zh_CN")
let options = AVMediaSelectionGroup.mediaSelectionOptions(from: (group?.options)!, with: locale)
item?.select(options.first, in: group!)
@IBAction func fullScreenButtonClicked(_ sender: UIButton) { //点击横竖屏切换按钮进行横竖屏切换
if UIDevice.current.orientation == UIDeviceOrientation.portrait {//切换到横屏
UIDevice.current.setValue(UIInterfaceOrientation.landscapeRight.rawValue, forKey: "orientation")
sender.isSelected = true
}else{//切换到竖屏
UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
sender.isSelected = false
}
}
func deviceDidRotate(notification:NSNotification){
if UIDeviceOrientationIsLandscape(UIDevice.current.orientation){
//横屏时
}else{
//竖屏时
}
}
self.removeFromSuperview() //在父窗口里移除播放器
self.frame = HorizontalFrame //播放器横屏全屏尺寸
playerLayer.frame = self.bounds //播放层横屏全屏尺寸
controlView.frame = playerLayer.frame //控制层视图横屏全屏尺寸
controlView.fullScreenButton.isSelected = true //控制层全屏按钮变为选中状态
UIApplication.shared.keyWindow?.addSubview(self) //把播放器加在视图最上层
self.removeFromSuperview() //在父窗口里移除播放器
self.frame = VerticalFrame //播放器竖屏窗口尺寸
playerLayer.frame = self.bounds //播放层竖屏窗口尺寸
controlView.fullScreenButton.isSelected = false //控制层全屏按钮变为未选中状态
fatherView.addSubview(self) //把播放器加回原先fatherView竖屏的窗口
playerPub.addPeriodicTimeObserver(forInterval: CMTime.init(value: 1, timescale: 2), queue: DispatchQueue.main) { (time) in
let currentTime = self.playerPub.currentTime() //获取当前播放时间
let totalTime = self.playerPub.currentItem?.duration //获取当总播放时间
let progress = CMTimeGetSeconds(currentTime) / CMTimeGetSeconds(totalTime!) //播放进度百分比
let text = "\(formatPlayTime(CMTimeGetSeconds(currentTime)))/\(formatPlayTime(CMTimeGetSeconds(totalTime!)))" //时间文字
self.controlVView.videoPlaySlider.value = Float(progress) //刷新播放进度百分比
self.controlVView.timelabel.text = text //刷新时间文字
}
func appWillResignActive(){
playerLayer.player = nil //开启后台播放功能
}
func appDidBecomeActive() {
playerLayer.player = playerPub //回到前台播放
}
deinit {
if (playerPub != nil) {
playerPub.removeTimeObserver(playObserver)
playerPub.removeObserver(self, forKeyPath: "status")
playerPub.currentItem?.removeObserver(self, forKeyPath: "loadedTimeRanges")
UserDefaults.standard.set(playSeekTimeDic, forKey: "playSeekTimeDic")
}
}
func playURL(_ urlString:String){
videoView.fatherView = videoBackgroundView //指定播放放到的视图
videoView.holdImage = UIImage.init(named: "NetWaiting") //播放的封面图
videoView.url = urlString //播放的网络地址
videoView.playerPub.play()//开始播放
}
@IBAction func playAndPause() {
if isPlaying == true {
videoView.playerPub.pause()
isPlaying = false
}else{
videoView.playerPub.play()
isPlaying = true
}
}
@IBOutlet weak var TapGestureRecognizerOneTappes: UITapGestureRecognizer!
@IBAction func videoViewOneTap(_ sender: UITapGestureRecognizer) {
if playButton.isHidden == true {
var alpha = CGFloat(0.50)
if self.controlVView.alpha == CGFloat(0.50) { //显示和消失状态切换
alpha = 0
}
UIView.animate(withDuration: 0.6) { //切换时的动画
self.controlView.alpha = CGFloat(alpha)
}
}
}
@IBOutlet weak var ShareView: VideoDetailShareView!
@IBAction func shareButtonClicked(_ sender: UIButton) {
ShareView.fatherView = view
}