vue-video-player 实现动态渲染后端传来的视频

本文主要是介绍vue-video-player 实现动态渲染后端传来的视频,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.安装vue-video-player

npm install vue-video-player --save

 2.在main.js入口文件中引入

import VideoPlayer from 'vue-video-player'
require('video.js/dist/video-js.css')
require('vue-video-player/src/custom-theme.css')
Vue.use(VideoPlayer)

3.在页面中使用

<template><div  class="video-demo"><video-player  id="video" class="video-player vjs-custom-skin"ref="videoPlayer":playsinline="true"style="object-fit:fill":options="playerOptions":x5-video-player-fullscreen="true"@pause="onPlayerPause($event)"@play="onPlayerPlay($event)"@fullscreenchange="onFullscreenChange($event)"@click="fullScreen"></video-player></div>
</template>

4.配置数据

 playerOptions: {playbackRates: [0.7, 1.0, 1.5, 2.0], //播放速度autoplay: true, //如果true,浏览器准备好时开始回放。muted: false, // 默认情况下将会消除任何音频。loop: false, // 导致视频一结束就重新开始。preload: 'auto', // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)language: 'zh-CN',aspectRatio: '16:9', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。sources: [{src: '',  // 路径type: 'video/mp4'  // 类型}],// poster: "../../static/images/test.jpg", //你的封面地址// width: document.documentElement.clientWidth,notSupportedMessage: '此视频暂无法播放,请稍后再试', //允许覆盖Video.js无法播放媒体源时显示的默认信息。controlBar: {timeDivider: true,durationDisplay: true,remainingTimeDisplay: false,fullscreenToggle: true  //全屏按钮}}

 5.方法目前还不完善 以后..再。。。。。

 可参考 较详细:https://www.jb51.net/article/173816.htm

6.在其他组件调用

<vueVideoPlayer :src="data.url" :cover_url="data.cover_url" />import vueVideoPlayer from './module/vueVideoPlayer'  // 引入视频组件components: {vueVideoPlayer 
}

 vue-video-player 实现动态渲染后端传来的视频

html

<template><div class="container"><div class="content"><div class="nav"><!-- 选项卡标题图片 挺垃圾的可以改为 :src="img" --><ul class="tabs"><li @click="nowschool()" class="now"><imgsrc="http://yikaojs.jymmy.cn/static/img/now2.png"alt=""class="activeone"/><imgsrc="http://yikaojs.jymmy.cn/static/img/now.png"alt=""style="display: none"class="unactiveone"/></li><li @click="allschool()" class="all"><imgsrc="http://yikaojs.jymmy.cn/static/img/all.png"alt=""class="unactive"/><imgsrc="http://yikaojs.jymmy.cn/static/img/all2.png"alt=""style="display: none"class="active"/></li></ul><!-- 选项卡内容 --><div class="cards" style="background: white; height: 200px"><!-- 循环出多个小视频box --><div class="tab-now tabcards" id="tabone" style="display: block"><divclass="box"v-for="(item, index) in videos":key="index"@click="getVideoDetail(index)"><div class="video-small"><video-playerclass="video-player-box"ref="videoPlayer":options="videoConfig[index]":playsinline="true"></video-player></div><div class="text"><div class="jigou">{{ item.mechanism }}</div><div class="bottom"><div class="name">{{ item.username }}</div><div class="time">{{ item.published_time | momentTime }}</div></div></div></div></div><div class="tab-all tabcards" style="display: none"><divclass="box"v-for="(item, index) in videos":key="index"@click="getVideoDetail(index)"><div class="video-small"><video-playerclass="video-player-box"ref="videoPlayer":options="videoConfig[index]":playsinline="true"></video-player></div><div class="text"><div class="jigou">{{ item.mechanism }}</div><div class="bottom"><div class="name">{{ item.username }}</div><div class="time">{{ item.published_time | momentTime }}</div></div></div></div></div></div><!-- 分页 --><div class="block"><el-paginationlayout="prev, next":total="totalCount":page-size="8":current-page="currentPage"@size-change="handleSizeChange"@current-change="handleCurrentChange"></el-pagination></div><!-- 弹窗 点击小视频弹出大视频及详情--><div class="tan"><el-dialog :visible.sync="dialogFormVisible" @close="closeDialog"><div class="videoall"><div class="video-demo"><video-playerid="video"class="video-player vjs-custom-skin"ref="videoPlayer":options="playerOptions":playsinline="true":destroy-on-close = "true"style="width: 1004px; height: 435px"></video-player></div><div class="textall"><div class="toptext"><div class="name" style="color: #bbbbbb">{{ pinlun.username }}</div><div class="jigou1" style="color: #bbbbbb">{{ pinlun.mechanism }}</div></div><div class="heng"></div><div class="text"><div class="top"><div class="image"><img :src="pinlun.head_img" alt="" /></div><div class="top-right"><div class="names">大毛子</div><div class="times" style="color: #bbbbbb">{{ pinlun.dianpingtime | momentTimeFull }}</div></div></div><div class="detail">{{ pinlun.dptext }}</div></div></div></div><!-- <div slot="footer" class="dialog-footer"><el-button @click="dialogFormVisible = false">取 消</el-button><el-button type="primary" @click="dialogFormVisible = false">确 定</el-button></div> --></el-dialog></div></div></div><!-- 上传视频弹窗 --><div class="tovideo"><divclass="videobtn"style="height: 100px; width: 100px"@click="dialogVisible = true"><img src="http://yikaojs.jymmy.cn/static/img/shipinsc.png" alt="" /></div><el-dialog :destroy-on-close="true" :visible.sync="dialogVisible"><Comment ref="upload_dialog"></Comment></el-dialog></div><key></key><back :backData="backGo"></back></div>
</template>

js

 此处用到     Vue--moment时间格式插件安装和使用  (可参考)

 此处用到       elementUI实现分页 - 简书

关于vue中的videoPlayer的src视频地址参数动态修改(网上一堆错误方法,被误导很久,自己找到了正确的方法,供大家借鉴) - 蔡文君 - 博客园

<script>
import back from "./conmon/back";
import key from './conmon/key'
import Comment from './comment.vue'  //引入视频上传页面
import moment from 'moment'   //引入时间组件
export default {components: {back,key,Comment //视频上传},data () {return {backGo: '',dialogFormVisible: false,  //弹窗初始化关闭dialogVisible: false,currentPage: 1,   // 默认显示第几页totalCount: 0,// 总条数currentType: 1,PageSize: 8,  // 默认每页显示的条数videoConfig: [],pinlun: {},videos: [],//小视频 数据配置playerOptions: {playbackRates: [0.7, 1.0, 1.5, 2.0], //播放速度autoplay: true, //如果true,浏览器准备好时开始回放。muted: false, // 默认情况下将会消除任何音频。loop: false, // 导致视频一结束就重新开始。preload: 'auto', // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)language: 'zh-CN',aspectRatio: '16:9', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。sources: [{src: '',  // ---路径为空方便动态赋值---type: 'video/mp4'  // 类型}],// poster: "../../static/images/test.jpg", //你的封面地址// width: document.documentElement.clientWidth,notSupportedMessage: '此视频暂无法播放,请稍后再试', //允许覆盖Video.js无法播放媒体源时显示的默认信息。controlBar: {timeDivider: true,durationDisplay: true,remainingTimeDisplay: false,fullscreenToggle: true  //全屏按钮}}}},mounted () {this.getData()},//过滤器filters: {momentTime (times) {return moment(times*1000).format('YYYY-MM-DD')  //显示时间的格式},momentTimeFull (times) {return moment(times*1000).format('YYYY-MM-DD HH:mm:ss')}},methods: {//选项卡改变事件nowschool () {// alert(123)$(".activeone").css("display", "block");$(".unactiveone").css("display", "none");$(".active").css("display", "none");$(".unactive").css("display", "block");$(".tab-now").css("display", "block");$(".tab-all").css("display", "none");this.currentPage = 1;  //显示第一页this.currentType = 1;  //此页面标识为1this.getData(this.currentType, this.currentPage)},allschool () {$(".active").css("display", "block");$(".unactive").css("display", "none");$(".activeone").css("display", "none");$(".unactiveone").css("display", "block");$(".tab-now").css("display", "none");$(".tab-all").css("display", "block");this.currentPage = 1;this.currentType = 2;//此页面标识为2this.getData()},//关闭弹框的事件closeDialog () {this.$refs.videoPlayer.player.pause(); //视频暂停},// 分页// 每页显示的条数handleSizeChange (val) {console.log(val)// 改变每页显示的条数 // this.PageSize = val// // 注意:在改变每页显示的条数时,要将页码显示到第一页// this.currentPage = 1},// 显示第几页handleCurrentChange (val) {console.log(val)this.currentPage = valthis.getData()// 改变默认的页数的// this.currentPage = val},getData () {this.videos = []this.videoConfig = []var urll = ''var uuid = JSON.parse(sessionStorage.getItem('cache')).user.id  var getdata = {}   //将页面中的数据传入 定义的空数组中 再传给后端//根据不同页面调用接口if (this.currentType === 1) {//当前校区urll = this.$api.pkapi + '后端接口'getdata['id'] = uuid} else if (this.currentType === 2) {//全国精选urll = this.$api.pkapi + '后端接口'}getdata['page'] = this.currentPagegetdata['list_rows'] = this.PageSizethis.$axios({url: urll,  //接口路径params: getdata, //参数集合}).then((res) => {console.log(res)console.log(res.data.code === 0)if (res.data.code === 1) {this.videos = res.data.data.data  //获取总数据(包含视频数据)this.totalCount = res.data.data.total //获取总页数//处理视频配置 循环取出多个视频放入videoConfig数组中for (let i in this.videos) {this.videoConfig.push({autoplay: false, //如果true,浏览器准备好时开始回放。muted: true, // 默认情况下将会消除任何音频。loop: false, // 导致视频一结束就重新开始。controls: false,preload: 'auto', // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)language: 'zh-CN',aspectRatio: '16:9', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。sources: [{src: this.videos[i].video,  // 获取视频路径type: 'video/mp4'  // 类型}],// poster: "../../static/images/test.jpg", //你的封面地址// width: document.documentElement.clientWidth,notSupportedMessage: '此视频暂无法播放,请稍后再试', //允许覆盖Video.js无法播放媒体源时显示的默认信息。controlBar: {timeDivider: false,durationDisplay: false,remainingTimeDisplay: false,fullscreenToggle: false  //全屏按钮}})}}}).catch((err) => {console.log(err)})},//点击小视频获取对应的大视频数据getVideoDetail (index) {this.pinlun = {}this.dialogFormVisible = truevar vid = this.videos[index].idthis.$axios({url: this.$api.pkapi + '后端接口',params: {id: vid},}).then((res) => {console.log(res)console.log(res.data.code === 0)if (res.data.code === 1) {this.playerOptions.sources[0].src = res.data.data.video //获取后端视频路径动态赋值console.log(this.playerOptions.sources[0].src);this.pinlun = res.data.data   //获取弹窗中信息}}).catch((err) => {console.log(err)})}}
}</script>

css


<style scoped>
.container {width: 1920px;height: 1080px;background: url("http://yikaojs.jymmy.cn/static/img/bei1.png");position: relative;
}
.content {width: 1720px;height: 829px;margin: auto;padding-top: 20px;position: relative;top: 20%;border-radius: 10px;background: rgba(255, 245, 245, 0.3);
}
.nav {width: 1680px;height: 794px;margin: auto;border-radius: 10px;background: #ffffff;/* position: relative; */
}
.tabs {width: 50%;margin: auto;display: flex;justify-content: space-around;position: relative;top: -20%;
}
.tabcards {width: 90%;height: 640px;margin: -25px auto;/* background: chartreuse; */padding-left: 5px;z-index: 999999;
}
.box {height: 246px;width: 350px;border-radius: 10px;position: relative;float: left;margin: 30px 12px;
}
.video-small {height: 246px;width: 350px;background: rgba(29, 28, 28, 0.3);border-radius: 10px;
}
.video-small >>> .video-js {height: 246px;width: 360px;border-radius: 10px;background-color: transparent;
}
.video-small >>> .video-js .vjs-big-play-button {display: none;
}
.box > .text {width: 100%;height: 83px;background: rgba(0, 0, 0, 0.61);color: white;position: absolute;bottom: 0;border-bottom-left-radius: 10px;border-bottom-right-radius: 10px;
}
.jigou {font-size: 20px;/* text-align: left; */margin-left: 38px;margin-top: 5px;margin-bottom: 5px;
}
.bottom {display: flex;justify-content: space-around;
}
.name {font-size: 29px;
}
.time {margin-top: 12px;font-size: 18px;
}
.el-pagination {/* background: red; *//* color: #ffffff; */height: 50px;position: relative;top: 72px;
}.el-pagination >>> .btn-prev {width: 70px;height: 70px;background: url("http://yikaojs.jymmy.cn/static/img/left.png");position: absolute;left: 15px;color: white;
}
.el-pagination >>> .btn-next {width: 70px;height: 70px;background: url("http://yikaojs.jymmy.cn/static/img/right1.png");position: absolute;right: 15px;color: white;
}
.el-pagination >>> .btn-prev:disabled {width: 70px;height: 70px;color: white;background: url("http://yikaojs.jymmy.cn/static/img/left1.png");
}
.el-pagination >>> .btn-next:disabled {width: 70px;height: 70px;color: white;background: url("http://yikaojs.jymmy.cn/static/img/right.png");
}
.tan {width: 1249px;height: 959px;/* background: greenyellow; */
}.tan >>> .el-dialog {width: 1249px;height: 990px;/* margin: auto; */margin-top: 5% !important;background: url("http://yikaojs.jymmy.cn/static/img/tan2.png") no-repeat;background-size: 100% 100%;box-shadow: none;
}
/* 叉号 */
.tan >>> .el-dialog__headerbtn {height: 40px;width: 42px;background: url("http://yikaojs.jymmy.cn/static/img/cha.png") no-repeat;background-size: 100% 100%;margin: 15px;
}
.videoall {height: 850px;width: 1004px;margin: auto;
}
.video-demo {width: 1004px;height: 435px;margin: auto;border-radius: 10px;
}
.video-demo >>> .video-js .vjs-tech {width: 100%;height: 100%;margin: auto;border-radius: 10px;
}
.textall {width: 100%;height: 330px;margin: auto;position: relative;top: 15%;/* background: tomato; */
}
.toptext {
margin-bottom: 5px;
}
.jigou1 {color: white;font-size: 20px;/* margin: 1px 0; */
}
.heng {background: white;width: 100%;height: 2px;border-radius: 1px;opacity: 0.1;/* position:absolute;top: 34%; */
}
.text {height: 250px;width: 100%;/* background: turquoise; */margin-top: 15px;
}
.top {width: 30%;height: 85px;display: flex;justify-content: space-around;
}
.image {height: 85px;width: 94px;
}
.image > img {height: 85px;width: 94px;
}
.names {color: white;font-size: 29px;font-weight: bold;
}
.times {margin-top: 12px;font-size: 18px;
}
.detail {height: 155px;width: 86%;/* margin-top: 10px; */background: #23232e;border-radius: 10px;color: white;padding: 10px 20px;position: absolute;right: 0;
}
.container > .tovideo {position: absolute;right: -10px;top: 35%;
}
.tovideo >>> .el-dialog {width: 1249px;height: 809px;border-radius: 4px;background: url("http://yikaojs.jymmy.cn/static/img/tan.png") no-repeat;background-size: 100% 100%;
}
.tovideo >>> .el-dialog__headerbtn {height: 40px;width: 42px;background: url("http://yikaojs.jymmy.cn/static/img/cha.png") no-repeat;background-size: 100% 100%;margin: 15px;
}
</style>

效果图:

小视频展示页面 

​​​​​​​​​​​​​​​​​​​​​​​​​

 

大视频详情展示页面

 

 

 

 

这篇关于vue-video-player 实现动态渲染后端传来的视频的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/897909

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

流媒体平台/视频监控/安防视频汇聚EasyCVR播放暂停后视频画面黑屏是什么原因?

视频智能分析/视频监控/安防监控综合管理系统EasyCVR视频汇聚融合平台,是TSINGSEE青犀视频垂直深耕音视频流媒体技术、AI智能技术领域的杰出成果。该平台以其强大的视频处理、汇聚与融合能力,在构建全栈视频监控系统中展现出了独特的优势。视频监控管理系统EasyCVR平台内置了强大的视频解码、转码、压缩等技术,能够处理多种视频流格式,并以多种格式(RTMP、RTSP、HTTP-FLV、WebS

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

【 html+css 绚丽Loading 】000046 三才归元阵

前言:哈喽,大家好,今天给大家分享html+css 绚丽Loading!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 📚一、效果📚二、信息💡1.简介:💡2.外观描述:💡3.使用方式:💡4.战斗方式:💡5.提升:💡6.传说: 📚三、源代码,上代码,可以直接复制使用🎥效果🗂️目录✍️

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

动态规划---打家劫舍

题目: 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。 思路: 动态规划五部曲: 1.确定dp数组及含义 dp数组是一维数组,dp[i]代表

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象