Skip to content

Commit 38e7592

Browse files
authored
Merge pull request #7 from khzhg/main
直播支持组播流,修复正则表达
2 parents 57c7d49 + c5c52fe commit 38e7592

File tree

3 files changed

+41
-10
lines changed

3 files changed

+41
-10
lines changed

dashboard/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"flv.js": "^1.6.2",
2525
"hls.js": "^1.6.13",
2626
"json-server": "^0.17.4",
27+
"mpegts.js": "^1.8.0",
2728
"pinia": "^2.2.6",
2829
"shaka-player": "^4.16.3",
2930
"v-viewer": "^3.0.22",

dashboard/src/api/services/live.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,12 @@ class LiveService {
126126

127127
for (let i = 0; i < lines.length; i++) {
128128
const line = lines[i]
129-
129+
// 跳过空行
130+
if (!line) continue;
131+
130132
if (line.startsWith('#EXTINF:')) {
131133
// 解析频道信息 - 修复正则表达式来正确处理属性和频道名称
132-
const match = line.match(/#EXTINF:(-?\d+),(.*)$/)
134+
const match = line.match(/^#EXTINF:([-\.\d]+)\s*(.*)$/);
133135
if (match) {
134136
const duration = match[1]
135137
const fullStr = match[2].trim()
@@ -483,4 +485,4 @@ class LiveService {
483485
// 创建单例实例
484486
const liveService = new LiveService()
485487

486-
export default liveService
488+
export default liveService

dashboard/src/views/Live.vue

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,8 @@
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'
224225
import { useRouter } from 'vue-router'
225226
import { Message } from '@arco-design/web-vue'
226227
import {
@@ -236,6 +237,7 @@ import liveService from '@/api/services/live.js'
236237
const router = useRouter()
237238
238239
// 响应式数据
240+
let mpegtsPlayer = null
239241
const loading = ref(false)
240242
const error = ref('')
241243
const liveData = ref(null)
@@ -332,7 +334,6 @@ const selectGroup = (groupName) => {
332334
const 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+
})
353383
const getCurrentChannelUrl = () => {
354384
if (!selectedChannel.value) return ''
355385
@@ -365,20 +395,17 @@ const getCurrentChannelUrl = () => {
365395
const 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

Comments
 (0)