概述
前言
jq事件:https://www.jb51.cc/js/153165.html
示例代码
<!DOCTYPE html>
<html>
<head>
<script src="./video.js"></script>
<link href="./video-js.css" rel="stylesheet" />
<script src="./videojs-contrib-hls.min.js"></script>
<script src="./jquery-3.5.0.min.js"></script>
</head>
<body>
<video id="myVideo" class="video-js vjs-default-skin" controls preload="auto" width="1000" height="500"
data-setup='{}'>
</video>
<script>
/**
* 逻辑:
* 1.进入页面,页面获取到请求参数
* 2.页面通过ajax进行请求,获取到文件信息
* 3.开始播放时,获取下一集的文件信息
* 4.播放结束时,更新视频地址,继续播放下一集
*
*/
// 第一步
var num = 0
var id = GetPar('id')
// 第二步
var url = 'http://localhost:8001/file/playOnline/' + id
$.get(url, function(res) {
if (res.code == 200) {
localStorage.setItem("currentId", id)
localStorage.setItem("currentUrl", res.data)
var player = videojs('myVideo',{
// 播放速度
playbackRates: [0.7, 1.0, 1.5, 2.0],
// 如果true,浏览器准备好时开始回放。
autoplay: true,
//
默认情况下将会消除任何音频。
muted: false,
//
导致视频一结束就重新开始。
loop: false,
//
建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
preload: 'auto',
sources: [
{
// 这里的种类支持很多种:基本视频格式、直播、流媒体等,具体可以参看git网址项目
type: 'application/x-mpegURL',
src: ''
}
],
});
videojs("myVideo").ready(function(){
player.ready(function() {
this.src({
src: localStorage.getItem('currentUrl'),
type: 'application/x-mpegURL',
});
this.on("play", function() {
console.log("我走了Play")
num++
if (num == 1) {
// 第三步
getNextEpisode(localStorage.getItem('currentId'))
}
});
this.on("ended", function() {
debugger
// 第四步
num = 0
var nextUrl = localStorage.getItem("nextUrl")
if(nextUrl != null && typeof(nextUrl) != 'undefined' && nextUrl != ''){
this.src({
src: nextUrl,
type: 'application/x-mpegURL',
});
}
});
});
});
}
})
// 获取下一集信息
function getNextEpisode(id) {
var url = "http://localhost:8001/file/getNextEpisode";
$.ajax({
url: url,
type: "POST",
data: JSON.stringify({
id: id
}),
contentType: "application/json",
dataType: "json",
success: function(res) {
debugger
if(res.code == 200){
if(res.data == null){
localStorage.setItem('nextUrl', '')
}else{
localStorage.setItem('nextUrl', res.data.m3u8Url)
localStorage.setItem('nextId', res.data.id)
}
}
}
});
}
// 获取浏览器请求参数
function GetPar(name) {
var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)')
var r = window.location.search.substr(1).match(reg)
if (r != null) return decodeURIComponent(r[2])
return null
}
</script>
</html>
vue中使用video.js。代码仅做个人备份
功能:点击进行播放,当前播放完毕自动跳到下一集。全部播放完毕暂停。 PC手机都可以
<template>
<el-card class="box-card">
<div class="block-search">
<el-input
class="width-190"
v-model="queryParam.keyword"
placeholder="请输入文件名称"
size="medium"
clearable
></el-input>
<el-select
v-model="queryParam.fileType"
placeholder="全部类型"
class="width-190"
size="medium"
clearable
>
<el-option
v-for="item in optionsByFileType"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
<el-button type="primary" plain size="medium" icon="el-icon-search" @click="_search">搜索</el-button>
</div>
<el-table :data="tableData" border style="width: 100%" size="mini">
<el-table-column fixed prop="id" label="文件id" width="60"></el-table-column>
<el-table-column prop="oldName" label="原文件名称" width="120" show-overflow-tooltip></el-table-column>
<el-table-column prop="newName" label="新文件名称" width="120" show-overflow-tooltip></el-table-column>
<el-table-column prop="fileSize" label="文件大小" width="120" show-overflow-tooltip>
<template slot-scope="scope">{{scope.row.fileSize + 'kb'}}</template>
</el-table-column>
<el-table-column prop="fileType" label="文件类型" width="120" show-overflow-tooltip>
<template slot-scope="scope">{{_getFileTypeStr(scope.row)}}</template>
</el-table-column>
<el-table-column prop="suffixName" label="扩展名" width="120" v-if="false"></el-table-column>
<el-table-column prop label="二维码" width="120">
<template slot-scope="scope">
<el-popover placement="bottom" title="手机扫码在线观看" width="200" trigger="hover" content>
<canvas :id="'QRCode_'+scope.row.id"></canvas>
<i class="fa fa-qrcode" slot="reference" @mouseenter="generatorQrcode(scope.row)"></i>
</el-popover>
</template>
</el-table-column>
<el-table-column
prop="downloadPath"
label="文件路径"
width="300"
show-overflow-tooltip
v-if="true"
></el-table-column>
<el-table-column prop="lastEpisodeName" label="上一集名称" width="120" show-overflow-tooltip>
<template slot-scope="scope">{{scope.row.lastEpisodeName | columnDefauleValue}}</template>
</el-table-column>
<el-table-column prop="nextEpisodeName" label="下一集名称" width="120" show-overflow-tooltip>
<template slot-scope="scope">{{scope.row.nextEpisodeName | columnDefauleValue}}</template>
</el-table-column>
<el-table-column prop="createDate" label="上传时间" width="170">
<template slot-scope="scope">{{scope.row.createDate | timestampFormatTime}}</template>
</el-table-column>
<el-table-column fixed="right" label="操作" width="400">
<template slot-scope="scope">
<el-button size="mini" type="default" @click="_download(scope.row)">
<i class="fa fa-cloud-download"></i>下载
</el-button>
<el-button
size="mini"
type="default"
@click="_toFileConfig(scope.row)"
v-if="parseInt(scope.row.fileType) === 4"
>
<i class="fa fa-retweet"></i>配置
</el-button>
<el-button
size="mini"
type="primary"
disabled
v-if="parseInt(scope.row.fileType) === 4 && scope.row.transcodingStatus=== 2"
>
<i class="fa fa-spinner fa-pulse"></i>转码中
</el-button>
<el-button
size="mini"
type="primary"
@click="_playOnline(scope.row)"
v-else-if="parseInt(scope.row.fileType) === 4 &&(scope.row.transcodingStatus=== 1|| scope.row.transcodingStatus=== 3)"
>
<i class="fa fa-video-camera"></i>在线播放
</el-button>
<el-button size="mini" type="danger" @click="_delete(scope.row)">
<i class="fa fa-trash-o"></i>删除
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 文件配置 -->
<el-dialog
:title="$jsConstants.title"
:visible.sync="dialogVisibleByConfig"
width="30%"
:before-close="handleCloseByConfig"
>
<el-form
ref="fileConfig"
:model="fileConfig"
label-width="100px"
size="small"
v-if="currentFile"
>
<el-form-item label="原文件名称" class>{{currentFile.oldName}}</el-form-item>
<el-form-item label="新文件名称" class>{{currentFile.newName}}</el-form-item>
<el-form-item label="上一集">
<el-input v-model="fileConfig.lastEpisode" placeholder="请输入文件id"></el-input>
</el-form-item>
<el-form-item label="下一集">
<el-input v-model="fileConfig.nextEpisode" placeholder="请输入文件id"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="handleCloseByConfig">取 消</el-button>
<el-button type="primary" @click="_updateFileInfo">确 定</el-button>
</span>
</el-dialog>
<el-dialog
:title="$jsConstants.title"
:visible.sync="isShow"
width="50%"
:before-close="handleClose"
@open="handleOpen"
>
<video
id="myVideo"
ref="myVideoRef"
controls
preload="auto"
class="video-js vjs-big-play-centered vjs-fluid vjs-16-9 vjs-big-play-centered"
data-setup="{}"
>
<source :src="playVideoUrl" type="application/x-mpegURL" />
</video>
</el-dialog>
<span ref="testRef"></span>
</el-card>
</template>
<script>
import QRCode from 'qrcode'
import { mapState, mapActions } from 'vuex'
import {
getNextEpisode,
updateFileInfo,
delFile,
getFilesByTtanscoded,
playOnline,
queryFileInfoPageList,
download,
getFileTypes
} from '@/api/logic/api-file'
export default {
data() {
return {
// 第一次播放标志
playFlagForTheFirstTime: 0,
// 播放地址
playVideoUrl: 'http://192.168.17.46:8001/158304068-bkmmp4/ts/bkm.m3u8',
// 当前文件
currentFile: {},
// 文件配置
fileConfig: {
id: null,
lastEpisode: null,
nextEpisode: null
},
dialogVisibleByConfig: false,
// 刷新数组
transcodingArr: [],
// 在线播放
playOnlineUrl: null,
// 查询参数
queryParam: {
pageInfoDto: {
pageNum: 0,
pageSize: 10
},
keyword: null,
fileType: null
},
// 文件类型
optionsByFileType: [],
// 列表数据
tableData: []
}
},
components: {
QRCode
},
computed: {
...mapState('StoreModuleFile', ['video']),
player() {
return this.$refs.videoPlayer.player
},
isShow: function() {
return this.$store.state.StoreModuleFile.video.isShow
},
getPlayOnlineUrl() {
return this.video.url
}
},
created() {
this._getFileTypes()
this._search()
},
onload() {},
onShow() {
debugger
console.log(this)
},
mounted() {},
methods: {
...mapActions('StoreModuleFile', ['setVideo']),
// 下一集
_getNextEpisode(currentId, currentUrl = null) {
getNextEpisode({ id: currentId }).then(res => {
if (res.code === this.$jsConstants.SUCCESS) {
// 获取video信息
let video = JSON.parse(
JSON.stringify(this.$store.state.StoreModuleFile.video)
)
// 保存第一集视频地址
if (video.firstId) {
video.firstId = video.firstId
video.firstUrl = video.firstUrl
} else {
video.firstId = currentId
video.firstUrl = currentUrl
}
if (res.data != null) {
// 如果没有下一集
video.currentId = res.data.id
video.currentUrl = res.data.m3u8Url
video.nextEpisodeId = null
video.nextEpisodeUrl = null
} else {
video.currentId = null
video.currentUrl = null
video.nextEpisodeId = null
video.nextEpisodeUrl = null
}
this.setVideo(video)
}
})
},
// 在线播放
_playOnline(row) {
this.setVideo({
isShow: true
})
playOnline(row.id).then(res => {
let that = this
if (res.code === this.$jsConstants.SUCCESS) {
that.setVideo({
isShow: true,
currentId: row.id,
currentUrl: res.data,
nextEpisodeId: null,
nextEpisodeUrl: null,
firstId: row.id,
firstUrl: res.data
})
that.playVideoUrl = res.data
// 设置视频源
let myVideo = document.getElementById('myVideo')
myVideo = myVideo === null ? that.$refs.viodeRef : myVideo
var options = {}
var player = that.$video(myVideo, options, function() {
player.ready(function() {
this.src({
src: res.data,
type: 'application/x-mpegURL'
})
this.on('play', function() {
let video = that.$store.state.StoreModuleFile.video
if (video.isOK) {
myVideo.pause()
// 清空暂停状态
let newVideo = JSON.parse(JSON.stringify(video))
newVideo.isOK = false
that.setVideo(newVideo)
return false
}
// 播放开始,取当前文件id,查询下一集的信息,存储到状态管理
// 查询下一集;此处之所以判断是否第一次播放,是因为视频暂停时,也会触发该事件
that.playFlagForTheFirstTime++
if (that.playFlagForTheFirstTime === 1) {
that._getNextEpisode(video.currentId, video.currentUrl)
}
})
this.on('ended', function() {
let video = that.$store.state.StoreModuleFile.video
// 当前这一集视频播放结束,play次数更新为获0
that.playFlagForTheFirstTime = 0
// 更新播放器视频地址为下一集
let currentUrl = video.currentUrl
if (currentUrl) {
player.src({
src: video.currentUrl
})
} else {
// 最后一集播放完毕,把视频地址更换为第一集地址;更新状态管理播放文件信息;然后设置停止播放。
video.currentId = video.firstId
video.currentUrl = video.firstUrl
player.src({
src: video.firstUrl,
autoplay: false
})
// 添加暂停状态,否则会循环播放
let newVideo = JSON.parse(JSON.stringify(video))
newVideo.isOK = true
that.setVideo(newVideo)
}
})
})
})
}
})
},
//
关闭
handleClose() {
// 更新单个视频获取下一集次数
this.playFlagForTheFirstTime = 0
this.setVideo({ isShow: false })
},
//
打开
handleOpen() {
// 更新单个视频获取下一集次数
this.playFlagForTheFirstTime = 0
},
// 初始化video
initVideo() {
debugger
this.setVideo({ isShow: true })
// 初始化视频方法
let myVideo = document.getElementById('myVideo')
myVideo = myVideo === null ? this.$refs.myVideoRef : myVideo
if (myVideo) {
this.$video(myVideo, {
// 确定播放器是否具有用户可以与之交互的控件。没有控件,启动视频播放的唯一方法是使用autoplay属性或通过Player API。
controls: true,
// 自动播放属性,muted:静音播放
autoplay: 'muted',
// 建议浏览器是否应在<video>加载元素后立即开始下载视频数据。
preload: 'auto',
// 设置视频播放器的显示宽度(以像素为单位)
width: '800px',
// 设置视频播放器的显示高度(以像素为单位)
height: '400px',
hls: {
withCredentials: true
}
})
}
},
// 获取二维码地址
generatorQrcode(row) {
// 二维码地址
let val = 'http://192.168.17.46:8080/static/h5/index.html?id=' + row.id
// 获取页面的canvas
var msg = document.getElementById('QRCode_' + row.id)
// 将获取到的数据(val)画到msg(canvas)上
QRCode.toCanvas(msg, val, function(error) {
console.log(error)
})
},
// 关闭config
handleCloseByConfig() {
this.dialogVisibleByConfig = false
this.currentFile = {}
this.fileConfig = {}
},
// 文件配置
_updateFileInfo() {
updateFileInfo(this.fileConfig).then(res => {
if (this.$jsConstants.SUCCESS === res.code) {
this.dialogVisibleByConfig = false
this.currentFile = {}
this.fileConfig = {}
this.$notify({
title: '成功',
message: '配置成功',
type: 'success'
})
this._search()
}
})
},
_toFileConfig(row) {
// 文件配置
this.fileConfig.id = row.id
this.fileConfig.lastEpisode = row.lastEpisode
this.fileConfig.nextEpisode = row.nextEpisode
// 当前文件
this.currentFile = row
this.dialogVisibleByConfig = true
},
// 文件下载
_download(row) {
download(row.id)
},
// 查询
_search() {
queryFileInfoPageList(this.queryParam).then(res => {
console.log('res', res)
if (this.$jsConstants.SUCCESS === res.code) {
this.tableData = res.data.list
// 过滤出转码中的数据,然后每10秒刷新一次状态
this.transcodingArr = []
this.tableData.forEach(obj => {
if (obj.transcodingStatus === 2) {
this.transcodingArr.push(obj.id)
}
})
this._RefreshStatus(this.transcodingArr)
}
})
},
// 刷新状态
_RefreshStatus(ids) {
let that = this
if (ids === null || ids.length === 0) {
return false
}
let timeId = null
timeId = setInterval(function() {
getFilesByTtanscoded({ fileIds: ids }).then(res => {
if (that.$jsConstants.SUCCESS === res.code) {
if (res.data != null && res.data.length > 0) {
res.data.forEach(obj => {
// 弹框显示转码成功
that.$notify({
title: '成功',
message: obj.newName + ' 转码成功',
type: 'success'
})
// 删除该刷新元素
that.transcodingArr.some((item, index) => {
if (item === obj.id) {
that.transcodingArr.splice(index, 1)
// 如果没有转码中的数据,则关闭定时器
if (that.transcodingArr.length === 0) {
clearInterval(timeId)
}
}
})
// 更新列表状态
that.tableData.some((updateObj, updateIndex) => {
if ((updateObj.id = obj.id)) {
updateObj.transcodingStatus = 3
}
})
})
}
}
})
}, 3000)
},
// 删除
_delete(row) {
if (row.transcodingStatus === 2) {
this.$notify({
title: '警告',
message: '文件正在转码,请稍后操作',
type: 'warning'
})
return false
}
this.$confirm('你确定要删除吗?')
.then(_ => {
// 二次确定
delFile({ id: row.id }).then(res => {
if (this.$jsConstants.SUCCESS === res.code) {
this.$notify({
title: '成功',
message: '删除成功',
type: 'success'
})
this._search()
}
})
})
.catch(_ => {})
},
// 获取文件类型
_getFileTypeStr(row) {
let str = ''
this.optionsByFileType.forEach(element => {
if (parseInt(element.value) === parseInt(row.fileType)) {
str = element.label
}
})
return str
},
// 遍历选项
_getFileTypes() {
getFileTypes().then(res => {
this.optionsByFileType = []
res.data.forEach(element => {
this.optionsByFileType.push({
label: element.typeDescription,
value: element.typeId
})
})
})
}
}
}
</script>
<style lang="less" scoped>
</style>
最后
以上就是幽默小懒虫为你收集整理的video.js 相关实现文档的全部内容,希望文章能够帮你解决video.js 相关实现文档所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复