阿里云点播SDK集成(二)封装篇
1.上篇说到阿里云的文件上传以及注意的一些事项,今天就来说说简单的封装一下阿里云的播放器,简单说下思路(ps:在tableView或collectionView上用。为了节省资源以及滚动的流畅度,我们全局只用到1个播放器,提前加载视频并缓存本地,在滚动到当前视频的时候才去将播放器添加到cell上进行播放,滚动到下一个视频的时候会删除上一个播放器,网速好的情况下很流畅,其次也是看阿里云的视频解码速度 )
class PlayerManager: NSObject { /// 播放器superview let playSuperView = UIView() /// 播放器view let playView = UIView() /// 进度view fileprivate let progressView = UIProgressView() /// 播放器状态view fileprivate let playStatusImgView = UIImageView(image: UIImage(named: "icon_search_play")) /// 播放器 let player = AliPlayer() /// 代理 fileprivate weak var vc: PlayerListDelete! /// 当前正在播放视频的索引 var currentIndex: Int = -1 { didSet{ print("current index =>:\(currentIndex)") } } /// 播放状态 用来控制播放器播放状态 fileprivate var playerStatus_: AVPStatus = AVPStatusIdle { didSet {
//监听播放器状态,暂停就显示播放按钮,播放就隐藏播放按钮 playStatusImgView.isHidden = playerStatus_ == AVPStatusStarted } } weak var delegate: PlayerManagerDelegate? /// 实际播放状态 给外部使用 var playerStatus: AVPStatus = AVPStatusIdle /// 是否能够播放 var canPlay = true { didSet { if canPlay && isShow && playerStatus_ != AVPStatusPaused && playerStatus_ != AVPStatusStopped && playerStatus_ != AVPStatusError { resume() playStatusImgView.isHidden = true } else { player?.pause() playStatusImgView.isHidden = false } } } /// 构造函数 init(vc: VVPlayerListDelete) { super.init() self.vc = vc initPlayer() initUI() } fileprivate func initPlayer() { AliPrivateService.initLicense() player?.isLoop = false player?.isAutoPlay = true player?.scalingMode = AVP_SCALINGMODE_SCALEASPECTFIT let playConfig = player?.getConfig() playConfig?.clearShowWhenStop = true player?.setConfig(playConfig) player?.delegate = self AliListPlayer.setEnableLog(true) } fileprivate func initUI() { player?.playerView = playView playSuperView.backgroundColor = .black playSuperView.addSubview(playView) playSuperView.isHidden = true playStatusImgView.contentMode = .scaleAspectFit playStatusImgView.isHidden = true playSuperView.addSubview(playStatusImgView) playStatusImgView.snp.makeConstraints { (make) in make.center.equalToSuperview() } progressView.progressTintColor = .white progressView.backgroundColor = UIColor(white: 1, alpha: 0.2) progressView.isHidden = true playSuperView.addSubview(progressView) progressView.snp.makeConstraints { (make) in make.left.right.equalToSuperview() make.bottom.equalToSuperview().offset(0) make.height.equalTo(20) } }
//适配大小 fileprivate func setPlayerscalingMode() { if let trackInfo = player?.getMediaInfo()?.tracks.first { if trackInfo.videoWidth < trackInfo.videoHeight { player?.scalingMode = AVP_SCALINGMODE_SCALEASPECTFILL } else { player?.scalingMode = AVP_SCALINGMODE_SCALEASPECTFIT } let width = SCREEN_WIDTH var height = playSuperView.frame.height let scaleX = (CGFloat)(trackInfo.videoHeight) / (CGFloat)(trackInfo.videoWidth) height = scaleX * width height = height > playSuperView.frame.height ? height : playSuperView.frame.height let criticalScale = height / playSuperView.frame.height if criticalScale >= 0.8 { height = playSuperView.frame.height } playView.frame = CGRect(x: 0, y: 0, width: width, height: height) } } }
2.封装播放组件api
// MARK:- 外部使用api extension PlayerManager { /// 停止播放 func stop() { player?.stop() playerStatus_ = AVPStatusStopped delegate?.playStatusChange(isPause: false) } /// 暂停 func pause() { player?.pause() playerStatus_ = AVPStatusPaused delegate?.playStatusChange(isPause: true) } /// 恢复播放 func resume() { player?.start() playerStatus_ = AVPStatusStarted delegate?.playStatusChange(isPause: false) } /// 播放指定索引的视频 func playAtIndex(index: Int, vid: String) { progressView.setProgress(0, animated: false) currentIndex = index playSuperView.frame = vc.playerList(playerManager: self, frameForIndexAt: index) player?.playerView.frame = playSuperView.bounds let source = AVPVidStsSource() source.vid = vid source.region = STSManager.shared.region source.securityToken = STSManager.shared.securityToken source.accessKeySecret = STSManager.shared.accessKeySecret source.accessKeyId = STSManager.shared.accessKeyId self.player?.setStsSource(source) self.player?.prepare() if canPlay { resume() } else { player?.pause() } } /// 单击暂停或者播放 func singleTap() { switch playerStatus_ { case AVPStatusStarted: pause() default: resume() } } func removePlayView() { playSuperView.removeFromSuperview() playSuperView.isHidden = true player?.stop() currentIndex = -1 } /// 移除某个video func removeVideo(index: Int) { currentIndex = -1 } func updatePlayerStatus(withControllerStatus status: PlayerListControllerStatus) { if status == .active { canPlay = true } else { canPlay = false } } }
3.根据代理设置监听,涉及到播放进度或者播放完成等一些事件可以在这里监听
extension VVPlayerManager: AVPDelegate { func onError(_ player: AliPlayer!, errorModel: AVPErrorModel!) { playerStatus_ = AVPStatusStopped if errorModel.code.rawValue == 537198597 || errorModel.code.rawValue == 537067523 { delegate?.playerManage(AuthorityExpired: self) } print("________playermanager________ 播放失败 => \(String(describing: errorModel.message))") VVSTSManager.shared.updateSts() } func onPlayerEvent(_ player: AliPlayer!, eventType: AVPEventType) { print("________playermanager________ \(eventType)") switch eventType { case AVPEventPrepareDone: setPlayerscalingMode() case AVPEventFirstRenderedStart: playSuperView.isHidden = false case AVPEventLoopingStart: //一次完整视频播放完成 self.delegate?.aCompletePlaybackIsCompleted() case AVPEventCompletion: self.delegate?.playbackCompleted() default: break } } func onPlayerStatusChanged(_ player: AliPlayer!, oldStatus: AVPStatus, newStatus: AVPStatus) { playerStatus = newStatus } func onLoadingProgress(_ player: AliPlayer!, progress: Float) { } func onCurrentPositionUpdate(_ player: AliPlayer!, position: Int64) { let duration: Float = Float(player.duration) let position: Float = Float(position) let current: Float = position / duration self.delegate?.playChange(progressVaues: current, totalProgress: duration, currentProgress: position) } }
以上就是阿里云播放器的简单封装,有问题的请在下方评论,看到后第1时间回复