当前位置:   article > 正文

videoJS 视频 + 独一无二皮肤 + mp4/m3u8_video.js 好看的样式

video.js 好看的样式

推荐和参考文章:

video.js调用-腾讯云开发者社区-腾讯云>  一、总结(点击显示或隐藏总结内容)一句话总结:网上有各种细致的现成的代码可以拿来用,没必要自己死专1、video.js有两种初始化方式?一种是在video的html标签之中一种是使用jicon-default.png?t=N7T8https://cloud.tencent.com/developer/article/1649057?from=15425video.js的使用,打造自定义视频播放器 - 简书温馨提示:在HTML5中,video标签本身有个自定义属性playbackRate[https://www.w3school.com.cn/tags/av_prop_play...icon-default.png?t=N7T8https://www.jianshu.com/p/3b38f795616f 

 

  1. <template>
  2. <div>
  3. <el-button
  4. @click="openDialog('http://ai-xxxxx4.m3u8', 1)"
  5. type="primary">Open Video 1 (.m3u8)</el-button>
  6. <el-button
  7. @click="openDialog('http://xxxxx4.mp4', 2)"
  8. type="primary">Open Video 2 (.mp4)</el-button>
  9. <el-button @click="openDialog('', 3)" type="primary">Unable to play.</el-button>
  10. <el-button @click="openDialog('http://txax-vssod.cdn.xxxx/8888/', 3)" type="primary">err Link</el-button>
  11. <el-dialog v-if="showDialog" :visible.sync="showDialog" :title="'Video ' + currentPlayerId" @close="closeDialog"
  12. width="720px" class="video-dialog">
  13. <div v-if="videoError">
  14. <p>{{ videoError }}</p>
  15. </div>
  16. <video :id="'videoPlayer' + currentPlayerId" :class="videoClass" style="width: 100%;" controls preload="auto"
  17. :width="videoWidth">
  18. </video>
  19. </el-dialog>
  20. </div>
  21. </template>
  22. <script>
  23. import videojs from 'video.js';
  24. import 'video.js/dist/video-js.css';
  25. export default {
  26. data() {
  27. return {
  28. showDialog: false,
  29. currentPlayerId: null,
  30. videoPlayer: null,
  31. videoError: null,
  32. videoWidth: '720px', // Default width
  33. videoHeight: '450px', // Default height
  34. videoClass: 'video-js vjs-default-skin vjs-big-play-centered' // Default class
  35. };
  36. },
  37. methods: {
  38. openDialog(url, playerId) {
  39. this.showDialog = true;
  40. this.currentPlayerId = playerId;
  41. this.videoError = null;
  42. // Wait for next tick to ensure the element is mounted before initializing Video.js
  43. this.$nextTick(() => {
  44. this.initVideoPlayer(url);
  45. this.replacePlaybackRateText();
  46. });
  47. },
  48. closeDialog() {
  49. if (this.videoPlayer) {
  50. this.videoPlayer.dispose();
  51. this.videoPlayer = null;
  52. }
  53. this.showDialog = false;
  54. this.currentPlayerId = null;
  55. this.videoError = null;
  56. },
  57. initVideoPlayer(url) {
  58. this.videoPlayer = videojs('videoPlayer' + this.currentPlayerId, {
  59. html5: {
  60. hls: {
  61. overrideNative: true
  62. }
  63. },
  64. playbackRates: [0.5, 0.75, 1.0, 1.25, 1.5, 2],
  65. language: 'zh-CN' // 指定使用的语言为中文
  66. });
  67. this.videoPlayer.on('error', (error) => {
  68. console.error('Video playback error:', error);
  69. this.videoError = 'Unable to play the video.';
  70. });
  71. const type = this.getVideoType(url);
  72. if (type === 'video/mp4') {
  73. this.videoPlayer.src({
  74. src: url,
  75. type: 'video/mp4'
  76. });
  77. } else if (type === 'application/x-mpegURL') {
  78. this.videoPlayer.src({
  79. src: url,
  80. type: 'application/x-mpegURL'
  81. });
  82. }
  83. this.videoPlayer.ready(() => {
  84. // 忽略未使用的变量
  85. /* eslint-disable no-unused-vars */
  86. // const videoEl = document.getElementById('videoPlayer' + this.currentPlayerId);
  87. // const aspectRatio = this.videoPlayer.videoWidth() / this.videoPlayer.videoHeight();
  88. // this.videoWidth = 720;
  89. // this.videoHeight = this.videoWidth / aspectRatio;
  90. // videoEl.style.height = `${this.videoHeight}px`;
  91. this.videoPlayer.play();
  92. });
  93. },
  94. getVideoType(url) {
  95. const extension = url.toLowerCase().includes('.mp4') ? 'mp4' : 'm3u8';
  96. if (extension === 'mp4') {
  97. return 'video/mp4';
  98. } else if (extension === 'm3u8') {
  99. return 'application/x-mpegURL';
  100. } else {
  101. return '';
  102. }
  103. },
  104. replacePlaybackRateText() {
  105. const playbackRateButton = document.querySelector('.vjs-playback-rate .vjs-playback-rate-value');
  106. if (playbackRateButton) {
  107. playbackRateButton.textContent = '倍速'; // 替换原始文本为“倍速”
  108. }
  109. }
  110. },
  111. beforeDestroy() {
  112. if (this.videoPlayer) {
  113. this.videoPlayer.dispose();
  114. this.videoPlayer = null;
  115. }
  116. },
  117. };
  118. // 在加载 Video.js 播放器之前,添加以下代码
  119. videojs.addLanguage('zh-CN', {
  120. 'Playback Rate': '倍速'
  121. });
  122. </script>
  123. <style>
  124. /* Add any custom styles for the video player here */
  125. .video-dialog {
  126. .el-dialog__header {
  127. border-bottom: none;
  128. }
  129. .el-dialog__body {
  130. padding: 0;
  131. }
  132. /*
  133. .dialog-content {
  134. padding:0 40px;
  135. }
  136. .el-dialog__footer {
  137. padding: 10px 10px 10px;
  138. border-top: none;
  139. } */
  140. }
  141. </style>
  142. <style>
  143. .video-js button{
  144. outline: none;
  145. }
  146. .video-js.vjs-fluid,
  147. .video-js.vjs-16-9,
  148. .video-js.vjs-4-3{ /* 视频占满容器高度 */
  149. height: 100%;
  150. background-color: #161616;
  151. }
  152. .vjs-poster{
  153. background-color: #161616;
  154. }
  155. .vjs-paused .vjs-big-play-button,
  156. .vjs-paused.vjs-has-started .vjs-big-play-button {
  157. display: block;
  158. }
  159. .video-js .vjs-big-play-button { /* 中间大的播放按钮 */
  160. font-size: 2.5em;
  161. line-height: 2.3em;
  162. height: 2.5em;
  163. width: 2.5em;
  164. -webkit-border-radius: 2.5em;
  165. -moz-border-radius: 2.5em;
  166. border-radius: 2.5em;
  167. /* background-color: #73859f; */
  168. background-color: rgba(115, 133, 159, .5);
  169. border-width: 0.15em;
  170. margin-top: -1.25em;
  171. margin-left: -1.75em;
  172. }
  173. .video-js.vjs-paused .vjs-big-play-button{ /* 视频暂停时显示播放按钮 */
  174. display: block;
  175. }
  176. .video-js.vjs-error .vjs-big-play-button{ /* 视频加载出错时隐藏播放按钮 */
  177. display: none;
  178. }
  179. /* 中间的播放箭头 */
  180. .vjs-big-play-button .vjs-icon-placeholder {
  181. font-size: 1.63em;
  182. }
  183. /* 加载圆圈 */
  184. .vjs-loading-spinner {
  185. font-size: 2.5em;
  186. width: 2em;
  187. height: 2em;
  188. border-radius: 1em;
  189. margin-top: -1em;
  190. margin-left: -1.5em;
  191. }
  192. /* 点击屏幕播放/暂停 */
  193. /* .video-js.vjs-playing .vjs-tech {
  194. pointer-events: auto;
  195. } */
  196. /* 进度显示当前播放时间 */
  197. /*
  198. video.js 默认倒序显示时间,也就是视频播放的剩余时间。
  199. 要显示当前的播放时间,以及总共视频时长,加2行CSS解决
  200. */
  201. .video-js .vjs-time-control {
  202. display: block;
  203. padding-top: 1px;
  204. }
  205. .video-js .vjs-remaining-time {
  206. /* display: block;
  207. padding-top: 1px; */
  208. display: none;
  209. }
  210. /* 进度条背景色 */
  211. /* 播放进度条背景色 */
  212. .video-js .vjs-play-progress {
  213. /* 设置播放进度条的背景色为绿色 */
  214. background-color: #26A69A;
  215. }
  216. /* 音量条背景色 */
  217. .video-js .vjs-volume-level {
  218. /* 设置音量条的背景色为蓝色 */
  219. /* background-color: #2196f3; */
  220. background-color: #00aeec;
  221. }
  222. .vjs-mouse-display .vjs-time-tooltip{
  223. padding-bottom: 6px;
  224. background-color: #26A69A;
  225. }
  226. .video-js .vjs-play-progress .vjs-time-tooltip{
  227. display: none!important;
  228. }
  229. /*
  230. .vjs-button > .vjs-icon-placeholder:before{ // 控制条所有图标,图标字体大小最好使用px单位,如果使用em,各浏览器表现可能会不大一样
  231. font-size: 18px;
  232. line-height: 1.7;
  233. }*/
  234. </style>
  235. <style>
  236. .video-js .vjs-playback-rate .vjs-playback-rate-value {
  237. line-height: 2.4;
  238. font-size: 10px;
  239. padding: 4px ;
  240. }
  241. /* 为菜单项添加上下间距 */
  242. .video-js .vjs-playback-rate .vjs-menu-item-text {
  243. font-size: 10px;
  244. }
  245. /* 鼠标离开时恢复透明度为1,字体颜色为蓝色 */
  246. .video-js .vjs-playback-rate .vjs-menu-item.vjs-selected {
  247. opacity: 1;
  248. background-color: rgba(0, 0, 0, 0);
  249. color: #00aeec;
  250. }
  251. /* 鼠标悬停时将文字设置为蓝色 */
  252. .video-js .vjs-playback-rate .vjs-menu-item:hover .vjs-menu-item-text {
  253. /* color:#00aeec; */
  254. }
  255. /* 鼠标悬停时和选中时候整体透明度减轻 */
  256. .video-js .vjs-playback-rate .vjs-menu-item:hover,
  257. .video-js .vjs-playback-rate .vjs-selected {
  258. opacity: 0.7;
  259. }
  260. /* 隐藏垂直滚动条 */
  261. .video-js .vjs-playback-rate .vjs-menu-content {
  262. overflow-y: hidden;
  263. }
  264. /* 隐藏水平滚动条 */
  265. .video-js .vjs-playback-rate .vjs-menu-content {
  266. overflow-x: hidden;
  267. }
  268. </style>

改良版:

  1. <template>
  2. <div>
  3. <el-button @click="openDialog('https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8', 1)" type="primary">Open Video 1 (.m3u8)</el-button>
  4. <el-button @click="openDialog('https://media.w3.org/2010/05/sintel/trailer.mp4', 2)" type="primary">Open Video 2 (.mp4)</el-button>
  5. <el-button @click="openDialog('', 3)" type="primary">Unable to play.</el-button>
  6. <el-button @click="openDialog('http://txax-vssod.cdn.xxxx/8888/', 3)" type="primary">err Link</el-button>
  7. <el-dialog v-if="showDialog" :visible.sync="showDialog" :title="'Video ' + currentPlayerId" @close="closeDialog" width="720px" class="video-dialog">
  8. <div v-if="videoError">
  9. <p>{{ videoError }}</p>
  10. </div>
  11. <video :id="'videoPlayer' + currentPlayerId" :class="videoClass" style="width: 100%;" controls preload="auto" :width="videoWidth"></video>
  12. </el-dialog>
  13. </div>
  14. </template>
  15. <script>
  16. import videojs from 'video.js';
  17. import 'video.js/dist/video-js.css';
  18. import '@/js/customTimeDisplay'
  19. export default {
  20. data() {
  21. return {
  22. showDialog: false,
  23. currentPlayerId: null,
  24. videoPlayer: null,
  25. videoError: null,
  26. videoWidth: '720px', // Default width
  27. videoHeight: '450px', // Default height
  28. videoClass: 'video-js vjs-default-skin vjs-big-play-centered', // Default class
  29. sourceTypes: {
  30. 'video/mp4': 'video/mp4',
  31. 'application/x-mpegURL': 'application/x-mpegURL'
  32. },
  33. };
  34. },
  35. methods: {
  36. openDialog(url, playerId) {
  37. this.showDialog = true;
  38. this.currentPlayerId = playerId;
  39. this.videoError = null;
  40. // Wait for next tick to ensure the element is mounted before initializing Video.js
  41. this.$nextTick(() => {
  42. this.initVideoPlayer(url);
  43. });
  44. },
  45. closeDialog() {
  46. if (this.videoPlayer) {
  47. this.videoPlayer.dispose();
  48. this.videoPlayer = null;
  49. }
  50. this.showDialog = false;
  51. this.currentPlayerId = null;
  52. this.videoError = null;
  53. },
  54. initVideoPlayer(url) {
  55. this.videoPlayer = videojs('videoPlayer' + this.currentPlayerId, {
  56. html5: {
  57. hls: {
  58. overrideNative: true
  59. }
  60. },
  61. playbackRates: [0.5, 0.75, 1.0, 1.25, 1.5, 2],
  62. language: 'zh-CN' // 指定使用的语言为中文
  63. });
  64. // 添加 Video.js 插件功能:设置时间显示格式为 HH:MM:SS
  65. // 应用自定义时间格式显示插件
  66. this.videoPlayer.customTimeFormat();
  67. this.videoPlayer.on('error', (error) => {
  68. console.error('Video playback error:', error);
  69. this.videoError = 'Unable to play the video.';
  70. });
  71. const type = this.getVideoType(url);
  72. if (this.sourceTypes[type]) {
  73. this.videoPlayer.src({
  74. src: url,
  75. type: this.sourceTypes[type]
  76. });
  77. }
  78. this.videoPlayer.ready(() => {
  79. this.videoPlayer.play();
  80. });
  81. },
  82. getVideoType(url) {
  83. const extension = url.toLowerCase().includes('.mp4') ? 'mp4' : 'm3u8';
  84. if (extension === 'mp4') {
  85. return 'video/mp4';
  86. } else if (extension === 'm3u8') {
  87. return 'application/x-mpegURL';
  88. } else {
  89. return '';
  90. }
  91. }
  92. },
  93. beforeDestroy() {
  94. if (this.videoPlayer) {
  95. this.videoPlayer.dispose();
  96. this.videoPlayer = null;
  97. }
  98. }
  99. };
  100. // 在加载 Video.js 播放器之前,添加以下代码
  101. videojs.addLanguage('zh-CN', {
  102. 'Playback Rate': '倍速'
  103. });
  104. </script>
  105. <style>
  106. /* Add any custom styles for the video player here */
  107. .video-dialog {
  108. .el-dialog__header {
  109. border-bottom: none;
  110. }
  111. .el-dialog__body {
  112. padding: 0;
  113. }
  114. }
  115. </style>
  116. <style>
  117. .video-js button {
  118. outline: none;
  119. }
  120. .video-js.vjs-fluid,
  121. .video-js.vjs-16-9,
  122. .video-js.vjs-4-3 {
  123. /* 视频占满容器高度 */
  124. height: 100%;
  125. background-color: #161616;
  126. }
  127. .vjs-poster {
  128. background-color: #161616;
  129. }
  130. .vjs-paused .vjs-big-play-button,
  131. .vjs-paused.vjs-has-started .vjs-big-play-button {
  132. display: block;
  133. }
  134. .video-js .vjs-big-play-button {
  135. /* 中间大的播放按钮 */
  136. font-size: 2.5em;
  137. line-height: 2.3em;
  138. height: 2.5em;
  139. width: 2.5em;
  140. -webkit-border-radius: 2.5em;
  141. -moz-border-radius: 2.5em;
  142. border-radius: 2.5em;
  143. /* background-color: #73859f; */
  144. background-color: rgba(115, 133, 159, .5);
  145. border-width: 0.15em;
  146. margin-top: -1.25em;
  147. margin-left: -1.75em;
  148. }
  149. .video-js.vjs-paused .vjs-big-play-button {
  150. /* 视频暂停时显示播放按钮 */
  151. display: block;
  152. }
  153. .video-js.vjs-error .vjs-big-play-button {
  154. /* 视频加载出错时隐藏播放按钮 */
  155. display: none;
  156. }
  157. /* 中间的播放箭头 */
  158. .vjs-big-play-button .vjs-icon-placeholder {
  159. font-size: 1.63em;
  160. }
  161. /* 加载圆圈 */
  162. .vjs-loading-spinner {
  163. font-size: 2.5em;
  164. width: 2em;
  165. height: 2em;
  166. border-radius: 1em;
  167. margin-top: -1em;
  168. margin-left: -1.5em;
  169. }
  170. /* 点击屏幕播放/暂停 */
  171. /* .video-js.vjs-playing .vjs-tech {
  172. pointer-events: auto;
  173. } */
  174. /* 进度显示当前播放时间 */
  175. /*
  176. video.js 默认倒序显示时间,也就是视频播放的剩余时间。
  177. 要显示当前的播放时间,以及总共视频时长,加2行CSS解决
  178. */
  179. .video-js .vjs-time-control {
  180. display: block;
  181. padding-top: 1px;
  182. }
  183. .video-js .vjs-current-time, .vjs-no-flex .vjs-current-time {
  184. padding-right: 0 !important;
  185. }
  186. .video-js .vjs-duration, .vjs-no-flex .vjs-duration {
  187. padding-left: 0 !important;
  188. }
  189. .video-js .vjs-remaining-time {
  190. /* display: block;
  191. padding-top: 1px; */
  192. display: none;
  193. }
  194. /* 进度条背景色 */
  195. /* 播放进度条背景色 */
  196. .video-js .vjs-play-progress {
  197. /* 设置播放进度条的背景色为绿色 */
  198. /* background-color: #26A69A; */
  199. /* background-image: linear-gradient(to right, #58dae8, #00aeec) !important; */
  200. background-image: linear-gradient(to right, #e89e58, #ec6a00) !important;
  201. }
  202. /* 音量条背景色 */
  203. .video-js .vjs-volume-level {
  204. /* 设置音量条的背景色为蓝色 */
  205. /* background-color: #2196f3; */
  206. /* background-color: #00aeec; */
  207. /* background-image: linear-gradient(to right, #58dae8, #00aeec) !important; */
  208. background-image: linear-gradient(to right, #e89e58, #ec6a00) !important;
  209. }
  210. .vjs-mouse-display .vjs-time-tooltip {
  211. padding-bottom: 6px;
  212. background-color: #e48847;
  213. }
  214. .video-js .vjs-play-progress .vjs-time-tooltip {
  215. display: none !important;
  216. }
  217. /*
  218. .vjs-button > .vjs-icon-placeholder:before{ // 控制条所有图标,图标字体大小最好使用px单位,如果使用em,各浏览器表现可能会不大一样
  219. font-size: 18px;
  220. line-height: 1.7;
  221. }*/
  222. </style>
  223. <style>
  224. .video-js .vjs-playback-rate .vjs-playback-rate-value {
  225. line-height: 2.4;
  226. font-size: 10px;
  227. padding: 4px;
  228. }
  229. /* 为菜单项添加上下间距 */
  230. .video-js .vjs-playback-rate .vjs-menu-item-text {
  231. font-size: 10px;
  232. }
  233. /* 鼠标离开时恢复透明度为1,字体颜色为蓝色 */
  234. .video-js .vjs-playback-rate .vjs-menu-item.vjs-selected {
  235. opacity: 1;
  236. background-color: rgba(0, 0, 0, 0);
  237. color: #00aeec;
  238. }
  239. /* 鼠标悬停时将文字设置为蓝色 */
  240. .video-js .vjs-playback-rate .vjs-menu-item:hover .vjs-menu-item-text {
  241. /* color:#00aeec; */
  242. }
  243. /* 鼠标悬停时和选中时候整体透明度减轻 */
  244. .video-js .vjs-playback-rate .vjs-menu-item:hover,
  245. .video-js .vjs-playback-rate .vjs-selected {
  246. opacity: 0.7;
  247. }
  248. /* 隐藏垂直滚动条 */
  249. .video-js .vjs-playback-rate .vjs-menu-content {
  250. overflow-y: hidden;
  251. }
  252. /* 隐藏水平滚动条 */
  253. .video-js .vjs-playback-rate .vjs-menu-content {
  254. overflow-x: hidden;
  255. }
  256. </style>
  257. <style>
  258. /* 隐藏默认的进度条控制滑块 */
  259. .video-js .vjs-progress-control .vjs-play-progress.vjs-slider-bar:before {
  260. width: 0;
  261. height: 0;
  262. background: none;
  263. border: none;
  264. }
  265. /* 设置自定义图标作为进度条控制滑块 */
  266. .video-js .vjs-progress-control .vjs-play-progress.vjs-slider-bar:before {
  267. width: 20px;
  268. height: 20px;
  269. background-image: url('@/assets/huya.png');
  270. background-size: cover;
  271. background-position: center; /* 将背景图像居中显示 */
  272. content: '';
  273. display: block;
  274. position: absolute;
  275. top: 50%;
  276. /* left: 0; */
  277. transform: translateY(-50%);
  278. }
  279. </style>
  • customTimeDisplay.js
  1. import videojs from 'video.js';
  2. // 注册自定义插件
  3. videojs.registerPlugin('customTimeFormat', function () {
  4. var player = this;
  5. player.ready(function () {
  6. // 获取当前时间显示控件和总时间显示控件
  7. var currentTimeDisplay = player.controlBar.getChild('currentTimeDisplay');
  8. var durationDisplay = player.controlBar.getChild('durationDisplay');
  9. // 监听时间更新事件
  10. player.on('timeupdate', function () {
  11. updateTimeDisplay(currentTimeDisplay, player.currentTime());
  12. });
  13. // 监听总时间加载完成事件
  14. player.on('durationchange', function () {
  15. updateTimeDisplay(durationDisplay, player.duration());
  16. });
  17. });
  18. // 更新时间显示函数
  19. function updateTimeDisplay(displayComponent, timeInSeconds) {
  20. var formattedTime = formatTime(timeInSeconds);
  21. displayComponent.el().textContent = formattedTime;
  22. }
  23. // 格式化时间函数
  24. function formatTime(time) {
  25. var hours = Math.floor(time / 3600);
  26. var minutes = Math.floor((time % 3600) / 60);
  27. var seconds = Math.floor(time % 60);
  28. // 格式化成 HH:MM:SS
  29. var formattedTime = (hours < 10 ? '0' + hours : hours) + ':' +
  30. (minutes < 10 ? '0' + minutes : minutes) + ':' +
  31. (seconds < 10 ? '0' + seconds : seconds);
  32. return formattedTime;
  33. }
  34. });
  35. export default videojs;

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/空白诗007/article/detail/792366
推荐阅读
相关标签
  

闽ICP备14008679号