查具体属性文档: https://help.aliyun.com/document_detail/125572.html?spm=a2c4g.11186623.6.1179.131d10e43Evs78

一、安装插件 vue-aliplayer

npm install --save vue-aliplayer

二、vue-aliplayer 文件引入使用

1、在config/index.ts下,设置常规变量
// 常规配置
const config = {
  host:"https://zyapi.23544.com",
  aliplayercomponentsUrl:'/libs/aliplayercomponents-1.1.2.min.js',
  aliplayerUrl:"https://g.alicdn.com/apsara-media-box/imp-web-player/2.21.0/aliplayer-min.js"
}

export { config }
2、在App.vue中使用
<script setup lang="ts">
import { onMounted } from 'vue'
import { config } from '@/config'
onMounted(() => {
  //等待首页加载完成后在加载阿里播放器
  if(!document.getElementById('aliplayerScript')){
    const script = document.createElement('script')
    script.src = config.aliplayerUrl
    script.setAttribute('id','aliplayerScript')
    document.body.appendChild(script)
  }
  if(!document.getElementById('aliplayercomponents')){
    const script = document.createElement('script')
    script.src = config.aliplayercomponentsUrl
    script.setAttribute('id','aliplayercomponents')
    document.body.appendChild(script)
  }
})
</script>

三、创建组件文件 Aliplayer.vue

1、vue2 + 直播版本

(1)组件
<template>
  <div class='prism-player' :id='playerId' :style='playStyle'></div>
</template>

<script>
  export default {
    name: 'Aliplayer',
    props: {
      playStyle: {
        type: String,
        default: ''
      },
      aliplayerSdkPath: {
        // Aliplayer 代码的路径
        type: String,
        default: '//g.alicdn.com/de/prismplayer/2.9.3/aliplayer-min.js'
      },
      autoplay: {
        //播放器是否自动播放,在移动端autoplay属性会失效
        type: Boolean,
        default: true
      },
      isLive: {
        type: Boolean,
        default: true
      },
      playsinline: {
        type: Boolean,
        default: false
      },
      width: {
        type: String,
        default: '100%'
      },
      height: {
        type: String,
        default: '500px'
      },
      controlBarVisibility: {
        // 控制面板的实现,默认值为:hover。取值:
        // click:点击。
        // hover:停留。
        // always:一直。
        type: String,
        default: 'always'
      },
      useH5Prism: {
        type: Boolean,
        default: false
      },
      useFlashPrism: {
        type: Boolean,
        default: false
      },
      vid: {
        //媒体转码服务的媒体Id
        type: String,
        default: ''
      },
      playauth: {
        //播放权证
        type: String,
        default: ''
      },
      source: {
        //视频播放地址url
        type: String,
        default: ''
      },
      cover: {
        //播放器默认封面图片,请填写正确的图片url地址。需要autoplay值为false时,才生效
        type: String,
        default: ''
      },
      format: {
        //指定播放地址格式
        type: String,
        default: ''
      },
      x5_video_position: {
        type: String,
        default: 'top'
      },
      x5_type: {
        type: String,
        default: 'h5'
      },
      x5_fullscreen: {
        type: Boolean,
        default: false
      },
      x5_orientation: {
        type: Number,
        default: 2
      },
      autoPlayDelay: {
        type: Number,
        default: 0
      },
      autoPlayDelayDisplayText: {
        type: String
      }
    },
    data () {
      return {
        playerId: "aliplayer_" +
        Math.random().toString(36).substr(2),
        scriptTagStatus: 0,
        instance: null,
      }
    },
    created () {
      if (window.Aliplayer !== undefined) {
        // 如果全局对象存在,说明编辑器代码已经初始化完成,直接加载编辑器
        this.scriptTagStatus = 2
        this.initAliplayer()
      } else {
        // 如果全局对象不存在,说明编辑器代码还没有加载完成,需要加载编辑器代码
        this.insertScriptTag()
      }
    },
    mounted () {
      if (window.Aliplayer !== undefined) {
        // 如果全局对象存在,说明编辑器代码已经初始化完成,直接加载编辑器
        this.scriptTagStatus = 2
        this.initAliplayer()
      } else {
        // 如果全局对象不存在,说明编辑器代码还没有加载完成,需要加载编辑器代码
        this.insertScriptTag()
      }
    },
    unmounted(){
      this.ended()
    },
    methods: {
      insertScriptTag () {
        const _this = this
        let playerScriptTag = document.getElementById('playerScriptTag')
        // 如果这个tag不存在,则生成相关代码tag以加载代码
        if (playerScriptTag === null) {
          playerScriptTag = document.createElement('script')
          playerScriptTag.type = 'text/javascript'
          playerScriptTag.src = this.aliplayerSdkPath
          playerScriptTag.id = 'playerScriptTag'
          let s = document.getElementsByTagName('head')[0]
          s.appendChild(playerScriptTag)
        }
        if (playerScriptTag.loaded) {
          _this.scriptTagStatus++
        } else {
          playerScriptTag.addEventListener('load', () => {
            _this.scriptTagStatus++
            playerScriptTag.loaded = true
            _this.initAliplayer()
          })
        }
        _this.initAliplayer()
      },
      initAliplayer () {
        const _this = this
        // scriptTagStatus 为 2 的时候,说明两个必需引入的 js 文件都已经被引入,且加载完成
        if (_this.scriptTagStatus === 2 && _this.instance === null) {
          // Vue 异步执行 DOM 更新,这样一来代码执行到这里的时候可能 template 里面的 script 标签还没真正创建
          // 所以,我们只能在 nextTick 里面初始化 Aliplayer
          _this.$nextTick(() => {
            _this.instance = window.Aliplayer({
              id: _this.playerId,
              autoplay: _this.autoplay,
              isLive: _this.isLive,
              playsinline: _this.playsinline,
              format: _this.format,
              width: _this.width,
              height: _this.height,
              controlBarVisibility: _this.controlBarVisibility,
              useH5Prism: _this.useH5Prism,
              useFlashPrism: _this.useFlashPrism,
              vid: _this.vid,
              playauth: _this.playauth,
              source: _this.source,
              cover: _this.cover,
              x5_video_position: _this.x5_video_position,
              x5_type: _this.x5_type,
              x5_fullscreen: _this.x5_fullscreen,
              x5_orientation: _this.x5_orientation,
              autoPlayDelay: _this.autoPlayDelay,
              autoPlayDelayDisplayText: _this.autoPlayDelayDisplayText
            })
            // 绑定事件,当 AliPlayer 初始化完成后,将编辑器实例通过自定义的 ready 事件交出去
            _this.instance.on('ready', () => {
              this.$emit('ready', _this.instance)
            })
            _this.instance.on('play', () => {
              this.$emit('play', _this.instance)
            })
            _this.instance.on('pause', () => {
              this.$emit('pause', _this.instance)
            })
            _this.instance.on('ended', () => {
              this.$emit('ended', _this.instance)
            })
            _this.instance.on('liveStreamStop', () => {
              this.$emit('liveStreamStop', _this.instance)
            })
            _this.instance.on('m3u8Retry', () => {
              this.$emit('m3u8Retry', _this.instance)
            })
            _this.instance.on('hideBar', () => {
              this.$emit('hideBar', _this.instance)
            })
            _this.instance.on('waiting', () => {
              this.$emit('waiting', _this.instance)
            })
            _this.instance.on('snapshoted', () => {
              this.$emit('snapshoted', _this.instance)
            })
          })
        }
      },
      // 播放视频
      play: function () {
        this.instance.play()
      },
      // 暂停视频
      pause: function () {
        this.instance.pause()
      },
      // 结束视频
      ended: function () {
        this.instance.dispose()
      },
      // 重播视频
      replay: function () {
        this.instance.replay()
      },
      /**
       * 跳转到某个时刻进行播放
       * @argument time 的单位为秒
       */
      seek: function (time) {
        this.instance.seek(time)
      },
      /**
       * 获取当前时间 单位秒
       */
      getCurrentTime: function () {
        return this.instance.getCurrentTime()
      },
      /**
       *获取视频总时长,返回的单位为秒
       * @returns 返回的单位为秒
       */
      getDuration: function () {
        return this.instance.getDuration()
      },
      /**
       获取当前的音量,返回值为0-1的实数ios和部分android会失效
       */
      getVolume: function () {
        return this.instance.getVolume()
      },
      /**
       *直接播放视频url,time为可选值(单位秒)目前只支持同种格式(mp4/flv/m3u8)之间切换暂不支持直播rtmp流切换
       *@argument url 视频地址
       *@argument time 跳转到多少秒
       */
      loadByUrl: function (url) {
        this.instance.loadByUrl(url)
      },
      /**
       * 直播流中断时触发。M3U8、FLV、RTMP在重试5次未成功后触发。提示上层流中断或需要重新加载视频。
       */
      liveStreamStop:function() {
        this.instance.liveStreamStop()
      },
      /**
       * M3U8直播流中断后重试事件,每次断流只触发一次。
       */
      m3u8Retry:function() {
        this.instance.m3u8Retry()
      },
      /**
       * 设置播放器大小w,h可分别为400px像素或60%百分比chrome浏览器下flash播放器分别不能小于397x297
       *@argument w 播放器宽度
       *@argument h 播放器高度
       */
      setPlayerSize: function (w, h) {
        this.instance.setPlayerSize(w, h)
      },
      /**
       * 目前只支持HTML5界面上的重载功能,暂不支持直播rtmp流切换m3u8)之间切换,暂不支持直播rtmp流切换
       *@argument vid 视频id
       *@argument playauth 播放凭证
       */
      reloaduserPlayInfoAndVidRequestMts: function (vid, playauth) {
        this.instance.reloaduserPlayInfoAndVidRequestMts(vid, playauth)
      },

    }
  }
</script>

<style>
  @import url(//g.alicdn.com/de/prismplayer/2.9.3/skins/default/aliplayer-min.css);
  .prism-player video{
    background: url('../../../assets/img/login.png') no-repeat;
    background-size: 100% 100%;
  }
  .prism-setting-btn, .prism-cc-btn, .prism-big-play-btn.pause{
    display: none;
  }
</style>

(2)页面调用
<template>
<div>
   <aliplayer v-if="videoUrl" class="aliplayer_box" ref="player" @liveStreamStop="liveStreamStop($event)" :autoplay="true" :isLive="isLive" :rePlay="false" showBuffer="false" showBarTime="5000" format="m3u8" 
 :source="videoUrl"></aliplayer>
</div>
</template>

<script>
import aliplayer from '@/components/Aliplayer.vue' // 引入
export default {
    components:{ aliplayer },
    data(){
      return{
         isLive: false,
         visitable: false
      }
    },
    method: {
        // 直播播放器
        init(isLive){
            this.isLive = this.isLive
            this.visitable = true
        }
        liveStreamStop(event){
            // message('直播失败或直播已结束')
            this.visitable = event
        }
    }
}
</script>

2、vue3 + 录播版本

(1)组件
<template>
  <div class="video">
    <div style="width: 100%;height: 100%" class="prism-player" id="J_prismPlayer"></div>
  </div>
</template>
<script lang='ts' setup>
import { onMounted, nextTick, onUnmounted } from 'vue';

type TProps = {
  videoList: any[],
  url: string,
  currTime: number
  coverURL:string
}

const props = withDefaults(defineProps<TProps>(), {})
const emits = defineEmits(['on-pause', 'on-play', 'on-timeupdate', 'on-ompleteSeek'])
let play: any = null

onMounted(() => {
  let str = ''
  if (props.videoList) {
    props.videoList?.forEach((item, index) => {
      if ((props.videoList.length - 1) === index) {
        str += `"${item.Definition}":"${item.Url}"`
      } else {
        str += `"${item.Definition}":"${item.Url}",`
      }

    })
  } else {
    str = props.url
  }

  console.log(str);
  nextTick(() => {
    //@ts-ignore
    play = new Aliplayer({
      id: 'J_prismPlayer',
      source: props.videoList ? `{${str}}` : str, // 播放地址,可以是第三方点播地址,或阿里云点播服务中的播放地址。
      cover:props.coverURL,
      useH5Prism: true,
      width:'50%',
      height:'',
      preload:true,
      "controlBarVisibility": "always",
      skinLayout: [
      {
      "name": "H5Loading",
      "align": "cc"
    },
        { name: "bigPlayButton", align: "cc", x: 30, y: 80 },
        {name: "thumbnail"},
        {
        name: "controlBar", align: "blabs", x: 0, y: 0,
        children: [
          { name: "progress", align: "blabs", x: 0, y: 44 },
          { name: "playButton", align: "tl", x: 15, y: 12 },
          { name: "timeDisplay", align: "tl", x: 10, y: 7 },
          { name: "fullScreenButton", align: "tr", x: 10, y: 12 },
          { name: "setting", align: "tr", x: 15, y: 12 },
          { name: "volume", align: "tr", x: 5, y: 10 }
        ]
      }],
    }, function (player: any) {
      console.log('The player is created.', player)
    });
    play.on('ready', () => {
      play.seek(props.currTime)
    })
    play.on('pause', () => {
      emits('on-pause')
    })
    play.on('play', () => {
      emits('on-play')
    })
    play.on('timeupdate', () => {
      emits('on-timeupdate', play.getCurrentTime(), play.getDuration())
    })
    play.on('dispose', () => {
      play = null
    })
    play.on('click', () => {
      let playBtn = document.getElementsByClassName('prism-big-play-btn')[0]
      if (playBtn.style.display==='block') {
        if (play._status === 'playing') {
          play.pause()
        }
      } else {
        if (play._status==='pause') {
          play.play()
        } else {
          play.pause()
        }
      }
    })
    document.addEventListener('keydown', function (event) {
      if (event.keyCode === 32) {
        if (play&&play._status === 'playing') {
          play.pause()
        } else {
          play.play()
        }
      } else if (event.keyCode === 37) { //左键
        if (play) {
          var currentTime = play.getCurrentTime()
          play.seek(currentTime - 15)
        }
      } else if (event.keyCode === 39) { //右键
        if (play) {
          var currentTime = play.getCurrentTime()
          play.seek(currentTime + 15)
        }
      }
    })
  })
})

onUnmounted(() => {
  // 在组件卸载时移除点击事件监听
  document.removeEventListener('keydown', ()=>{})
  if (play) {
    play.dispose()
  }
})

</script>
<style lang='scss' scoped>
.video {
  width: 100%;
  height: 500px;
}
</style>
(2)页面调用
<aliPlayer :videoList="textCont?.VideoList" :coverURL="textCont.CoverURL" :url="textCont.Url" :currTime="textCont.ProgressTimes" @on-pause="onPause" @on-play="onPlay" @on-timeupdate="onLoadedmetadata" />

import aliPlayer from '@/components/aliPlayer/index.vue'
const textCont = ref({
    Url: 'https://cdn.23544.com/sv/2286901c-18a73b0bb25/2286901c-18a73b0bb25.mp4',
    ConvertPageCount: 0,
    Extension: 'mp4',
    Name: '《论语十二章》第一课时PPT.mp4',
    Type: false,
    MaterialType: '录播视频',
    Sort: 1,
    DownState: false,
    Children: null,
    DetailsId: 393,
    LearningNum: 0,
    Progress: 0,
    ProgressTime: 0,
    ProgressTimes: 0,
    MaxProgress: 0,
    VideoList: [
        {
            Url: 'https://cdn.23544.com/sv/2286901c-18a73b0bb25/2286901c-18a73b0bb25.mp4',
            Duration: '2728.683',
            Definition: 'OD',
            DefinitionName: '原画',
            Format: 'mp4'
        }
    ],
    CoverURL: 'https://cdn.23544.com/3b1513904e1971ee8a875017e1e90102/snapshots/98d409a88d6e4427a3a2aa4dc505959a-00005.jpg'
})
// 播放
const onPlay = () => {
}
// 暂停
const onPause = () => {
}
// 时间进度
const onLoadedmetadata = (currentTime: number, totalTime: number) => {
}
(3)视频打点插件
1、aliplayercomponents-1.1.2.min.js 需要先下载下来才能使用

下载地址:阿里云Aliplayer播放器

2、将下载好的 aliplayercomponents-1.1.2.min.js 放到 “ public/libs ” 文件夹下

3、引入请看 在App.vue中使用
4、页面使用
let play = new Aliplayer({
  id: 'J_prismPlayer',
  source: './video.mp4', // 播放地址,可以是第三方点播地址,或阿里云点播服务中的播放地址。
  cover:'https://alivc-demo-vod.aliyuncs.com/image/cover/9A3F562E595E4764AD1DD546FA52C6E5-6-2.png',
  useH5Prism: true,
  width:'50%',
  height:'',
  preload: false,
  progressMarkers:[{
    offset: 30,
    isCustomized:true,
    coverUrl: 'https://alivc-demo-vod.aliyuncs.com/image/cover/9A3F562E595E4764AD1DD546FA52C6E5-6-2.png',
    title: 'test title',
    describe: 'test string',
  }, {
    offset:50,
    isCustomized:true,
    coverUrl: 'https://alivc-demo-vod.aliyuncs.com/image/cover/1E7F402241CD4C0F94AD2BBB5CCC3EC7-6-2.png',
    title: 'test title',
    describe: 'test string',
  }, {
    offset:150,
    isCustomized:true,
    coverUrl: 'https://alivc-demo-vod.aliyuncs.com/image/cover/553AEA01161342C8A2B1756E83B69B5B-6-2.png',
    title: 'test title',
    describe: 'test string',
  }, {
    offset:120,
    isCustomized:true,
    coverUrl: 'https://alivc-demo-vod.aliyuncs.com/image/cover/553AEA01161342C8A2B1756E83B69B5B-6-2.png',
    title: 'test title',
    describe: 'test string',
  }],
  components: [
    {
      // 视频打点插件
      name: "ProgressComponent",
      //@ts-ignore
      type: AliPlayerComponent.ProgressComponent,
    },
  ]
})
5、为节点添加点击事件(当前节点没有点击事件,只有鼠标移动展示事件)

解决方法:

(1)将鼠标移动上去在 markerDotOver 方法中 获取当前节点的相关数据

(2)再通过click事件找到点击的元素(问题:鼠标单击时有偏差,显示的始终是 i 标签,并不能准确的定位到节点元素 .prism-marker-dot,所以此处需修改 .progress-component 下的 i 标签为 display: none; 将.prism-marker-dot 元素显示出来,此时鼠标单击时,便是.prism-marker-dot 元素了)

(3)用元素查找方法给当前相等的元素添加点击事件,并赋值到当前节点 play.seek()

play.on('click', function (event: any) {
  const target = event.target;
  console.log(555,target) // 元素名称:prism-marker-dot
})

play.on('markerDotOver', function (event: any) {
  const left = (event.paramData.left * 100).toFixed(5).slice(0, 6)
  const offset = event.paramData.progressMarker.offset
  document.querySelectorAll('.prism-marker-dot').forEach((element) => {
    //@ts-ignore
    if (element.style.left.slice(0, 6) === left) {
      element.addEventListener('click', () => {
        play.seek(offset);
      })
    }
  })
});


<style lang='scss' scoped>
:deep(.progress-component){
  cursor: pointer;
  i{
    display: none;
  }
}
:deep(.prism-progress-marker){
// 给节点修改样式
  .prism-marker-dot{
    background: #fff !important;
    top: -0.8px;
    overflow: hidden;
    width: 7px !important;
    height: 7px !important;
    border-radius: 50% !important;
  }
}

:deep(.pregress-play-btn){
  display: none;
}
</style>
(4)获取视频加载网速 K/s
<template>
  <div class="video">
    <div style="width: 100%;height: 100%" class="prism-player" id="J_prismPlayer"></div>
  </div>
</template>


<script lang='ts' setup>
import { onMounted } from 'vue';

onMounted(()=>{
  const video = document.querySelector('video'); // 获取video元素
  let lastBuffered = 0;
  let lastTime = performance.now();
  //@ts-ignore
  video.addEventListener('progress', function () {
    //@ts-ignore
    if(video.buffered.length>0){
      //@ts-ignore
      let buffered = video.buffered.end(0) - video.buffered.start(0); // 已缓冲区域大小
      let currentTime = performance.now();
      let timeDiff = (currentTime - lastTime) / 1000; // 时间差,单位为秒
      let speed = ((buffered - lastBuffered) / timeDiff).toFixed(2); // 计算网速,单位为字节/秒
      lastBuffered = buffered;
      lastTime = currentTime;
      emits('on-speed', `${speed} K/s`)
    }
  });
})
</script>

       希望我的愚见能够帮助你哦~,若有不足之处,还望指出,你们有更好的解决方法,欢迎大家在评论区下方留言支持,大家一起相互学习参考呀~

Logo

前往低代码交流专区

更多推荐