diff --git a/src/components/DPlayerVideo.vue b/src/components/DPlayerVideo.vue index 5b2fbe2..8be95c0 100644 --- a/src/components/DPlayerVideo.vue +++ b/src/components/DPlayerVideo.vue @@ -143,7 +143,7 @@ const initDPlayer = async (url: string) => { await loadHLSScript() } - // DPlayer配置 - 先使用简单配置确保能播放 + // DPlayer配置 const options: any = { container: container, autoplay: props.autoplay, @@ -154,8 +154,24 @@ const initDPlayer = async (url: string) => { hotkey: true, preload: 'auto', volume: 0.8, - mutex: true, - video: { + mutex: true + } + + // 如果有多个清晰度选项,配置quality + if (props.qualities && props.qualities.length > 1) { + console.log('🎬 配置多清晰度:', props.qualities) + options.video = { + quality: props.qualities.map(q => ({ + name: q.label, + url: q.url, + type: isHLS ? 'hls' : 'normal' + })), + defaultQuality: props.qualities.findIndex(q => q.value === props.currentQuality) || 0, + pic: props.poster || '' + } + } else { + // 单一清晰度 + options.video = { url: url, pic: props.poster || '', type: 'normal' @@ -166,8 +182,17 @@ const initDPlayer = async (url: string) => { // HLS特殊处理 if (isHLS && (window as any).Hls && (window as any).Hls.isSupported()) { - console.log('🔧 使用HLS.js播放HLS流:', url) - options.video.type = 'hls' + console.log('🔧 使用HLS.js播放HLS流') + + // 如果是多清晰度,需要为每个清晰度设置type + if (options.video.quality) { + options.video.quality.forEach((q: any) => { + q.type = 'hls' + }) + } else { + options.video.type = 'hls' + } + options.video.customType = { hls: function(video: HTMLVideoElement, _player: DPlayer) { console.log('🎬 配置HLS.js实例') diff --git a/src/views/Resources.vue b/src/views/Resources.vue index 74fb000..f23368c 100644 --- a/src/views/Resources.vue +++ b/src/views/Resources.vue @@ -127,9 +127,19 @@
- +
@@ -146,6 +156,8 @@ const showVideoModal = ref(false) const currentVideo = ref(null) const currentVideoUrl = ref('') const videoPlayerRef = ref>() +const currentVideoQualities = ref>([]) +const currentQuality = ref('720') // 视频源配置 const VIDEO_CONFIG = { @@ -318,21 +330,63 @@ const parseVideoUrls = (fileUrl: string): string[] => { return fileUrl.split(',').map(url => url.trim()).filter(url => url) } -// 获取最佳视频URL -const getBestVideoUrl = (fileUrl: string): string => { - console.log('🔍 解析视频URL:', fileUrl) +// 从URL中提取清晰度标签 +const extractQualityLabel = (url: string): string => { + if (url.includes('1080p')) return '1080P' + if (url.includes('720p')) return '720P' + if (url.includes('480p')) return '480P' + if (url.includes('360p')) return '360P' + return '标清' +} + +// 解析视频清晰度选项 +const parseVideoQualities = (fileUrl: string) => { const urls = parseVideoUrls(fileUrl) - console.log('🔍 解析后的URL数组:', urls) if (urls.length === 0) { - console.warn('⚠️ 没有有效的视频URL,使用本地视频作为备用') - return VIDEO_CONFIG.LOCAL + return { + qualities: [], + defaultQuality: '720', + defaultUrl: VIDEO_CONFIG.LOCAL + } } - // 优先选择720p,如果没有则选择第一个 - const preferredUrl = urls.find(url => url.includes('720p')) || urls[0] - console.log('✅ 选择的视频URL:', preferredUrl) - return preferredUrl + // 将URL转换为清晰度选项 + const qualities = urls.map(url => { + let qualityValue = '360' + if (url.includes('1080p')) qualityValue = '1080' + else if (url.includes('720p')) qualityValue = '720' + else if (url.includes('480p')) qualityValue = '480' + + return { + label: extractQualityLabel(url), + value: qualityValue, + url: url + } + }) + + // 按清晰度排序(从高到低) + const qualityOrder: Record = { '1080': 3, '720': 2, '480': 1, '360': 0 } + qualities.sort((a, b) => (qualityOrder[b.value] || 0) - (qualityOrder[a.value] || 0)) + + // 默认选择720,如果没有则选择最高清晰度 + const defaultQuality = qualities.find(q => q.value === '720')?.value || qualities[0]?.value || '720' + const defaultUrl = qualities.find(q => q.value === defaultQuality)?.url || urls[0] + + console.log('🎬 解析的清晰度选项:', qualities) + console.log('🎯 默认清晰度:', defaultQuality, '默认URL:', defaultUrl) + + return { + qualities, + defaultQuality, + defaultUrl + } +} + +// 获取最佳视频URL(保留用于兼容) +const getBestVideoUrl = (fileUrl: string): string => { + const { defaultUrl } = parseVideoQualities(fileUrl) + return defaultUrl } // 视频播放相关方法 @@ -354,20 +408,20 @@ const handleVideoClick = async (video: FeaturedResource) => { currentVideo.value = video - // 获取最佳视频URL - const videoUrl = getBestVideoUrl(video.fileUrl) - currentVideoUrl.value = videoUrl + // 解析视频清晰度选项 + const { qualities, defaultQuality, defaultUrl } = parseVideoQualities(video.fileUrl) + currentVideoQualities.value = qualities + currentQuality.value = defaultQuality + currentVideoUrl.value = defaultUrl - console.log('🎯 最终使用的视频URL:', currentVideoUrl.value) + console.log('🎯 清晰度选项:', qualities) + console.log('🎯 默认清晰度:', defaultQuality) + console.log('🎯 默认URL:', defaultUrl) showVideoModal.value = true - // 等待弹窗显示后初始化播放器 + // 等待弹窗显示后,播放器会自动通过 watch 初始化 await nextTick() - if (videoPlayerRef.value) { - console.log('🔧 初始化播放器,URL:', currentVideoUrl.value) - await videoPlayerRef.value.initializePlayer(currentVideoUrl.value) - } } // 处理旧格式视频数据的点击事件 @@ -400,10 +454,18 @@ const closeVideoModal = () => { showVideoModal.value = false currentVideo.value = null currentVideoUrl.value = '' + currentVideoQualities.value = [] + currentQuality.value = '720' // 销毁播放器实例 if (videoPlayerRef.value) { - videoPlayerRef.value.destroy() + try { + if (typeof videoPlayerRef.value.destroy === 'function') { + videoPlayerRef.value.destroy() + } + } catch (e) { + console.warn('销毁播放器失败:', e) + } } }