1,关于阿里播放器使用过的几种播放方式

url (source)

① 要在创建播放器前要拿到资源否则会报错

② 在有不同清晰度的资源时  直接调用 player.loadByUrl() 方法会报错 官网给出的例子:JSON.stringify({ 'FD': videoUrl.Fd, 'SD': videoUrl.Sd })   (首次可以播,但在切换时资源路径会出错,官网的demo只有单个视频,无法测试切换)

解决方法是 直接抛弃 player.loadByUrl()  ,每次销毁播放器,然后重新创建。

vid+playauth:

这种方式清晰度不需要自己设置,但坑比较多。在F5刷新后视频组件会丢失,只剩下封面,并且此类型必须额外写入一些配置,指定清晰度等等。

这种方式切换视频源不用player.loadByUrl() ,要用  player.replayByVidAndPlayAuth(this.vid, this.playauth)  方法

        // vid+playauth播放
        // vid: this.vid,
        // playauth: this.playauth,
        // encryptType: '1', // 播放加密视频
        // qualitySort: "asc", // 指定排序方式,只有使用Vid + PlayAuth播放方式时支持。
        // format: "m3u8", // 指定播放地址格式,只有使用vid的播放方式时支持可选值。
        // definition: "FD,LD,SD,HD,OD,2K,4K", // 此值是vid对应流清晰度的一个子集,仅H5模式支持。
        // defaultDefinition: 'SD', // 默认视频清晰度,此值是vid对应流的一个清晰度,仅H5模式支持。

2,需注意这几种事件的坑,在记录上报,播放时常要在 播放中playing 而不是 播放play 中执行,播放完毕后顺序播放可以用自带组件,这里是自己实现,但是有个bug是 ended播放完毕回调中 事件会执行两次!这里是设置了个开关来限制的。

3,配置中有个 skinLayout 可以设置一些播放组件,其中 setting 里自带倍速,字幕,音轨,清晰度,但是字幕和音轨这里用不到,还没法去掉。但是注释了setting又会导致 倍速和清晰度不见了。

这里官方提供了 components组件

components: [
          { name: 'RateComponent', type: AliPlayerComponent.RateComponent },
          { name: 'MemoryPlayComponent', type: AliPlayerComponent.MemoryPlayComponent },
          {
            name: 'QualityComponent',
            type: AliPlayerComponent.QualityComponent
          }],
 
RateComponent 为倍速
MemoryPlayComponent 历史记录
QualityComponent 是清晰度 ,这里有个坑,就是原本项目中引入的是   https://g.alicdn.com/de/prismplayer/2.8.1/aliplayer-min.js   (2.8.1版本的js和css)导致 一引入 清晰度组件就会报错,一只到不到原因,后来修改为 2.9.23版本的,报错消失。
 
4,倍速功能,因为有之前的坑,每次会销毁播放器重新创建,所以导致播放下一个视频时倍速会重置成1,官网还没有提供切换倍速抛出的事件,所以就捕获不到倍速的改变,也就无法在下一个时去设置倍速。只能手写一个倍速盒子点击时去对接阿里的方法。
 
音乐播放器的代码:
<template>
<!-- 容器 -->
<div class="container">
<!-- 音频播放器 -->
<transition name="el-zoom-in-top">
<div v-show="isShowPlayer" class="audioWrapper">
<div class="header">
<div class="title">正在播放 {{playingAudioName}}</div>
<img class="close" src="@/assets/image/close.png" alt="关闭播放器" @click="closePlayer">
</div>
<div class="audio-box" v-loading="playerLoading">
<img :src="play?pauseIcon:playIcon" alt="播放暂停" @click="playHandle()">
<div class="audio-progress">
<el-slider v-model="sliderVal" :format-tooltip="formatTooltip" :min="sliderMin" :max="sliderMax" @change="sliderChange"></el-slider>
<div id="aliPlayer"></div>
<div class="audio-info">
<div>
<span class="current-time">{{currentTime}}</span>
<span class="time-middle">/</span>
<em class="time-long">{{duration}}</em>
</div>
<div class="util-box">
<span @click="isShowRateList = !isShowRateList">倍速{{rateVal}}x</span>
<ul v-if="isShowRateList">
<li v-for="(t,i) in playBackRateList" :key="i" @click="changeRate(t)">{{t}}</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</transition>
</div>
</template> <script>
import { courseStore } from "@/store/course.js";
import { tokenStore } from "@/store/user.js";
export default {
layout: 'detail',
name: 'CourseCatalogue', // 校验动态路由参数的有效性
validate({ params, query }) { },
// 获取详情数据
async asyncData({ $axios, params }) {
return { }
}, // 处理数据
created() { }, mounted() {
// 初始化播放器
this.createPlayer() }, // 销毁定时器及阿里播放器
beforeDestroy() {
this.stopReportLearning()
if (this.player) {
this.player.dispose()
this.player = null
}
}, //
computed: { },
data() {
return {
store: courseStore(), // 课程商店
userStore: tokenStore(), // 用户商店 seeked: true, // 是否可续播
// 播放相关
canplay: false,// 是否可以播放
isShowPlayer: false,// 是否显示播放器
playerLoading: true, // 播放器loading
playingAudioName: '', // 正在播放的课程名称
player: null, // 播放器
timer: null, // 学习上报定时器
playDate: '', // 当前视频的时间戳
opener: true,
playerUrl: '/a.m3u8', // 播放的资源路径
sliderVal: 0, // 滑块当前时长。
sliderMin: 0,
sliderMax: 0, // 滑块的总时长。
currentTime: '00:00', // 当前播放时间
duration: '00:00', // 总时长
play: false, // 播放ing?暂停?
// 播放/暂停图标
playIcon: require('@/assets/image/play.png'),
pauseIcon: require('@/assets/image/pause.png'),
isShowRateList: false, // 是否展示倍速列表
rateVal: 1, // 当前倍速
playBackRateList: [0.25, 0.5, 0.75, '正常', 1.25, 1.5, 1.75, 2], // 倍速
}
},
methods: {
// 获取vid+playauth
getVid() { },// 初始化播放器
createPlayer() {
let prop = {
id: "aliPlayer",
source: this.playerUrl,
mediaType: "audio",
width: "100%",
height: "100%",
autoplay: false, // 自动播放
isLive: false, // 直播
rePlay: false, // 循环播放
playsinline: true, //H5是否内置播放
preload: true, //播放器自动加载
language: "zh-cn", // 语言
cover: '', //播放器默认封面图片,需要autoplay为’false’时,才生效
controlBarVisibility: "hover", //控制面板的实现 ‘click’ 点击出现、‘hover’ 浮动出现、‘always’ 一直在
useH5Prism: true //指定使用H5播放器
} this.player = new Aliplayer(prop, function (player) {
console.log("The player is created");
}) // 播放 (由暂停恢复为播放时触发)
this.player.on('play', () => {
this.play = true
}) // 暂停
this.player.on('pause', () => {
this.play = false
this.stopReportLearning()
}) // 播放ing (播放中,会触发多次)
this.player.on('playing', () => {
// console.log('播放中ing') // 学习记录上报
this.learningReport()
}) // 可以播放
this.player.on('canplay', () => {
this.playerLoading = false
const courseInfo = this.store.getCourseInfo
if (this.canplay && this.seeked && courseInfo.duration && courseInfo.newestLessonId === courseInfo.lessonId) {
this.seeked = false
this.player.seek(courseInfo.duration)
}
}) // 等待缓冲
this.player.on('waiting', () => {
this.playerLoading = true
}) // 时长发生变动时
this.player.on('timeupdate', () => {
this.updateTime()
}) // 播放出错
this.player.on('error', () => {
this.$message.error('播放出错')
this.stopReportLearning()
this.sliderVal = 0
this.play = false
this.playerLoading = true
this.isShowPlayer = false
this.store.setIsPlaying(false)
}) // 播放完毕
this.player.on("ended", () => {
if (this.opener) {
this.opener = false
console.log('播放完了!') // 停止学习上报
this.stopReportLearning()
this.playDate = '' // 调用子组件方法,自动播放下一个
const courseInfo = this.store.getCourseInfo
this.$refs.CourseCurriculum.createdPlayList(courseInfo.courseId, courseInfo.lessonId)
}
});
}, // 学习记录上报
learningReport() { // 先清空
this.stopReportLearning() const courseInfo = this.store.getCourseInfo
const lessonAudioVideo = courseInfo.lessonAudioVideo // 播放时长小于1时不进行上报
// if (curTime <= 1) {
// return
// } if (this.playDate === '') {
const nowDate = new Date
this.playDate = nowDate.getTime()
} // 学次唯一值
const userInfo = this.userStore.getUserInfo
const key = `${userInfo.userId}_${courseInfo.orderId}_${courseInfo.projectId}_${courseInfo.courseId}_${courseInfo.lessonId}_${this.playDate}`;
const sessionKey = this.$md5(key) this.timer = setInterval(() => {
const curTime = parseInt(this.player.getCurrentTime())
this.$axios.$post('/hadoop/learning/learningRecordSend', {
sessionKey: sessionKey,
orderId: courseInfo.orderId,
projectId: courseInfo.projectId,
courseId: courseInfo.courseId,
courseCatalogId: courseInfo.lessonId,
resourceType: lessonAudioVideo.type,
resourceId: lessonAudioVideo.audioId,
duration: curTime
}).then(() => { }).catch((err) => {
if (err.code === 10009) this.player.pause()
});
}, 5000)
}, // 停止上报学习记录
stopReportLearning() {
if (this.timer) {
clearInterval(this.timer)
this.timer = null
}
}, // 关闭播放器
closePlayer() {
this.isShowPlayer = false
this.store.setIsPlaying(false)
this.stopReportLearning()
this.play = false
this.playerLoading = true
this.player.pause()
}, // 播放/暂停
playHandle() {
this.play = !this.play
this.play ? this.player.play() : this.player.pause()
}, // 更新时间
updateTime() {
if (!Number.isFinite(this.player.getDuration())) {
this.currentTime = Number.MAX_SAFE_INTEGER;
this.currentTime = '00:00';
} else {
const total = this.formatTime(this.player.getDuration())
const current = this.formatTime(this.player.getCurrentTime())
this.duration = `${total.min}:${total.sec}`
this.currentTime = `${current.min}:${current.sec}`
this.sliderVal = Math.floor(this.player.getCurrentTime())
this.sliderMax = Math.floor(this.player.getDuration())
}
}, // 格式化毫秒,返回String型分秒对象
formatTime(time) {
// 如果没获取到
if (!time) return { min: '00', sec: '00' }
return {
min: Math.floor(time / 60).toString().padStart(2, '0'),
sec: Math.floor(time % 60).toString().padStart(2, '0')
}
}, // 格式化毫秒数,对应elm滑块组件
formatTooltip(val) {
const time = this.formatTime(val)
return `${time.min}:${time.sec}`
}, // 滑块松动后触发。更新当前时长,
// 时长发生变动会init里的方法进行更新数据
sliderChange(val) {
this.player.seek(this.sliderVal)
}, // 倍速改变时
changeRate(t) {
if (t === '正常') t = 1;
this.rateVal = t
this.player.setSpeed(t)
this.isShowRateList = false
},
}
}
</script>

视频播放代码:

<template>
<div class="wrap">
<!-- 视频区域 -->
<div class="video" :class="{'w1': sideBarFlag}"> <!-- 视频 -->
<div class="player" id="aliVideoPlayer"></div> </div> <!-- 侧边栏区域 --> </div>
</template> <script>
import { courseStore } from "@/store/course.js";
import { tokenStore } from "@/store/user.js";
export default {
layout: 'index',
async asyncData({ $axios, query }) {
const [chapterList] = await Promise.all([
// 获取视频资源
// $axios.$get(`/resources/resources/video/${lessonAudioVideo.videoId}`),
// 获取课程列表
$axios.$get('/learning/user/project/pc/catalog/v1', {
params: {
projectId: query.projectId,
courseId: query.courseId
}
}),
])
return {
// videoData,
chapterList
}
},
data() {
return {
store: courseStore(), // 课程商店
userStore: tokenStore(), // 用户商店
courseInfo: {},// 当前播放的课程相关信息
player: null, // 播放器
opener: true,
playerUrl: '', // 播放的资源url
vid: '', // vid + playauth
playauth: '',
lessonName: '', // 当前播放的课次名称
seeked: true, // 是否可续播
speed: 1, // 倍速
// 侧边栏
sideBarFlag: true,
// 目录/笔记
listFlag: true,
// 学习上报定时器
timer: null,
// 当前视频的时间戳
playDate: '',
}
}, beforeMount() {
this.courseInfo = this.store.getCourseInfo
// 获取视频资源url
// this.playerUrl = this.courseInfo.lessonAudioVideo.url
}, async mounted() {
// 获取视频vid+playauth
const videoInfo = await this.getVid()
this.playerUrl = JSON.stringify({ 'FD': videoInfo.Fd, 'SD': videoInfo.Sd })
// this.vid = videoInfo.VideoId
// this.playauth = videoInfo.PlayAuth
// 初始化播放器
this.createPlayer()
}, // 销毁定时器
beforeDestroy() {
this.stopReportLearning()
if (this.player) {
this.player.dispose()
this.player = null
}
}, methods: {
// 获取vid+playauth
getVid() {
return this.$axios.$get(`/file/sys/file/getVideoPlayUrl`, {
params: {
videoId: this.courseInfo.lessonAudioVideo.resourcesId
}
})
},
// 初始化播放器
createPlayer() {
let prop = {
id: "aliVideoPlayer", // 资源url播放
source: this.playerUrl, // vid+playauth播放
// vid: this.vid,
// playauth: this.playauth,
// encryptType: '1', // 播放加密视频
// qualitySort: "asc", // 指定排序方式,只有使用Vid + PlayAuth播放方式时支持。
// format: "m3u8", // 指定播放地址格式,只有使用vid的播放方式时支持可选值。
// definition: "FD,LD,SD,HD,OD,2K,4K", // 此值是vid对应流清晰度的一个子集,仅H5模式支持。
// defaultDefinition: 'SD', // 默认视频清晰度,此值是vid对应流的一个清晰度,仅H5模式支持。 mediaType: "video",
width: "100%",
height: "100%",
autoplay: true, // 自动播放
isLive: false, // 直播
rePlay: false, // 循环播放
playsinline: true, //H5是否内置播放
preload: true, //播放器自动加载
keyShortCuts: true, // 是否启用快捷键
language: "zh-cn", // 语言
cover: '', //播放器默认封面图片,需要autoplay为’false’时,才生效
controlBarVisibility: "hover", //控制面板的实现 ‘click’ 点击出现、‘hover’ 浮动出现、‘always’ 一直在
useH5Prism: true, //指定使用H5播放器
components: [
{ name: 'RateComponent', type: AliPlayerComponent.RateComponent },
{ name: 'MemoryPlayComponent', type: AliPlayerComponent.MemoryPlayComponent },
{
name: 'QualityComponent',
type: AliPlayerComponent.QualityComponent
}],
skinLayout: [
{ name: "bigPlayButton", align: "blabs", x: 30, y: 80 },
{ name: "H5Loading", align: "cc" },
{ name: "errorDisplay", align: "tlabs", x: 0, y: 0 },
{ name: "infoDisplay" },
{ name: "tooltip", align: "blabs", x: 0, y: 56 },
{ 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: "subtitle", align: "tr", x: 15, y: 12 },
// { name: "setting", align: "tr", x: 15, y: 12 },
{ name: "volume", align: "tr", x: 5, y: 10 }
]
}
]
} this.player = new Aliplayer(prop, function (player) {
console.log("The player is created");
player.on('sourceloaded', function (params) {
var paramData = params.paramData
var desc = paramData.desc
var definition = paramData.definition
// 获取清晰度组件并调用清晰度组件的 setCurrentQuality 设置清晰度
player.getComponent('QualityComponent').setCurrentQuality(desc, definition)
}) // 是否有设置过倍速
if (this.speed) {
player.setSpeed(this.speed)
}
}) // 播放
this.player.on('play', () => {
// console.log('开始播放')
}) // 播放ing
this.player.on('playing', () => {
// console.log('播放中ing') this.speed = this.player.tag.playbackRate // 学习记录上报
this.learningReport()
}) // 可以播放
this.player.on('canplay', () => {
if (this.seeked && this.courseInfo.duration && this.courseInfo.newestLessonId === this.courseInfo.lessonId) {
this.seeked = false
this.player.seek(this.courseInfo.duration)
}
}) // 暂停
this.player.on('pause', () => {
// console.log('播放暂停') // 停止上报
this.stopReportLearning()
}) // 播放出错
this.player.on('error', () => {
this.$message.error('播放出错')
}) // 播放完毕
this.player.on("ended", (e) => {
if (this.opener) {
this.opener = false
console.log('播放完了!!!!!')
this.stopReportLearning()
this.playDate = '' // 调用子组件方法,自动播放下一个
this.$refs.videoList.createdPlayList(this.courseInfo.lessonId)
}
})
}, // 接受到子组件课次变化,播放新的视频
async lessonChange(doing) { this.courseInfo = this.store.getCourseInfo // 未告知要播放时,只展示课次名字
if (doing !== 'play') {
this.lessonName = this.courseInfo.lessonName
return
} // 检测播放源是否相同(目前不进行检测,否则导致点击相同资源时->无法重播)
// if (this.playerUrl !== this.courseInfo.lessonAudioVideo.url) { // 更改视频源 // TODO: url
// this.playerUrl = this.courseInfo.lessonAudioVideo.url
// this.player.loadByUrl(this.playerUrl) // TODO: vod
const videoUrl = await this.getVid()
// this.playerUrl = videoInfo.Sd
// this.player.loadByUrl(this.playerUrl)
this.player.dispose()
this.playerUrl = JSON.stringify({ 'FD': videoUrl.Fd, 'SD': videoUrl.Sd })
this.createPlayer() // TODO: vid+playauth
// this.vid = videoInfo.VideoId
// this.playauth = videoInfo.PlayAuth
// this.player.replayByVidAndPlayAuth(this.vid, this.playauth) // } else {
// this.player.play()
// } this.lessonName = this.courseInfo.lessonName
this.seeked = true
this.opener = true
}, // 停止上报学习记录,清楚定时器
stopReportLearning() {
if (this.timer) {
clearInterval(this.timer)
this.timer = null
}
}, // 学习记录上报
learningReport() {
// 先清空
this.stopReportLearning() const courseInfo = this.courseInfo
const lessonAudioVideo = this.courseInfo.lessonAudioVideo if (this.playDate === '') {
const nowDate = new Date
this.playDate = nowDate.getTime()
// console.log(this.playDate)
} // 学次唯一值
const userInfo = this.userStore.getUserInfo
const key = `${userInfo.userId}_${courseInfo.orderId}_${courseInfo.projectId}_${courseInfo.courseId}_${courseInfo.lessonId}_${this.playDate}`;
const sessionKey = this.$md5(key) this.timer = setInterval(() => {
const curTime = parseInt(this.player.getCurrentTime())
this.$axios.$post('/hadoop/learning/learningRecordSend', {
sessionKey: sessionKey,
orderId: courseInfo.orderId,
projectId: courseInfo.projectId,
courseId: courseInfo.courseId,
courseCatalogId: courseInfo.lessonId,
resourceType: lessonAudioVideo.type,
resourceId: lessonAudioVideo.videoId,
duration: curTime
}).then(() => { }).catch((err) => {
if (err.code === 10009) this.player.pause()
});
}, 5000)
}
}
}
</script>
 

最新文章

  1. .NET基础 一步步 一幕幕[循环、逻辑语句块]
  2. .net使用cefsharp开源库开发chrome浏览器(二)
  3. Security &#187; Authorization &#187; 通过映射限制身份
  4. spring beans
  5. 反编译CHM文件
  6. STM32 flash 内存分布介绍
  7. C#各类型大小
  8. C#判断文件及文件夹是否存在并创建(C#判断文件夹存在)
  9. CSS文件中第一行@charset &quot;utf-8&quot;;的作用
  10. 各种语言HMAC SHA256实现
  11. hadoop 生态系统版本对应问题
  12. NET Core MVC 在linux上的创建及发布
  13. 对象Equals相等性比较的通用实现
  14. The Super Powers
  15. ios原生项目内嵌u3d工程
  16. 2017-2018-2 20155303『网络对抗技术』Exp2:后门原理与实践
  17. 网页html随机切换背景图片
  18. Git简单操作命令
  19. js 正则之 检测素数
  20. python dict conver json

热门文章

  1. Java中Elasticsearch 实现分页方式(三种方式)
  2. Java用户交互方法——Scanner
  3. [数据结构]Dijkstra算法求单源最短路径
  4. 近邻取样插值方法缩放BGRA图片数据
  5. Array.from() ------来自❀ 前端宇宙 ❀公众号。
  6. 性能浪费的日志案例-使用Lambda优化日志案例
  7. MRS芯片状态错误排查方向
  8. 12月15日内容总结——ORM执行原生SQL语句、双下划线数据查询、ORM外键字段的创建、外键字段的相关操作、ORM跨表查询、基于对象的跨表查询、基于双下划线的跨表查询、进阶查询操作
  9. JavaScript 疑难记录(未解决)
  10. JavaScript: symbol 和 string key 取值用法