media.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. <template>
  2. <div>
  3. <video-player
  4. class="video-player vjs-custom-skin"
  5. ref="videoPlayer"
  6. :playsinline="true"
  7. @pause="onPlayerPause($event)"
  8. @play="onPlayerStart($event)"
  9. @timeupdate="onPlayerTimeupdate($event)"
  10. @ready="playerReadied"
  11. @ended="onPlayerEnded($event)"
  12. :globalOptions="{controls:true}"
  13. :options="options">
  14. </video-player>
  15. </div>
  16. </template>
  17. <script>
  18. import {httpServer} from "@/components/httpServer/httpServer.js";
  19. import md5 from 'js-md5';
  20. import {videoPlayer } from 'vue-video-player';
  21. import 'video.js/dist/video-js.css'
  22. import { MessageBox } from "element-ui";
  23. export default {
  24. name: "Index",
  25. data() {
  26. return {
  27. timer: false,
  28. tickNum: 0,
  29. prevTime:0,
  30. isReady:false,
  31. onPlay: false
  32. }
  33. },
  34. components: {
  35. videoPlayer
  36. },
  37. watch:{
  38. dialog( showDilog ){
  39. if( !showDilog){
  40. this.doPause()
  41. this.isReady = false
  42. }
  43. }
  44. },
  45. props: {
  46. media:{
  47. type: Object,
  48. default: ()=>{
  49. return {id: '', percent:0}
  50. }
  51. },
  52. dialog:{
  53. type: Boolean,
  54. default: true
  55. },
  56. options: {
  57. type: Object,
  58. default: () => {
  59. return {}
  60. }
  61. }
  62. },
  63. beforeDestroy() {
  64. if (this.timer) {
  65. clearInterval(this.timer); //关闭
  66. }
  67. },
  68. computed: {
  69. player() {
  70. return this.$refs.videoPlayer.player
  71. }
  72. },
  73. created() {
  74. this.timer = setInterval(this.tick, 5 * 1000);
  75. // this.startMonitor();
  76. },
  77. methods: {
  78. playerReadied(player) {
  79. let that = this;
  80. if( !this.isReady && this.media.position){
  81. this.setposition( this.media.position );
  82. }else if (!this.media.position ){
  83. setTimeout( ()=>{
  84. that.doPlay()
  85. }, 1000 )
  86. }
  87. this.isReady = true
  88. },
  89. onPlayerTimeupdate( player ){
  90. let myPlayer = this.$refs.videoPlayer.player;
  91. let curTimes = player.cache_.currentTime;
  92. if( curTimes>30 && curTimes > this.media.position+15 && !this.media.isFinish){
  93. console.log("return", curTimes, this.media.position )
  94. player.currentTime( this.media.position );
  95. return;
  96. }
  97. },
  98. setposition( position ) {
  99. if( position > this.media.duration) position = this.media.duration;
  100. if( !this.media.isFinish ){
  101. let player = this.$refs.videoPlayer.player;
  102. player.currentTime( position );
  103. }
  104. let player = this.$refs.videoPlayer.player;
  105. if( this.media.position >= this.media.duration-30 && !this.media.isFinish){
  106. this.tick( true )
  107. }
  108. this.onPlay = true
  109. },
  110. onPlayerPause(event) {
  111. this.onPlay = false
  112. },
  113. onPlayerEnded( event ){
  114. this.tick( true )
  115. },
  116. doPause( ){
  117. let myPlayer = this.$refs.videoPlayer.player;
  118. myPlayer && myPlayer.pause()
  119. console.log("doPause", myPlayer)
  120. this.onPlay = false
  121. },
  122. doPlay(){
  123. if( !this.$refs.videoPlayer || !this.$refs.videoPlayer.player ) return;
  124. if( !this.dialog ) return this.doPause();
  125. let myPlayer = this.$refs.videoPlayer.player;
  126. myPlayer && myPlayer.play()
  127. this.tickNum = 0
  128. this.onPlay = true
  129. },
  130. onPlayerStart() {
  131. this.onPlay = true
  132. },
  133. startMonitor() {
  134. let that = this
  135. window.onblur = function() {
  136. that.doPause()
  137. }
  138. window.onfocus = function () {
  139. that.doPlay()
  140. }
  141. },
  142. tickWait(){
  143. this.doPause()
  144. let that = this
  145. MessageBox({
  146. title: "连续学习超15分钟",
  147. message: "是否继续学习",
  148. showCancelButton: true,
  149. confirmButtonText: "确定",
  150. cancelButtonText: "取消",
  151. beforeClose: (action, instance, done) => {
  152. if (action === "confirm") {
  153. that.doPlay();
  154. done();
  155. } else{
  156. done();
  157. }
  158. }
  159. })
  160. },
  161. tick( force = false) {
  162. let media = this.media;
  163. this.tickNum ++
  164. // 已经完成
  165. if( this.media.isFinish ) return;
  166. // 主动暂停
  167. let myPlayer = this.$refs.videoPlayer.player;
  168. let curTimes = parseInt(myPlayer.currentTime());
  169. // 后退无心跳
  170. if( this.media.position > curTimes && !force ) return;
  171. if( curTimes< 4) return;
  172. let isFinish = force?1:0
  173. if( curTimes >= media.duration ) isFinish = 1;
  174. // 拉到后面
  175. if( !isFinish ){
  176. if ( !this.onPlay ) return;
  177. // if( curTimes < media.position ) return this.setposition(media.position )
  178. }
  179. // 强制完成
  180. let param ={id: media.id, position:curTimes ,isFinish};
  181. httpServer("course.tick", param, true).then( res => {
  182. if (res.code == 200) {
  183. let {skip, position, pause} = res.data
  184. if( pause ) {
  185. this.doPause();
  186. this.$emit("close")
  187. return
  188. }
  189. if( !skip ) this.setposition( position );
  190. Object.assign(param, res.data )
  191. this.$emit("update", param )
  192. }
  193. }).catch( res =>{
  194. console.log( "tick", res)
  195. })
  196. }
  197. }
  198. }
  199. </script>
  200. <style>
  201. .video-js{
  202. .vjs-control-bar{
  203. .vjs-icon-custombutton {
  204. font-family: VideoJS;
  205. font-weight: normal;
  206. font-style: normal;
  207. }
  208. .vjs-icon-custombutton:before {
  209. content: "\f108";
  210. font-size: 1.8em;
  211. line-height: 1.67;
  212. }
  213. }
  214. }
  215. .p-process{
  216. width: 100%;
  217. margin:20px auto;
  218. height: 30px;
  219. }
  220. </style>