阿里云点播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时间回复

浙公网安备 33010602011771号