fix(视频播放器): 修复视频封面缺失时的背景显示问题
在视频封面缺失时,播放器区域显示为透明背景,导致视觉不一致。为 VideoPlayer 组件添加黑色背景,并在 StudyDetailPage 中动态设置封面容器的背景色:有封面时透明,无封面时黑色。同时优化 useVideoPlayer 配置逻辑,避免传递空的 poster 属性。
Showing
3 changed files
with
41 additions
and
34 deletions
| ... | @@ -196,6 +196,7 @@ defineExpose({ | ... | @@ -196,6 +196,7 @@ defineExpose({ |
| 196 | height: 100%; | 196 | height: 100%; |
| 197 | display: block; | 197 | display: block; |
| 198 | aspect-ratio: 16/9; | 198 | aspect-ratio: 16/9; |
| 199 | + background-color: #000; | ||
| 199 | } | 200 | } |
| 200 | 201 | ||
| 201 | .video-player.loading { | 202 | .video-player.loading { | ... | ... |
| ... | @@ -276,42 +276,48 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) { | ... | @@ -276,42 +276,48 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) { |
| 276 | return !canPlayHlsNatively(); | 276 | return !canPlayHlsNatively(); |
| 277 | }); | 277 | }); |
| 278 | 278 | ||
| 279 | - const videoOptions = computed(() => ({ | 279 | + const videoOptions = computed(() => { |
| 280 | - controls: true, | 280 | + const base = { |
| 281 | - preload: "metadata", | 281 | + controls: true, |
| 282 | - responsive: true, | 282 | + preload: "metadata", |
| 283 | - autoplay: props.autoplay, | 283 | + responsive: true, |
| 284 | - playsinline: true, | 284 | + autoplay: props.autoplay, |
| 285 | - playbackRates: [0.5, 0.75, 1, 1.25, 1.5, 2], | 285 | + playsinline: true, |
| 286 | - sources: videoSources.value, | 286 | + playbackRates: [0.5, 0.75, 1, 1.25, 1.5, 2], |
| 287 | - html5: { | 287 | + sources: videoSources.value, |
| 288 | - vhs: { | 288 | + html5: { |
| 289 | - overrideNative: shouldOverrideNativeHls.value, | 289 | + vhs: { |
| 290 | + overrideNative: shouldOverrideNativeHls.value, | ||
| 291 | + }, | ||
| 292 | + nativeVideoTracks: false, | ||
| 293 | + nativeAudioTracks: false, | ||
| 294 | + nativeTextTracks: false, | ||
| 295 | + hls: { | ||
| 296 | + withCredentials: false | ||
| 297 | + } | ||
| 290 | }, | 298 | }, |
| 291 | - nativeVideoTracks: false, | 299 | + techOrder: ['html5'], |
| 292 | - nativeAudioTracks: false, | 300 | + userActions: { |
| 293 | - nativeTextTracks: false, | 301 | + hotkeys: true, |
| 294 | - hls: { | 302 | + doubleClick: true, |
| 295 | - withCredentials: false | 303 | + }, |
| 296 | - } | 304 | + controlBar: { |
| 297 | - }, | 305 | + progressControl: { |
| 298 | - techOrder: ['html5'], | 306 | + seekBar: { |
| 299 | - userActions: { | 307 | + mouseTimeDisplay: { |
| 300 | - hotkeys: true, | 308 | + keepTooltipsInside: true, |
| 301 | - doubleClick: true, | 309 | + }, |
| 302 | - }, | ||
| 303 | - controlBar: { | ||
| 304 | - progressControl: { | ||
| 305 | - seekBar: { | ||
| 306 | - mouseTimeDisplay: { | ||
| 307 | - keepTooltipsInside: true, | ||
| 308 | }, | 310 | }, |
| 309 | }, | 311 | }, |
| 310 | }, | 312 | }, |
| 311 | - }, | 313 | + ...props.options, |
| 312 | - ...props.options, | 314 | + errorDisplay: false, |
| 313 | - errorDisplay: false, | 315 | + }; |
| 314 | - })); | 316 | + if (!base.poster) { |
| 317 | + delete base.poster; | ||
| 318 | + } | ||
| 319 | + return base; | ||
| 320 | + }); | ||
| 315 | 321 | ||
| 316 | // 8. Video.js 挂载处理 | 322 | // 8. Video.js 挂载处理 |
| 317 | const handleVideoJsMounted = (payload) => { | 323 | const handleVideoJsMounted = (payload) => { | ... | ... |
| ... | @@ -10,8 +10,8 @@ | ... | @@ -10,8 +10,8 @@ |
| 10 | <!-- 视频播放区域 --> | 10 | <!-- 视频播放区域 --> |
| 11 | <div v-if="course.course_type === 'video'" class="w-full relative"> | 11 | <div v-if="course.course_type === 'video'" class="w-full relative"> |
| 12 | <!-- 视频封面和播放按钮 --> | 12 | <!-- 视频封面和播放按钮 --> |
| 13 | - <div v-if="!isPlaying" class="relative w-full" style="aspect-ratio: 16/9;"> | 13 | + <div v-if="!isPlaying" class="relative w-full" :style="{ aspectRatio: '16/9', backgroundColor: courseFile.cover ? 'transparent' : '#000' }"> |
| 14 | - <img :src="courseFile.cover" :alt="course.title" class="w-full h-full object-cover" /> | 14 | + <img v-if="courseFile.cover" :src="courseFile.cover" :alt="course.title" class="w-full h-full object-cover" /> |
| 15 | <div class="absolute inset-0 flex items-center justify-center cursor-pointer" | 15 | <div class="absolute inset-0 flex items-center justify-center cursor-pointer" |
| 16 | @click="startPlay"> | 16 | @click="startPlay"> |
| 17 | <div | 17 | <div | ... | ... |
-
Please register or login to post a comment