import flvJs from "flv.js"; // mpegts.js import { getCameraStream, getNearCamera, } from "@screen/pages/Home/components/RoadAndEvents/utils/httpList.js"; /** * * @param {HTMLElement} container 容器 * @param {{camId?: string; url?: string}?} options {camId: 相机ID; url: 直播地址} * @returns */ export async function openVideoStream(container, { camId, url } = {}) { if (camId) { const { code, data } = await getCameraStream(camId).catch(() => ({})); if (code != 200) return; url = data.liveUrl; } if (!url) return; // console.log(flvJs.getFeatureList().mseLivePlayback); const player = flvJs.createPlayer({ type: "flv", url: url, isLive: true, hasVideo: true, hasAudio: true, }); player.attachMediaElement(container); player.load(); player.play(); player.on(flvJs.Events.ERROR, (e) => {}); return player; } export class HttpLivePlayer { /** * @type { flvJs.Player } */ player; /** * @type { HTMLVideoElement } */ container; url; // 解码 帧 lastDecodedFrames; constructor(container, options) { this.container = container; this.getUrl(options).then(() => { this.initLiveVideo(); }); } async getUrl({ camId, url, pileNum } = {}) { this.url = url; if (pileNum) { const { code, data } = await getNearCamera(pileNum).catch(() => ({})); if (code != 200 || !data?.length) return; camId = data[0].camId; } if (camId) { const { code, data } = await getCameraStream(camId).catch(() => ({})); if (code != 200) return; url = data.liveUrl; } if (!url) return Promise.reject("获取 url 失败!"); this.url = url; } destroy() { if (!this.player) return; this.player.pause(); this.player.unload(); this.player.detachMediaElement(); this.player.destroy(); this.player = null; } initLiveVideo() { this.destroy(); this.lastDecodedFrames = null; console.log(this.url); if (!this.url) return; this.player = flvJs.createPlayer( { type: "flv", url: this.url, isLive: true, hasVideo: true, hasAudio: false, }, { autoCleanupSourceBuffer: true, // enableWorker: false, //不启用分离线程 // enableStashBuffer: true, //关闭IO隐藏缓冲区 isLive: true, lazyLoad: false, } ); this.player.attachMediaElement(this.container); this.player.load(); this.player.play(); this.player.on(flvJs.Events.ERROR, (errorType, errorDetail, errorInfo) => { console.log("errorType", errorType); console.log("errorDetail", errorDetail); console.log("errorInfo", errorInfo); // 视频出错后销毁重建 this.destroy(); this.initLiveVideo(); }); // 视频断流 this.player.on(flvJs.Events.STATISTICS_INFO, (res) => { if (this.lastDecodedFrames != res.decodedFrames) { this.lastDecodedFrames = res.decodedFrames; } else { this.lastDecodedFrames = 0; this.destroy(); this.initLiveVideo(); } }); } }