|
@@ -5,7 +5,14 @@
|
|
|
element-loading-text="加载中"
|
|
|
element-loading-background="rgba(0, 0, 0, 0.8)"
|
|
|
>
|
|
|
- <!-- <video :id="videoId" muted></video> -->
|
|
|
+ <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>
|
|
@@ -37,10 +44,9 @@
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import TCPlayer from "tcplayer.js";
|
|
|
-// doc: https://cloud.tencent.com/document/product/881/30820
|
|
|
+import flvjs from "flv.js";
|
|
|
+// doc: https://github.com/bilibili/flv.js/blob/42343088f22619cf014a057b3878fe3d320016a6/docs/api.md
|
|
|
import timeMixin from "../../../mixins/timeMixin";
|
|
|
-import { randomCode } from "@/utils/utils";
|
|
|
|
|
|
export default {
|
|
|
name: "flv-media",
|
|
@@ -60,7 +66,8 @@ export default {
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
- videoId: null,
|
|
|
+ videoId: `video${this._uid}`,
|
|
|
+ videoElement: null,
|
|
|
flvPlayer: null,
|
|
|
muted: true,
|
|
|
paused: false,
|
|
@@ -88,61 +95,48 @@ export default {
|
|
|
methods: {
|
|
|
initVideo() {
|
|
|
if (!this.liveUrl) return;
|
|
|
- // this.loading = true;
|
|
|
- this.createNewVideo();
|
|
|
- this.flvPlayer = TCPlayer(this.videoId, {
|
|
|
- controls: false,
|
|
|
- autoplay: true,
|
|
|
- muted: false,
|
|
|
- bigPlayButton: false,
|
|
|
- reportable: false,
|
|
|
- });
|
|
|
- this.flvPlayer.src(this.liveUrl);
|
|
|
- this.flvPlayer.ready(() => {
|
|
|
- // this.loading = false;
|
|
|
- this.flvPlayer.volume(0);
|
|
|
- });
|
|
|
- this.flvPlayer.on("error", this.playError);
|
|
|
- this.flvPlayer.on("ended", this.destroyPlayer);
|
|
|
- this.flvPlayer.on("pause", this.playerPaused);
|
|
|
- this.flvPlayer.on("play", this.playerPlaying);
|
|
|
- },
|
|
|
- createNewVideo() {
|
|
|
- let videoDom = document.createElement("video");
|
|
|
- this.videoId = `vedio-${randomCode()}`;
|
|
|
- videoDom.id = this.videoId;
|
|
|
- this.$el.appendChild(videoDom);
|
|
|
- },
|
|
|
- playError(res) {
|
|
|
- // console.log(res);
|
|
|
- switch (res.data.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(res.data.code + "其他问题,无法播放!");
|
|
|
- this.retryPlay();
|
|
|
- break;
|
|
|
+ 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.flvPlayer.paused
|
|
|
- ) {
|
|
|
+ if (this.lastDecodedFrames === res.decodedFrames && !this.paused) {
|
|
|
this.lastDecodedFrames = 0;
|
|
|
console.log("卡住了,准备重试!");
|
|
|
this.retryPlay();
|
|
@@ -150,6 +144,25 @@ 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("已尝试最大次数重新播放!");
|
|
@@ -158,7 +171,7 @@ export default {
|
|
|
message: "播放失败",
|
|
|
};
|
|
|
this.retryCount = 0;
|
|
|
- // this.loading = false;
|
|
|
+ this.loading = false;
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -167,44 +180,43 @@ 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.dispose();
|
|
|
+ this.flvPlayer.unload();
|
|
|
+ this.flvPlayer.detachMediaElement();
|
|
|
+ this.flvPlayer.destroy();
|
|
|
this.flvPlayer = null;
|
|
|
this.clearSetTs();
|
|
|
},
|
|
|
mutedPlayer(muted) {
|
|
|
if (!this.flvPlayer) return;
|
|
|
- const volume = muted ? 0 : 1;
|
|
|
- this.flvPlayer.volume(volume);
|
|
|
- this.muted = muted;
|
|
|
+ this.flvPlayer.muted = muted;
|
|
|
+ this.muted = this.flvPlayer.muted;
|
|
|
},
|
|
|
videoMuted() {
|
|
|
if (!this.flvPlayer) return;
|
|
|
- const volume = this.flvPlayer.volume();
|
|
|
- // console.log(volume);
|
|
|
+ const muted = this.flvPlayer.muted;
|
|
|
this.$emit("muted-change");
|
|
|
- const nvolume = volume === 1 ? 0 : 1;
|
|
|
- this.flvPlayer.volume(nvolume);
|
|
|
- this.muted = nvolume === 0;
|
|
|
+ this.flvPlayer.muted = !muted;
|
|
|
+ this.muted = this.flvPlayer.muted;
|
|
|
},
|
|
|
reloadVideo() {
|
|
|
this.result = {
|
|
|
error: false,
|
|
|
message: "",
|
|
|
};
|
|
|
- // this.loading = true;
|
|
|
+ this.loading = true;
|
|
|
this.$nextTick(() => {
|
|
|
this.destroyPlayer();
|
|
|
this.initVideo();
|
|
|
this.retryCount++;
|
|
|
});
|
|
|
},
|
|
|
- playOrPausePlayer() {
|
|
|
- if (!this.flvPlayer) return;
|
|
|
- this.paused ? this.flvPlayer.play() : this.flvPlayer.pause();
|
|
|
- },
|
|
|
playerPaused() {
|
|
|
this.paused = true;
|
|
|
console.log(this.paused);
|