<template> <div class="video-player"> <video v-if="showVideo" ref="videoPlayer" class="video-js vjs-matrix vjs-yoho" :poster="coverImg" controls preload="auto" muted="muted" playsinline x5-playsinline webkit-playsinline="true"> <source :src="source" :type="sourceType"></source> <p class="vjs-no-js"> To view this video please enable JavaScript, and consider upgrading to a web browser </p> <div class="vjs-yoho-voice"></div> </video> </div> </template> <script> import {get} from 'lodash'; import videojs from 'video.js'; import {getArticleImageSize, processImage} from 'utils/image-handler'; import versionCompare from 'utils/version'; export default { name: 'VideoPlayer', props: { source: String, cover: String, width: [Number, String], height: [Number, String], options: { type: Object, default() { return { muted: true, controls: true, aspectRatio: '1:1' }; } } }, data() { return { showVideo: false, player: null }; }, computed: { coverImg() { if (this.cover) { if (this.width && this.height) { let imgSize = getArticleImageSize({ width: this.width, height: this.height, minScale: 0, maxWidth: 500 }); return processImage(this.cover, 2, imgSize.width, imgSize.height, get(this.yoho, 'window.supportWebp')); } else { return this.cover.split('?')[0]; } } else { return ''; } }, sourceType() { let type = 'video/mp4'; if (this.source) { let source = this.source.split('?')[0]; source = source.split('.'); switch (source[source.length - 1]) { case 'opus': case 'ogv': type = 'video/ogg'; break; case 'mkv': type = 'video/x-matroska'; break; case 'm3u8': type = 'application/x-mpegURL'; break; case 'm4a': type = 'audio/mp4'; break; case 'mp3': type = 'audio/mpeg'; break; case 'aac': type = 'audio/aac'; break; case 'oga': type = 'audio/ogg'; break; default: break; } } return type; } }, watch: { source() { this.showPlayer(); } }, mounted() { this.showPlayer(); }, beforeDestroy() { if (this.player) { this.player.dispose(); } }, methods: { showPlayer() { if (this.showVideo || !this.source) { return; } this.showVideo = true; this.$nextTick(() => { this.initPlayer(); }); }, initPlayer() { const noVioceClass = 'vjs-yoho-novoice'; this.player = videojs(this.$refs.videoPlayer, this.options); this.voiceBtn = this.player.addChild('button'); this.voiceBtn.addClass('vjs-yoho-voice'); this.voiceBtn.addClass(noVioceClass); this.backBtn = this.player.addChild('button'); this.backBtn.addClass('vjs-yoho-back'); this.voiceBtn.on('touchend', () => { this.player.muted(!this.voiceBtn.hasClass(noVioceClass)); }); this.backBtn.on('touchend', () => { this.player.exitFullscreen(); }); this.player.on('play', () => { this.player._yohoPlayTime = this.getTime(); }); this.player.on('pause', () => { this.player._yohoPauseTime = this.getTime(); }); this.player.on('ended', () => { this.player._yohoEndedTime = this.getTime(); }); this.player.on('fullscreenchange', () => { // ios 退出全屏自动播放 if (this.$yoho.isiOS && versionCompare(this.$yoho.appVersion, '6.9.7') > 0) { let changeTime = this.getTime(); let playTime = this.player._yohoPlayTime || 0; let pauseTime = this.player._yohoPauseTime || 0; let endedTime = this.player._yohoEndedTime || 0; if ((changeTime - pauseTime) < 600 && pauseTime > playTime && playTime > endedTime) { setTimeout(() => { this.player.play(); }, 1000); } } }); this.player.on('volumechange', () => { const soundOff = this.player.muted() || this.player.volume() === 0; if (soundOff) { this.voiceBtn.addClass(noVioceClass); } else { this.voiceBtn.removeClass(noVioceClass); } }); this.$yoho.getNetStatus({}, (res) => { alert(res?.wifi); if (res?.wifi === '1' || res?.wifi === 1) { this.player.autoplay('muted'); } }); }, getTime() { return new Date().getTime(); } } }; </script> <style lang="scss" scoped> .video-js { width: 100%; height: auto; video { width: 100%; } &.vjs-yoho /deep/ { position: relative; background-color: #222; .vjs-resize-manager { z-index: 0; visibility: hidden; } .vjs-poster { background-color: #222; } .vjs-yoho-voice { width: 60px; height: 60px; position: absolute; top: 20px; right: 28px; opacity: 0; visibility: hidden; background: url("~statics/image/components/video-voice-icon.png"); background-size: cover; background-repeat: no-repeat; &.vjs-yoho-novoice { background-position: bottom left; } } &.vjs-has-started .vjs-yoho-voice { visibility: visible; opacity: 1; transition: visibility 1s, opacity 1s; } &.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-yoho-voice { visibility: visible; opacity: 0; } .vjs-big-play-button { width: 126px; height: 126px; line-height: 126px; font-size: 60px; border: none; left: 50%; top: 50%; margin: -63px auto auto -63px; /* background: url("~statics/image/components/video-play-btn.png"); */ background: url("data:image/png;base64,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"); background-size: contain; background-repeat: no-repeat; > * { display: none; } } @keyframes roundframe { 0% { -webkit-transform: rotate(0deg); } 25% { -webkit-transform: rotate(90deg); } 50% { -webkit-transform: rotate(180deg); } 75% { -webkit-transform: rotate(270deg); } 100% { -webkit-transform: rotate(360deg); } } .vjs-loading-spinner { width: 110px; height: 110px; margin-top: -55px; margin-left: -55px; border: none; background: url("~statics/image/components/video-loading-icon.png"); background-size: contain; background-repeat: no-repeat; background-position: center center; visibility: visible; animation: roundframe 1.3s linear infinite; &:before, &:after, > * { display: none; } } .vjs-control-bar { height: 80px; background: none; padding-bottom: 20px; .vjs-control { width: 80px; } .vjs-play-control { width: 60px; height: 60px; margin-left: 20px; background: url("~statics/image/components/video-play-icon.png"); background-size: cover; &.vjs-playing { background-position: bottom left; } > * { display: none; } } .vjs-volume-panel { display: none; } .vjs-duration, .vjs-current-time { display: block; order: 3; > span { font-size: 22px; font-weight: 300; } } .vjs-time-control { line-height: 60px; } .vjs-current-time { order: 1; } .vjs-remaining-time { display: none; } .vjs-progress-control { order: 2; .vjs-progress-holder { margin: 0; } .vjs-progress-holder, .vjs-load-progress, .vjs-play-progress { height: 1px; } .vjs-play-progress:before { font-size: 10px; top: 0; transform: translateY(-44%); } } .vjs-fullscreen-control { order: 4; width: 60px; height: 60px; margin-right: 20px; background: url("~statics/image/components/video-fullscreen-icon.png"); background-size: cover; > * { display: none; } } .vjs-icon-placeholder:before { font-size: 38px; line-height: 60px; } } &.vjs-fullscreen .vjs-fullscreen-control { background-position: bottom left; } &.vjs-fullscreen .vjs-yoho-back { width: 40px; height: 42px; background: url("~statics/image/components/video-back-icon.png"); background-size: contain; background-repeat: no-repeat; position: absolute; top: 20px; left: 32px; } } } </style>