220220</template >
221221
222222<script setup>
223- import { ref , reactive , computed , onMounted , watch , nextTick } from ' vue'
223+ import { ref , reactive , computed , onMounted , watch , nextTick , onUnmounted } from ' vue'
224+ import mpegts from ' mpegts.js'
224225import { useRouter } from ' vue-router'
225226import { Message } from ' @arco-design/web-vue'
226227import {
@@ -236,6 +237,7 @@ import liveService from '@/api/services/live.js'
236237const router = useRouter ()
237238
238239// 响应式数据
240+ let mpegtsPlayer = null
239241const loading = ref (false )
240242const error = ref (' ' )
241243const liveData = ref (null )
@@ -332,7 +334,6 @@ const selectGroup = (groupName) => {
332334const selectChannel = (channel ) => {
333335 selectedChannel .value = channel
334336 videoError .value = ' '
335-
336337 // 使用nextTick确保DOM更新后再设置线路ID
337338 nextTick (() => {
338339 if (channel && channel .routes && channel .routes .length > 0 ) {
@@ -341,15 +342,44 @@ const selectChannel = (channel) => {
341342 } else {
342343 currentRouteId .value = 1
343344 }
344-
345345 // 重置视频播放器
346346 if (videoPlayer .value ) {
347347 videoPlayer .value .load ()
348348 }
349+ setupMpegtsPlayer ()
349350 })
350351}
351352
352353// 获取当前频道的播放URL
354+ function setupMpegtsPlayer () {
355+ // 销毁旧播放器
356+ if (mpegtsPlayer) {
357+ mpegtsPlayer .destroy ()
358+ mpegtsPlayer = null
359+ }
360+ const url = getCurrentChannelUrl ()
361+ if (! url || ! videoPlayer .value ) return
362+ // 判断是否为 mpegts 流(简单判断 .ts 或 mpegts 协议)
363+ if (url .endsWith (' .ts' ) || url .includes (' mpegts' ) || url .includes (' udpxy' ) ||
364+ url .includes (' /udp/' ) || url .includes (' rtp://' ) || url .includes (' udp://' )) {
365+ if (mpegts .isSupported ()) {
366+ mpegtsPlayer = mpegts .createPlayer ({
367+ type: ' mpegts' ,
368+ url
369+ })
370+ mpegtsPlayer .attachMediaElement (videoPlayer .value )
371+ mpegtsPlayer .load ()
372+ mpegtsPlayer .play ()
373+ }
374+ }
375+ }
376+
377+ onUnmounted (() => {
378+ if (mpegtsPlayer) {
379+ mpegtsPlayer .destroy ()
380+ mpegtsPlayer = null
381+ }
382+ })
353383const getCurrentChannelUrl = () => {
354384 if (! selectedChannel .value ) return ' '
355385
@@ -365,20 +395,17 @@ const getCurrentChannelUrl = () => {
365395const switchRoute = (event ) => {
366396 const routeId = Number (event .target ? event .target .value : event )
367397 if (! selectedChannel .value || ! selectedChannel .value .routes ) return
368-
369398 const route = selectedChannel .value .routes .find (r => r .id === routeId)
370399 if (route) {
371400 currentRouteId .value = routeId
372401 videoError .value = ' '
373-
374- // 重新加载视频
375402 nextTick (() => {
376403 if (videoPlayer .value ) {
377404 videoPlayer .value .src = route .url
378405 videoPlayer .value .load ()
379406 }
407+ setupMpegtsPlayer ()
380408 })
381-
382409 Message .success (` 已切换到${ route .name } ` )
383410 }
384411}
@@ -442,6 +469,7 @@ const retryVideo = () => {
442469 if (videoPlayer .value ) {
443470 videoError .value = ' '
444471 videoPlayer .value .load ()
472+ setupMpegtsPlayer ()
445473 }
446474}
447475
0 commit comments