123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313 |
- <template>
- <div>
- <video-player
- class="video-player vjs-custom-skin"
- ref="videoPlayer"
- :playsinline="true"
- @pause="onPlayerPause($event)"
- @play="onPlayerStart($event)"
- @timeupdate="onPlayerTimeupdate($event)"
- @ready="playerReadied"
- @ended="onPlayerEnded($event)"
- :globalOptions="{controls:true}"
- :options="options">
- </video-player>
- <div class="dialog-footer">
- <el-row class="media-footer">
- <el-col :span="8" class="media-time">
- <span>{{curTimes|useTime}}</span>
- <strong>/</strong>
- <span>{{media.duration|useTime}}</span>
- </el-col>
- <el-col :span="8" class="media-center">
- <el-button class="bicon" v-if="!onPlay" type="primary" @click="doPlay" icon="el-icon-video-play" circle></el-button>
- <el-button class="bicon" v-else type="warning" @click="doPause" icon="el-icon-video-pause" circle></el-button>
- </el-col>
- <el-col :span="8" class="media-select">
- <el-button class="bicon" type="danger" icon="el-icon-close" @click="onClose" style="float: right;" >
- </el-button>
- <div style="margin-top:0px;float: right;">
- <el-select placeholder="流畅" v-model="selectMediaType" class="media-el-select" @change="(val)=>{$emit('changeMedia', val)}">
- <el-option label="流畅" value="ld" ></el-option>
- <el-option label="标清" value="hls"></el-option>
- </el-select>
- </div>
- </el-col>
- </el-row>
- </div>
- </div>
- </template>
- <script>
- import {httpServer} from "@/components/httpServer/httpServer.js";
- import md5 from 'js-md5';
- import {videoPlayer } from 'vue-video-player';
- import 'video.js/dist/video-js.css'
- import { MessageBox } from "element-ui";
- export default {
- name: "Index",
- data() {
- return {
- timer: false,
- tickNum: 0,
- prevTime:0,
- isReady:false,
- selectMediaType:'hls',
- curTimes:0,
- onPlay: false
- }
- },
- components: {
- videoPlayer
- },
- watch:{
- mediaType( ){
- console.log("change mediaType", this.mediaType)
- this.selectMediaType = this.mediaType;
- if( !this.mediaType ) return;
- },
- dialog( showDilog ){
- if( !showDilog){
- this.doPause()
- this.isReady = false
- }
- }
- },
- props: {
- mediaType:{
- type: String,
- default: ''
- },
- media:{
- type: Object,
- default: ()=>{
- return {id: '', percent:0}
- }
- },
- dialog:{
- type: Boolean,
- default: true
- },
- options: {
- type: Object,
- default: () => {
- return {}
- }
- }
- },
- filters:{
- useTime(val){
- let timestr = ""
- let hour = parseInt(val/3600);
- let min = parseInt(val/60 % 60);
- let sec = parseInt(val%60);
- if( hour <10) hour = "0"+hour;
- if( min <10) min = "0"+min;
- if( sec <10) sec = "0"+sec;
- return hour+":"+min+":"+sec
- }
- },
- beforeDestroy() {
- if (this.timer) {
- clearInterval(this.timer); //关闭
- }
- },
- computed: {
- player() {
- return this.$refs.videoPlayer.player
- }
- },
- created() {
- this.timer = setInterval(this.tick, 5 * 1000);
- // this.startMonitor();
- },
- methods: {
- playerReadied(player) {
- // console.log("playerReadied", this.media.position);
- let that = this;
- if( this.media.position){
- this.setposition( this.media.position );
- }else{
- setTimeout( ()=>{
- that.doPlay()
- }, 1000 )
- }
- this.isReady = true
- },
- onPlayerTimeupdate( player ){
- let myPlayer = this.$refs.videoPlayer.player;
- let curTimes = player.cache_.currentTime;
- this.curTimes = curTimes||0
- if( this.media.isFinish ){
- return;
- }
- if( curTimes>30 && curTimes > this.media.position+15 && !this.media.isFinish){
- console.log("return", curTimes, this.media.position )
- player.currentTime( this.media.position );
- return;
- }
- },
- setposition( position ) {
- if( position > this.media.duration) position = this.media.duration;
- let player = this.$refs.videoPlayer.player;
- player.currentTime( position );
- if( this.media.isFinish) return;
- if( this.media.position >= this.media.duration-30 && !this.media.isFinish){
- this.tick( true )
- }
- this.onPlay = true
- },
- onPlayerPause(event) {
- this.onPlay = false
- },
- onPlayerEnded( event ){
- this.tick( true )
- },
- onClose(){
- this.doPause()
- this.$emit("close")
- },
- doPause( ){
- let myPlayer = this.$refs.videoPlayer.player;
- myPlayer && myPlayer.pause()
- console.log("doPause", myPlayer)
- this.onPlay = false
- },
- doPlay(){
- this.onPlay = true
- console.log("doPlay")
- if( !this.$refs.videoPlayer || !this.$refs.videoPlayer.player ) return;
- if( !this.dialog ) return this.doPause();
- let myPlayer = this.$refs.videoPlayer.player;
- myPlayer && myPlayer.play()
- this.tickNum = 0
- },
- onPlayerStart() {
- this.onPlay = true
- },
- startMonitor() {
- let that = this
- window.onblur = function() {
- that.doPause()
- }
- window.onfocus = function () {
- that.doPlay()
- }
- },
- tickWait(){
- this.doPause()
- let that = this
- MessageBox({
- title: "连续学习超15分钟",
- message: "是否继续学习",
- showCancelButton: true,
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- beforeClose: (action, instance, done) => {
- if (action === "confirm") {
- that.doPlay();
- done();
- } else{
- done();
- }
- }
- })
- },
- tick( force = false) {
- let media = this.media;
- this.tickNum ++
- // 已经完成
- if( this.media.isFinish ) return;
- // 主动暂停
- let myPlayer = this.$refs.videoPlayer.player;
- let curTimes = parseInt(myPlayer.currentTime());
- // 后退无心跳
- if( this.media.position > curTimes && !force ) return;
- if( curTimes< 4) return;
- let isFinish = force?1:0
- if( curTimes >= media.duration ) isFinish = 1;
- // 拉到后面
- if( !isFinish ){
- if ( !this.onPlay ) return;
- if( curTimes > this.prevTime){
- this.prevTime = curTimes
- return;
- }
- }
- // 强制完成
- let param ={id: media.id, position:curTimes ,isFinish};
- httpServer("course.tick", param, true).then( res => {
- if (res.code == 200) {
- let {skip, position, pause} = res.data
- if( pause ) {
- this.doPause();
- this.$emit("close")
- return
- }
- if( !skip ) this.setposition( position );
- Object.assign(param, res.data )
- this.$emit("update", param )
- }
- }).catch( res =>{
- console.log( "tick", res)
- })
- }
- }
- }
- </script>
- <style>
- .video-js{
- .vjs-control-bar{
- .vjs-icon-custombutton {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal;
- }
- .vjs-icon-custombutton:before {
- content: "\f108";
- font-size: 1.8em;
- line-height: 1.67;
- }
- }
- }
- .p-process{
- width: 100%;
- margin:20px auto;
- height: 30px;
- }
- .media-footer{
- padding: 0px 30px;
- text-align: left;
- line-height: 40px !important;
- bottom: -10px;
- }
- .media-center{
- text-align: center;
- padding: 0px;
- }
- .media-time{
- font-size: 21px;
- vertical-align: center;
- }
- .media-select{
- white-space:nowrap;
- text-align: right;
- line-height: 40px !important;
- float: right;
- margin: 0px !important;
- }
- .bicon{
- font-size: 28px !important;
- padding: 4px !important;
- }
- .media-el-select {
- font-size: 28px !important;
- width: 80px;
- padding: -4px auto !important;
- }
- </style>
|