吉安感知网项目-前端
罗广辉
6 days ago d89b40229d445828b84ae456cfa2430d6b3eaef4
feat: 分享页支持m3u8视频播放
1 files modified
94 ■■■■■ changed files
applications/mobile-web-view/src/appPages/work/workDetail/index.vue 94 ●●●●● patch | view | raw | blame | history
applications/mobile-web-view/src/appPages/work/workDetail/index.vue
@@ -2,8 +2,16 @@
    <div class="workDetailContainer">
        <div class="detailTop">
            <div class="image-container">
                <van-swipe :autoplay="3000" indicator-color="#4C85FF">
                <van-swipe-item v-for="(img, index) in [imgSrc]" :key="index">
                <video
                    v-if="isVideoAttachment && mediaSrc"
                    ref="videoRef"
                    class="video-js vjs-default-skin vjs-big-play-centered detailVideo"
                    controls
                    preload="auto"
                    playsinline
                ></video>
                <van-swipe v-else :autoplay="3000" indicator-color="#4C85FF">
                    <van-swipe-item v-for="(img, index) in [mediaSrc]" :key="index">
                    <van-image class="detailImage" :src="img" fit="cover" width="100%" height="235px"
                        @click="openPreview(index)" preview-visible="false" />
                </van-swipe-item>
@@ -60,11 +68,17 @@
import { getShowImg, getSmallImg } from '@/utils/util'
import { useRoute,useRouter } from 'vue-router'
import { getAiImg } from '@ztzf/utils'
import videojs from 'video.js'
import 'video.js/dist/video-js.css'
const keyword = ref('')
const route = useRoute()
const router = useRouter()
const workDetailData = ref({})
const videoRef = ref(null)
let player = null
const isVideoAttachment = computed(() => Number(workDetailData.value.attachmentType) === 3)
// 预览图片
const getImageList = computed(() => {
@@ -77,8 +91,9 @@
    return imageArr
})
const openPreview = () => {
    if (isVideoAttachment.value || !mediaSrc.value) return
    showImagePreview({
        images: [imgSrc.value],
        images: [mediaSrc.value],
        startPosition: 0,
    })
}
@@ -100,7 +115,63 @@
    )
}
const imgSrc = ref('')
function getVideoType(url) {
    const path = (url || '').split('?')[0].toLowerCase()
    if (path.endsWith('.m3u8')) return 'application/x-mpegURL'
    if (path.endsWith('.mp4')) return 'video/mp4'
    if (path.endsWith('.webm')) return 'video/webm'
    if (path.endsWith('.ogg') || path.endsWith('.ogv')) return 'video/ogg'
    if (path.endsWith('.mov')) return 'video/quicktime'
    return ''
}
function getVideoSource() {
    const type = getVideoType(mediaSrc.value)
    return {
        src: mediaSrc.value,
        ...(type ? { type } : {}),
    }
}
function destroyPlayer() {
    if (!player) return
    player.dispose()
    player = null
}
async function initPlayer() {
    if (!isVideoAttachment.value || !mediaSrc.value) return
    await nextTick()
    if (!videoRef.value) return
    if (player) {
        player.src(getVideoSource())
        player.load()
        return
    }
    player = videojs(videoRef.value, {
        controls: true,
        preload: 'auto',
        autoplay: false,
        fluid: false,
        sources: [getVideoSource()],
    })
    player.on('error', () => {
        console.error('视频播放失败:', player?.error(), mediaSrc.value)
    })
}
const mediaSrc = ref('')
watch([isVideoAttachment, mediaSrc], () => {
    if (isVideoAttachment.value) {
        initPlayer()
    } else {
        destroyPlayer()
    }
})
onMounted(async () => {
    keyword.value = JSON.parse(route.query.workDetailData)
    try {
@@ -110,13 +181,15 @@
        // http://220.177.172.27:8100 改为 https://wrj.shuixiongit.com/ja-proxy
        eventImageUrl = replaceWithProxy(eventImageUrl)
        if (eventImageUrl){
            imgSrc.value = geojson ? await getAiImg(eventImageUrl,geojson) : eventImageUrl
            mediaSrc.value = !isVideoAttachment.value && geojson ? await getAiImg(eventImageUrl,geojson) : eventImageUrl
        }
    } catch (error) {
        showToast('分享链接失效')
    }
})
onBeforeUnmount(destroyPlayer)
</script>
<style lang="scss" scoped>
.workDetailContainer {
@@ -124,12 +197,23 @@
        .image-container {
            position: relative;
            width: 100%;
            height: 235px;
            .detailImage {
                width: 100%;
                height: 100%;
                display: block;
                object-fit: cover;
            }
            .detailVideo {
                width: 100%;
                height: 235px;
            }
            :deep(.video-js .vjs-tech) {
                width: 100%;
                height: 100%;
            }
        }
    }