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

 

posted @ 2024-09-26 11:35  哇哈爽  阅读(9)  评论(0编辑  收藏  举报