赞
踩
推荐和参考文章:
video.js调用-腾讯云开发者社区-腾讯云> 一、总结(点击显示或隐藏总结内容)一句话总结:网上有各种细致的现成的代码可以拿来用,没必要自己死专1、video.js有两种初始化方式?一种是在video的html标签之中一种是使用jhttps://cloud.tencent.com/developer/article/1649057?from=15425video.js的使用,打造自定义视频播放器 - 简书温馨提示:在HTML5中,video标签本身有个自定义属性playbackRate[https://www.w3school.com.cn/tags/av_prop_play...
https://www.jianshu.com/p/3b38f795616f
- <template>
- <div>
- <el-button
- @click="openDialog('http://ai-xxxxx4.m3u8', 1)"
- type="primary">Open Video 1 (.m3u8)</el-button>
- <el-button
- @click="openDialog('http://xxxxx4.mp4', 2)"
- type="primary">Open Video 2 (.mp4)</el-button>
- <el-button @click="openDialog('', 3)" type="primary">Unable to play.</el-button>
- <el-button @click="openDialog('http://txax-vssod.cdn.xxxx/8888/', 3)" type="primary">err Link</el-button>
-
- <el-dialog v-if="showDialog" :visible.sync="showDialog" :title="'Video ' + currentPlayerId" @close="closeDialog"
- width="720px" class="video-dialog">
- <div v-if="videoError">
- <p>{{ videoError }}</p>
- </div>
- <video :id="'videoPlayer' + currentPlayerId" :class="videoClass" style="width: 100%;" controls preload="auto"
- :width="videoWidth">
- </video>
- </el-dialog>
- </div>
- </template>
-
- <script>
- import videojs from 'video.js';
- import 'video.js/dist/video-js.css';
-
- export default {
- data() {
- return {
- showDialog: false,
- currentPlayerId: null,
- videoPlayer: null,
- videoError: null,
- videoWidth: '720px', // Default width
- videoHeight: '450px', // Default height
- videoClass: 'video-js vjs-default-skin vjs-big-play-centered' // Default class
- };
- },
- methods: {
- openDialog(url, playerId) {
- this.showDialog = true;
- this.currentPlayerId = playerId;
- this.videoError = null;
- // Wait for next tick to ensure the element is mounted before initializing Video.js
- this.$nextTick(() => {
- this.initVideoPlayer(url);
- this.replacePlaybackRateText();
- });
- },
- closeDialog() {
- if (this.videoPlayer) {
- this.videoPlayer.dispose();
- this.videoPlayer = null;
- }
- this.showDialog = false;
- this.currentPlayerId = null;
- this.videoError = null;
- },
- initVideoPlayer(url) {
- this.videoPlayer = videojs('videoPlayer' + this.currentPlayerId, {
- html5: {
- hls: {
- overrideNative: true
- }
- },
- playbackRates: [0.5, 0.75, 1.0, 1.25, 1.5, 2],
- language: 'zh-CN' // 指定使用的语言为中文
- });
-
- this.videoPlayer.on('error', (error) => {
- console.error('Video playback error:', error);
- this.videoError = 'Unable to play the video.';
- });
-
- const type = this.getVideoType(url);
-
- if (type === 'video/mp4') {
- this.videoPlayer.src({
- src: url,
- type: 'video/mp4'
- });
- } else if (type === 'application/x-mpegURL') {
- this.videoPlayer.src({
- src: url,
- type: 'application/x-mpegURL'
- });
- }
-
- this.videoPlayer.ready(() => {
- // 忽略未使用的变量
- /* eslint-disable no-unused-vars */
- // const videoEl = document.getElementById('videoPlayer' + this.currentPlayerId);
- // const aspectRatio = this.videoPlayer.videoWidth() / this.videoPlayer.videoHeight();
- // this.videoWidth = 720;
- // this.videoHeight = this.videoWidth / aspectRatio;
- // videoEl.style.height = `${this.videoHeight}px`;
- this.videoPlayer.play();
- });
-
- },
- getVideoType(url) {
- const extension = url.toLowerCase().includes('.mp4') ? 'mp4' : 'm3u8';
- if (extension === 'mp4') {
- return 'video/mp4';
- } else if (extension === 'm3u8') {
- return 'application/x-mpegURL';
- } else {
- return '';
- }
- },
- replacePlaybackRateText() {
- const playbackRateButton = document.querySelector('.vjs-playback-rate .vjs-playback-rate-value');
- if (playbackRateButton) {
- playbackRateButton.textContent = '倍速'; // 替换原始文本为“倍速”
- }
- }
- },
- beforeDestroy() {
- if (this.videoPlayer) {
- this.videoPlayer.dispose();
- this.videoPlayer = null;
- }
- },
- };
-
- // 在加载 Video.js 播放器之前,添加以下代码
- videojs.addLanguage('zh-CN', {
- 'Playback Rate': '倍速'
- });
- </script>
-
- <style>
- /* Add any custom styles for the video player here */
- .video-dialog {
- .el-dialog__header {
- border-bottom: none;
- }
-
- .el-dialog__body {
- padding: 0;
- }
-
- /*
- .dialog-content {
- padding:0 40px;
- }
- .el-dialog__footer {
- padding: 10px 10px 10px;
- border-top: none;
- } */
- }
- </style>
-
- <style>
-
- .video-js button{
- outline: none;
- }
- .video-js.vjs-fluid,
- .video-js.vjs-16-9,
- .video-js.vjs-4-3{ /* 视频占满容器高度 */
- height: 100%;
- background-color: #161616;
- }
- .vjs-poster{
- background-color: #161616;
- }
-
- .vjs-paused .vjs-big-play-button,
- .vjs-paused.vjs-has-started .vjs-big-play-button {
- display: block;
- }
-
- .video-js .vjs-big-play-button { /* 中间大的播放按钮 */
- font-size: 2.5em;
- line-height: 2.3em;
- height: 2.5em;
- width: 2.5em;
- -webkit-border-radius: 2.5em;
- -moz-border-radius: 2.5em;
- border-radius: 2.5em;
- /* background-color: #73859f; */
- background-color: rgba(115, 133, 159, .5);
- border-width: 0.15em;
- margin-top: -1.25em;
- margin-left: -1.75em;
- }
-
- .video-js.vjs-paused .vjs-big-play-button{ /* 视频暂停时显示播放按钮 */
- display: block;
- }
- .video-js.vjs-error .vjs-big-play-button{ /* 视频加载出错时隐藏播放按钮 */
- display: none;
- }
-
- /* 中间的播放箭头 */
- .vjs-big-play-button .vjs-icon-placeholder {
- font-size: 1.63em;
- }
-
- /* 加载圆圈 */
- .vjs-loading-spinner {
- font-size: 2.5em;
- width: 2em;
- height: 2em;
- border-radius: 1em;
- margin-top: -1em;
- margin-left: -1.5em;
- }
-
- /* 点击屏幕播放/暂停 */
- /* .video-js.vjs-playing .vjs-tech {
- pointer-events: auto;
- } */
-
- /* 进度显示当前播放时间 */
- /*
- video.js 默认倒序显示时间,也就是视频播放的剩余时间。
- 要显示当前的播放时间,以及总共视频时长,加2行CSS解决
- */
-
- .video-js .vjs-time-control {
- display: block;
- padding-top: 1px;
- }
- .video-js .vjs-remaining-time {
- /* display: block;
- padding-top: 1px; */
- display: none;
- }
-
- /* 进度条背景色 */
- /* 播放进度条背景色 */
- .video-js .vjs-play-progress {
- /* 设置播放进度条的背景色为绿色 */
- background-color: #26A69A;
- }
-
- /* 音量条背景色 */
- .video-js .vjs-volume-level {
- /* 设置音量条的背景色为蓝色 */
- /* background-color: #2196f3; */
- background-color: #00aeec;
- }
-
- .vjs-mouse-display .vjs-time-tooltip{
- padding-bottom: 6px;
- background-color: #26A69A;
- }
-
- .video-js .vjs-play-progress .vjs-time-tooltip{
- display: none!important;
- }
- /*
- .vjs-button > .vjs-icon-placeholder:before{ // 控制条所有图标,图标字体大小最好使用px单位,如果使用em,各浏览器表现可能会不大一样
- font-size: 18px;
- line-height: 1.7;
- }*/
- </style>
-
- <style>
- .video-js .vjs-playback-rate .vjs-playback-rate-value {
- line-height: 2.4;
- font-size: 10px;
- padding: 4px ;
- }
-
- /* 为菜单项添加上下间距 */
- .video-js .vjs-playback-rate .vjs-menu-item-text {
- font-size: 10px;
- }
-
- /* 鼠标离开时恢复透明度为1,字体颜色为蓝色 */
- .video-js .vjs-playback-rate .vjs-menu-item.vjs-selected {
- opacity: 1;
- background-color: rgba(0, 0, 0, 0);
- color: #00aeec;
- }
-
-
- /* 鼠标悬停时将文字设置为蓝色 */
- .video-js .vjs-playback-rate .vjs-menu-item:hover .vjs-menu-item-text {
- /* color:#00aeec; */
- }
-
- /* 鼠标悬停时和选中时候整体透明度减轻 */
- .video-js .vjs-playback-rate .vjs-menu-item:hover,
- .video-js .vjs-playback-rate .vjs-selected {
- opacity: 0.7;
- }
-
- /* 隐藏垂直滚动条 */
- .video-js .vjs-playback-rate .vjs-menu-content {
- overflow-y: hidden;
- }
-
- /* 隐藏水平滚动条 */
- .video-js .vjs-playback-rate .vjs-menu-content {
- overflow-x: hidden;
- }
-
- </style>
-

改良版:
- <template>
- <div>
- <el-button @click="openDialog('https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8', 1)" type="primary">Open Video 1 (.m3u8)</el-button>
- <el-button @click="openDialog('https://media.w3.org/2010/05/sintel/trailer.mp4', 2)" type="primary">Open Video 2 (.mp4)</el-button>
- <el-button @click="openDialog('', 3)" type="primary">Unable to play.</el-button>
- <el-button @click="openDialog('http://txax-vssod.cdn.xxxx/8888/', 3)" type="primary">err Link</el-button>
-
- <el-dialog v-if="showDialog" :visible.sync="showDialog" :title="'Video ' + currentPlayerId" @close="closeDialog" width="720px" class="video-dialog">
- <div v-if="videoError">
- <p>{{ videoError }}</p>
- </div>
- <video :id="'videoPlayer' + currentPlayerId" :class="videoClass" style="width: 100%;" controls preload="auto" :width="videoWidth"></video>
- </el-dialog>
- </div>
- </template>
-
- <script>
- import videojs from 'video.js';
- import 'video.js/dist/video-js.css';
- import '@/js/customTimeDisplay'
-
- export default {
- data() {
- return {
- showDialog: false,
- currentPlayerId: null,
- videoPlayer: null,
- videoError: null,
- videoWidth: '720px', // Default width
- videoHeight: '450px', // Default height
- videoClass: 'video-js vjs-default-skin vjs-big-play-centered', // Default class
- sourceTypes: {
- 'video/mp4': 'video/mp4',
- 'application/x-mpegURL': 'application/x-mpegURL'
- },
- };
- },
- methods: {
- openDialog(url, playerId) {
- this.showDialog = true;
- this.currentPlayerId = playerId;
- this.videoError = null;
- // Wait for next tick to ensure the element is mounted before initializing Video.js
- this.$nextTick(() => {
- this.initVideoPlayer(url);
- });
- },
- closeDialog() {
- if (this.videoPlayer) {
- this.videoPlayer.dispose();
- this.videoPlayer = null;
- }
- this.showDialog = false;
- this.currentPlayerId = null;
- this.videoError = null;
- },
- initVideoPlayer(url) {
- this.videoPlayer = videojs('videoPlayer' + this.currentPlayerId, {
- html5: {
- hls: {
- overrideNative: true
- }
- },
- playbackRates: [0.5, 0.75, 1.0, 1.25, 1.5, 2],
- language: 'zh-CN' // 指定使用的语言为中文
- });
-
- // 添加 Video.js 插件功能:设置时间显示格式为 HH:MM:SS
- // 应用自定义时间格式显示插件
- this.videoPlayer.customTimeFormat();
-
-
- this.videoPlayer.on('error', (error) => {
- console.error('Video playback error:', error);
- this.videoError = 'Unable to play the video.';
- });
-
- const type = this.getVideoType(url);
- if (this.sourceTypes[type]) {
- this.videoPlayer.src({
- src: url,
- type: this.sourceTypes[type]
- });
- }
-
- this.videoPlayer.ready(() => {
- this.videoPlayer.play();
- });
- },
- getVideoType(url) {
- const extension = url.toLowerCase().includes('.mp4') ? 'mp4' : 'm3u8';
- if (extension === 'mp4') {
- return 'video/mp4';
- } else if (extension === 'm3u8') {
- return 'application/x-mpegURL';
- } else {
- return '';
- }
- }
- },
- beforeDestroy() {
- if (this.videoPlayer) {
- this.videoPlayer.dispose();
- this.videoPlayer = null;
- }
- }
- };
-
- // 在加载 Video.js 播放器之前,添加以下代码
- videojs.addLanguage('zh-CN', {
- 'Playback Rate': '倍速'
- });
- </script>
-
- <style>
- /* Add any custom styles for the video player here */
- .video-dialog {
- .el-dialog__header {
- border-bottom: none;
- }
-
- .el-dialog__body {
- padding: 0;
- }
- }
- </style>
-
- <style>
- .video-js button {
- outline: none;
- }
-
- .video-js.vjs-fluid,
- .video-js.vjs-16-9,
- .video-js.vjs-4-3 {
- /* 视频占满容器高度 */
- height: 100%;
- background-color: #161616;
- }
-
- .vjs-poster {
- background-color: #161616;
- }
-
- .vjs-paused .vjs-big-play-button,
- .vjs-paused.vjs-has-started .vjs-big-play-button {
- display: block;
- }
-
- .video-js .vjs-big-play-button {
- /* 中间大的播放按钮 */
- font-size: 2.5em;
- line-height: 2.3em;
- height: 2.5em;
- width: 2.5em;
- -webkit-border-radius: 2.5em;
- -moz-border-radius: 2.5em;
- border-radius: 2.5em;
- /* background-color: #73859f; */
- background-color: rgba(115, 133, 159, .5);
- border-width: 0.15em;
- margin-top: -1.25em;
- margin-left: -1.75em;
- }
-
- .video-js.vjs-paused .vjs-big-play-button {
- /* 视频暂停时显示播放按钮 */
- display: block;
- }
-
- .video-js.vjs-error .vjs-big-play-button {
- /* 视频加载出错时隐藏播放按钮 */
- display: none;
- }
-
- /* 中间的播放箭头 */
- .vjs-big-play-button .vjs-icon-placeholder {
- font-size: 1.63em;
- }
-
- /* 加载圆圈 */
- .vjs-loading-spinner {
- font-size: 2.5em;
- width: 2em;
- height: 2em;
- border-radius: 1em;
- margin-top: -1em;
- margin-left: -1.5em;
- }
-
- /* 点击屏幕播放/暂停 */
- /* .video-js.vjs-playing .vjs-tech {
- pointer-events: auto;
- } */
-
- /* 进度显示当前播放时间 */
- /*
- video.js 默认倒序显示时间,也就是视频播放的剩余时间。
- 要显示当前的播放时间,以及总共视频时长,加2行CSS解决
- */
-
- .video-js .vjs-time-control {
- display: block;
- padding-top: 1px;
- }
-
- .video-js .vjs-current-time, .vjs-no-flex .vjs-current-time {
- padding-right: 0 !important;
- }
-
-
- .video-js .vjs-duration, .vjs-no-flex .vjs-duration {
- padding-left: 0 !important;
- }
-
- .video-js .vjs-remaining-time {
- /* display: block;
- padding-top: 1px; */
- display: none;
- }
-
- /* 进度条背景色 */
- /* 播放进度条背景色 */
- .video-js .vjs-play-progress {
- /* 设置播放进度条的背景色为绿色 */
- /* background-color: #26A69A; */
- /* background-image: linear-gradient(to right, #58dae8, #00aeec) !important; */
- background-image: linear-gradient(to right, #e89e58, #ec6a00) !important;
- }
-
- /* 音量条背景色 */
- .video-js .vjs-volume-level {
- /* 设置音量条的背景色为蓝色 */
- /* background-color: #2196f3; */
- /* background-color: #00aeec; */
- /* background-image: linear-gradient(to right, #58dae8, #00aeec) !important; */
- background-image: linear-gradient(to right, #e89e58, #ec6a00) !important;
- }
-
- .vjs-mouse-display .vjs-time-tooltip {
- padding-bottom: 6px;
- background-color: #e48847;
- }
-
- .video-js .vjs-play-progress .vjs-time-tooltip {
- display: none !important;
- }
-
- /*
- .vjs-button > .vjs-icon-placeholder:before{ // 控制条所有图标,图标字体大小最好使用px单位,如果使用em,各浏览器表现可能会不大一样
- font-size: 18px;
- line-height: 1.7;
- }*/
- </style>
-
- <style>
- .video-js .vjs-playback-rate .vjs-playback-rate-value {
- line-height: 2.4;
- font-size: 10px;
- padding: 4px;
- }
-
- /* 为菜单项添加上下间距 */
- .video-js .vjs-playback-rate .vjs-menu-item-text {
- font-size: 10px;
- }
-
- /* 鼠标离开时恢复透明度为1,字体颜色为蓝色 */
- .video-js .vjs-playback-rate .vjs-menu-item.vjs-selected {
- opacity: 1;
- background-color: rgba(0, 0, 0, 0);
- color: #00aeec;
- }
-
- /* 鼠标悬停时将文字设置为蓝色 */
- .video-js .vjs-playback-rate .vjs-menu-item:hover .vjs-menu-item-text {
- /* color:#00aeec; */
- }
-
- /* 鼠标悬停时和选中时候整体透明度减轻 */
- .video-js .vjs-playback-rate .vjs-menu-item:hover,
- .video-js .vjs-playback-rate .vjs-selected {
- opacity: 0.7;
- }
-
- /* 隐藏垂直滚动条 */
- .video-js .vjs-playback-rate .vjs-menu-content {
- overflow-y: hidden;
- }
-
- /* 隐藏水平滚动条 */
- .video-js .vjs-playback-rate .vjs-menu-content {
- overflow-x: hidden;
- }
- </style>
- <style>
- /* 隐藏默认的进度条控制滑块 */
- .video-js .vjs-progress-control .vjs-play-progress.vjs-slider-bar:before {
- width: 0;
- height: 0;
- background: none;
- border: none;
- }
-
- /* 设置自定义图标作为进度条控制滑块 */
- .video-js .vjs-progress-control .vjs-play-progress.vjs-slider-bar:before {
- width: 20px;
- height: 20px;
- background-image: url('@/assets/huya.png');
- background-size: cover;
- background-position: center; /* 将背景图像居中显示 */
- content: '';
- display: block;
- position: absolute;
- top: 50%;
- /* left: 0; */
- transform: translateY(-50%);
- }
-
- </style>

- import videojs from 'video.js';
-
- // 注册自定义插件
- videojs.registerPlugin('customTimeFormat', function () {
- var player = this;
-
- player.ready(function () {
- // 获取当前时间显示控件和总时间显示控件
- var currentTimeDisplay = player.controlBar.getChild('currentTimeDisplay');
- var durationDisplay = player.controlBar.getChild('durationDisplay');
-
- // 监听时间更新事件
- player.on('timeupdate', function () {
- updateTimeDisplay(currentTimeDisplay, player.currentTime());
- });
-
- // 监听总时间加载完成事件
- player.on('durationchange', function () {
- updateTimeDisplay(durationDisplay, player.duration());
- });
- });
-
- // 更新时间显示函数
- function updateTimeDisplay(displayComponent, timeInSeconds) {
- var formattedTime = formatTime(timeInSeconds);
- displayComponent.el().textContent = formattedTime;
- }
-
- // 格式化时间函数
- function formatTime(time) {
- var hours = Math.floor(time / 3600);
- var minutes = Math.floor((time % 3600) / 60);
- var seconds = Math.floor(time % 60);
-
- // 格式化成 HH:MM:SS
- var formattedTime = (hours < 10 ? '0' + hours : hours) + ':' +
- (minutes < 10 ? '0' + minutes : minutes) + ':' +
- (seconds < 10 ? '0' + seconds : seconds);
-
- return formattedTime;
- }
- });
-
- export default videojs;

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。