Ver código fonte

播放器切换

zhangjie 2 anos atrás
pai
commit
beb80d019f

+ 52 - 69
src/features/invigilation/common/FlvMedia.vue

@@ -9,7 +9,6 @@
       ref="VideoMedia"
       :id="videoId"
       muted
-      @ended="destroyPlayer"
       @pause="playerPaused"
       @play="playerPlaying"
     ></video>
@@ -31,7 +30,7 @@
     >
       <i :class="['icon', !muted ? 'icon-audio-act' : 'icon-audio']"></i>
     </div>
-    <div
+    <!-- <div
       v-if="liveUrl && !result.error && !loading && flvPlayer"
       class="media-video-play"
       @click.stop="playOrPausePlayer"
@@ -39,13 +38,13 @@
       <i
         :class="[this.paused ? 'el-icon-video-play' : 'el-icon-video-pause']"
       ></i>
-    </div>
+    </div> -->
   </div>
 </template>
 
 <script>
-import flvjs from "flv.js";
-// doc: https://github.com/bilibili/flv.js/blob/42343088f22619cf014a057b3878fe3d320016a6/docs/api.md
+import TCPlayer from "tcplayer.js";
+// doc: https://cloud.tencent.com/document/product/881/30820
 import timeMixin from "../../../mixins/timeMixin";
 
 export default {
@@ -67,7 +66,6 @@ export default {
   data() {
     return {
       videoId: `video${this._uid}`,
-      videoElement: null,
       flvPlayer: null,
       muted: true,
       paused: false,
@@ -95,48 +93,51 @@ export default {
   methods: {
     initVideo() {
       if (!this.liveUrl) return;
-      if (!flvjs.isSupported()) {
-        this.result = {
-          error: true,
-          message: "不支持播放",
-        };
-        return;
-      }
       this.loading = true;
 
-      this.flvPlayer = flvjs.createPlayer(
-        {
-          type: "flv",
-          isLive: true,
-          hasAudio: true,
-          url: this.liveUrl,
-        },
-        {
-          fixAudioTimestampGap: false,
-          enableStashBuffer: true,
-          stashInitialSize: false,
-        }
-      );
-      this.flvPlayer.attachMediaElement(this.$refs.VideoMedia);
-      this.flvPlayer.load();
-      this.flvPlayer.play();
-      this.flvPlayer.on(flvjs.Events.ERROR, this.playError);
-      this.flvPlayer.on(flvjs.Events.METADATA_ARRIVED, () => {
+      this.flvPlayer = TCPlayer(this.videoId, {
+        controls: false,
+        autoplay: true,
+        muted: false,
+        bigPlayButton: false,
+      });
+      this.flvPlayer.src(this.liveUrl);
+      this.flvPlayer.ready(() => {
         this.loading = false;
-        console.log("视频信息获取成功");
-        this.retryCount = 0;
+        this.flvPlayer.volume(0);
       });
-      this.flvPlayer.on(
-        flvjs.Events.STATISTICS_INFO,
-        this.statisticsInfoEventHandle
-      );
+      this.flvPlayer.on("error", this.playError);
+      this.flvPlayer.on("ended", this.destroyPlayer);
+    },
+    playError(code) {
+      switch (code) {
+        case 1:
+          console.log("媒体问题,准备重试!");
+          this.retryPlay();
+          break;
+        case 2:
+          console.log("网络问题,准备重试!");
+          this.retryPlay();
+          break;
+        case 3:
+          console.log("解码问题,准备重试!");
+          this.retryPlay();
+          break;
+        default:
+          console.log(code + "未知问题,无法播放!");
+          this.retryPlay();
+          break;
+      }
     },
     statisticsInfoEventHandle(res) {
       if (this.lastDecodedFrames === 0) {
         this.lastDecodedFrames = res.decodedFrames;
         return;
       }
-      if (this.lastDecodedFrames === res.decodedFrames && !this.paused) {
+      if (
+        this.lastDecodedFrames === res.decodedFrames &&
+        !this.flvPlayer.paused
+      ) {
         this.lastDecodedFrames = 0;
         console.log("卡住了,准备重试!");
         this.retryPlay();
@@ -144,25 +145,6 @@ export default {
         this.lastDecodedFrames = res.decodedFrames;
       }
     },
-    playError(errorType) {
-      switch (errorType) {
-        case flvjs.ErrorTypes.NETWORK_ERROR:
-          console.log("网络问题,准备重试!");
-          this.retryPlay();
-          break;
-        case flvjs.ErrorTypes.MEDIA_ERROR:
-          console.log("媒体问题,准备重试!");
-          this.retryPlay();
-          break;
-        default:
-          console.log("未知问题,无法播放!");
-          this.result = {
-            error: true,
-            message: "播放失败",
-          };
-          break;
-      }
-    },
     retryPlay() {
       if (this.retryCount >= this.maxRetryCount) {
         console.log("已尝试最大次数重新播放!");
@@ -180,30 +162,27 @@ export default {
         console.log("已重新播放");
       }, 1000);
     },
-    playOrPausePlayer() {
-      if (!this.flvPlayer) return;
-      this.paused ? this.flvPlayer.play() : this.flvPlayer.pause();
-    },
     destroyPlayer() {
       if (!this.flvPlayer) return;
       this.flvPlayer.pause();
-      this.flvPlayer.unload();
-      this.flvPlayer.detachMediaElement();
-      this.flvPlayer.destroy();
+      this.flvPlayer.dispose();
       this.flvPlayer = null;
       this.clearSetTs();
     },
     mutedPlayer(muted) {
       if (!this.flvPlayer) return;
-      this.flvPlayer.muted = muted;
-      this.muted = this.flvPlayer.muted;
+      const volume = muted ? 0 : 1;
+      this.flvPlayer.volume(volume);
+      this.muted = muted;
     },
     videoMuted() {
       if (!this.flvPlayer) return;
-      const muted = this.flvPlayer.muted;
+      const volume = this.flvPlayer.volume();
+      console.log(volume);
       this.$emit("muted-change");
-      this.flvPlayer.muted = !muted;
-      this.muted = this.flvPlayer.muted;
+      const nvolume = volume === 1 ? 0 : 1;
+      this.flvPlayer.volume(nvolume);
+      this.muted = nvolume === 0;
     },
     reloadVideo() {
       this.result = {
@@ -217,6 +196,10 @@ export default {
         this.retryCount++;
       });
     },
+    playOrPausePlayer() {
+      if (!this.flvPlayer) return;
+      this.paused ? this.flvPlayer.play() : this.flvPlayer.pause();
+    },
     playerPaused() {
       this.paused = true;
       console.log(this.paused);

+ 233 - 0
src/features/invigilation/common/FlvMediaFlv.vue

@@ -0,0 +1,233 @@
+<template>
+  <div
+    class="flv-media"
+    v-loading="loading"
+    element-loading-text="加载中"
+    element-loading-background="rgba(0, 0, 0, 0.8)"
+  >
+    <video
+      ref="VideoMedia"
+      :id="videoId"
+      muted
+      @ended="destroyPlayer"
+      @pause="playerPaused"
+      @play="playerPlaying"
+    ></video>
+    <div v-if="result.error" class="media-error" @click.stop="() => {}">
+      <div class="media-error-content">
+        <span>{{ result.message }},</span>
+        <el-button type="text" @click="reloadVideo">点击刷新</el-button>
+      </div>
+    </div>
+    <div v-if="!liveUrl" class="media-error" @click.stop="() => {}">
+      <div class="media-error-content">
+        <span>无视频源</span>
+      </div>
+    </div>
+    <div
+      v-if="liveUrl && !result.error && !loading && !hideAudioIcon"
+      class="media-video-muted"
+      @click.stop="videoMuted"
+    >
+      <i :class="['icon', !muted ? 'icon-audio-act' : 'icon-audio']"></i>
+    </div>
+    <div
+      v-if="liveUrl && !result.error && !loading && flvPlayer"
+      class="media-video-play"
+      @click.stop="playOrPausePlayer"
+    >
+      <i
+        :class="[this.paused ? 'el-icon-video-play' : 'el-icon-video-pause']"
+      ></i>
+    </div>
+  </div>
+</template>
+
+<script>
+import flvjs from "flv.js";
+// doc: https://github.com/bilibili/flv.js/blob/42343088f22619cf014a057b3878fe3d320016a6/docs/api.md
+import timeMixin from "../../../mixins/timeMixin";
+
+export default {
+  name: "flv-media",
+  mixins: [timeMixin],
+  props: {
+    liveUrl: {
+      type: String,
+    },
+    maxRetryCount: {
+      type: Number,
+      default: 3,
+    },
+    hideAudioIcon: {
+      type: Boolean,
+      default: false,
+    },
+  },
+  data() {
+    return {
+      videoId: `video${this._uid}`,
+      videoElement: null,
+      flvPlayer: null,
+      muted: true,
+      paused: false,
+      retryCount: 0,
+      loading: false,
+      result: {
+        error: false,
+        message: "",
+      },
+      lastDecodedFrames: 0,
+    };
+  },
+  watch: {
+    muted: {
+      handler() {
+        this.$emit("media-muted-change", this.muted);
+      },
+      immediate: true,
+    },
+  },
+  mounted() {
+    this.initVideo();
+    this.retryCount++;
+  },
+  methods: {
+    initVideo() {
+      if (!this.liveUrl) return;
+      if (!flvjs.isSupported()) {
+        this.result = {
+          error: true,
+          message: "不支持播放",
+        };
+        return;
+      }
+      this.loading = true;
+
+      this.flvPlayer = flvjs.createPlayer(
+        {
+          type: "flv",
+          isLive: true,
+          hasAudio: true,
+          url: this.liveUrl,
+        },
+        {
+          fixAudioTimestampGap: false,
+          enableStashBuffer: true,
+          stashInitialSize: false,
+        }
+      );
+      this.flvPlayer.attachMediaElement(this.$refs.VideoMedia);
+      this.flvPlayer.load();
+      this.flvPlayer.play();
+      this.flvPlayer.on(flvjs.Events.ERROR, this.playError);
+      this.flvPlayer.on(flvjs.Events.METADATA_ARRIVED, () => {
+        this.loading = false;
+        console.log("视频信息获取成功");
+        this.retryCount = 0;
+      });
+      this.flvPlayer.on(
+        flvjs.Events.STATISTICS_INFO,
+        this.statisticsInfoEventHandle
+      );
+    },
+    statisticsInfoEventHandle(res) {
+      if (this.lastDecodedFrames === 0) {
+        this.lastDecodedFrames = res.decodedFrames;
+        return;
+      }
+      if (this.lastDecodedFrames === res.decodedFrames && !this.paused) {
+        this.lastDecodedFrames = 0;
+        console.log("卡住了,准备重试!");
+        this.retryPlay();
+      } else {
+        this.lastDecodedFrames = res.decodedFrames;
+      }
+    },
+    playError(errorType) {
+      switch (errorType) {
+        case flvjs.ErrorTypes.NETWORK_ERROR:
+          console.log("网络问题,准备重试!");
+          this.retryPlay();
+          break;
+        case flvjs.ErrorTypes.MEDIA_ERROR:
+          console.log("媒体问题,准备重试!");
+          this.retryPlay();
+          break;
+        default:
+          console.log("未知问题,无法播放!");
+          this.result = {
+            error: true,
+            message: "播放失败",
+          };
+          break;
+      }
+    },
+    retryPlay() {
+      if (this.retryCount >= this.maxRetryCount) {
+        console.log("已尝试最大次数重新播放!");
+        this.result = {
+          error: true,
+          message: "播放失败",
+        };
+        this.retryCount = 0;
+        this.loading = false;
+        return;
+      }
+
+      this.addSetTime(() => {
+        this.reloadVideo();
+        console.log("已重新播放");
+      }, 1000);
+    },
+    playOrPausePlayer() {
+      if (!this.flvPlayer) return;
+      this.paused ? this.flvPlayer.play() : this.flvPlayer.pause();
+    },
+    destroyPlayer() {
+      if (!this.flvPlayer) return;
+      this.flvPlayer.pause();
+      this.flvPlayer.unload();
+      this.flvPlayer.detachMediaElement();
+      this.flvPlayer.destroy();
+      this.flvPlayer = null;
+      this.clearSetTs();
+    },
+    mutedPlayer(muted) {
+      if (!this.flvPlayer) return;
+      this.flvPlayer.muted = muted;
+      this.muted = this.flvPlayer.muted;
+    },
+    videoMuted() {
+      if (!this.flvPlayer) return;
+      const muted = this.flvPlayer.muted;
+      this.$emit("muted-change");
+      this.flvPlayer.muted = !muted;
+      this.muted = this.flvPlayer.muted;
+    },
+    reloadVideo() {
+      this.result = {
+        error: false,
+        message: "",
+      };
+      this.loading = true;
+      this.$nextTick(() => {
+        this.destroyPlayer();
+        this.initVideo();
+        this.retryCount++;
+      });
+    },
+    playerPaused() {
+      this.paused = true;
+      console.log(this.paused);
+    },
+    playerPlaying() {
+      this.paused = false;
+      console.log(this.paused);
+    },
+  },
+  beforeDestroy() {
+    this.destroyPlayer();
+  },
+};
+</script>

+ 12 - 10
src/features/invigilation/common/FlvMedia2.vue → src/features/invigilation/common/FlvMediaTc.vue

@@ -30,7 +30,7 @@
     >
       <i :class="['icon', !muted ? 'icon-audio-act' : 'icon-audio']"></i>
     </div>
-    <div
+    <!-- <div
       v-if="liveUrl && !result.error && !loading && flvPlayer"
       class="media-video-play"
       @click.stop="playOrPausePlayer"
@@ -38,7 +38,7 @@
       <i
         :class="[this.paused ? 'el-icon-video-play' : 'el-icon-video-pause']"
       ></i>
-    </div>
+    </div> -->
   </div>
 </template>
 
@@ -98,13 +98,13 @@ export default {
       this.flvPlayer = TCPlayer(this.videoId, {
         controls: false,
         autoplay: true,
-        muted: true,
+        muted: false,
         bigPlayButton: false,
       });
       this.flvPlayer.src(this.liveUrl);
       this.flvPlayer.ready(() => {
         this.loading = false;
-        console.log(this.flvPlayer.muted);
+        this.flvPlayer.volume(0);
       });
       this.flvPlayer.on("error", this.playError);
       this.flvPlayer.on("ended", this.destroyPlayer);
@@ -171,16 +171,18 @@ export default {
     },
     mutedPlayer(muted) {
       if (!this.flvPlayer) return;
-      this.flvPlayer.muted = muted;
-      this.muted = this.flvPlayer.muted;
+      const volume = muted ? 0 : 1;
+      this.flvPlayer.volume(volume);
+      this.muted = muted;
     },
     videoMuted() {
       if (!this.flvPlayer) return;
-      const muted = this.flvPlayer.volume();
-      console.log(muted);
+      const volume = this.flvPlayer.volume();
+      console.log(volume);
       this.$emit("muted-change");
-      this.flvPlayer.muted = !muted;
-      this.muted = this.flvPlayer.muted;
+      const nvolume = volume === 1 ? 0 : 1;
+      this.flvPlayer.volume(nvolume);
+      this.muted = nvolume === 0;
     },
     reloadVideo() {
       this.result = {

+ 1 - 1
src/main.js

@@ -26,7 +26,7 @@ import "./styles/icons.scss";
 import "./styles/base.scss";
 import "./styles/element-ui-custom.scss";
 // styles end
-// import "tcplayer.js/dist/tcplayer.min.css";
+import "tcplayer.js/dist/tcplayer.min.css";
 
 Vue.config.productionTip = false;