<script lang="ts" setup> import { onBeforeUnmount, onMounted, ref, watch } from 'vue' import flvjs from 'flv.js' // 定义 props const props = defineProps({ title: String, url: String, }) // 定义响应式数据 const videoElement = ref<HTMLVideoElement | null>(null) const flvPlayer = ref<flvjs.Player | null>(null) // 加载 flv 视频的方法 const flv_load = (url: string) => { if (flvjs.isSupported()) { if (videoElement.value) { flvPlayer.value = flvjs.createPlayer( { type: 'flv', // 媒体类型 url: url || '', // flv 格式媒体 URL isLive: true, // 数据源是否为直播流 hasAudio: false, // 数据源是否包含有音频 hasVideo: true, // 数据源是否包含有视频 enableStashBuffer: false, // 是否启用媒体源缓存功能,提高播放的流畅性 }, { enableWorker: false, // 是否启用分离的线程进行转换 enableStashBuffer: false, // 关闭 IO 隐藏缓冲区 autoCleanupSourceBuffer: true, // 自动清除缓存 }, ) flvPlayer.value.attachMediaElement(videoElement.value) // 将播放实例注册到节点 flvPlayer.value.load() // 加载数据流 flvPlayer.value.play() // 播放数据流 } } } // 销毁断流方法 const destoryVideo = () => { if (flvPlayer.value) { flvPlayer.value.pause() flvPlayer.value.unload() flvPlayer.value.detachMediaElement() flvPlayer.value.destroy() flvPlayer.value = null } } // 生命周期钩子 onMounted(() => { flv_load(props.url!) }) onBeforeUnmount(() => { destoryVideo() }) // 监听 url 变化 watch(() => props.url, (val) => { destoryVideo() flv_load(val!) }) </script> <template> <div class="player" style="position: relative;"> <!-- <p style="position: absolute !important;top: 10px;left: 20px;"> 通道{{ title }} </p> --> <video v-show="url" ref="videoElement" class="centeredVideo" controls autoplay muted /> </div> </template> <style scoped lang="scss"> .player { background-color: black; height: 100%; width: 100%; // border: 1px solid white; color: white; text-align: center; display: flex; align-items: center; } .centeredVideo { width: 100%; height: 98%; } </style>