hookehuyr

fix(视频播放器): 修复视频播放器初始化及播放逻辑问题

确保视频播放器组件完全初始化后再执行播放操作
增加播放失败时的错误处理和静音播放重试逻辑
添加调试日志帮助追踪播放流程
...@@ -113,6 +113,8 @@ const videoOptions = computed(() => ({ ...@@ -113,6 +113,8 @@ const videoOptions = computed(() => ({
113 })); 113 }));
114 114
115 const handleMounted = (payload) => { 115 const handleMounted = (payload) => {
116 + console.log('VideoPlayer: handleMounted 被调用');
117 + console.log('VideoPlayer: payload.player:', payload.player);
116 state.value = payload.state; 118 state.value = payload.state;
117 player.value = payload.player; 119 player.value = payload.player;
118 if (player.value) { 120 if (player.value) {
...@@ -259,14 +261,60 @@ defineExpose({ ...@@ -259,14 +261,60 @@ defineExpose({
259 } 261 }
260 }, 262 },
261 play() { 263 play() {
262 - if (player.value && !player.value.isDisposed && typeof player.value.isDisposed === 'function' && !player.value.isDisposed()) { 264 + console.log('VideoPlayer: play() 被调用');
265 + console.log('VideoPlayer: player.value:', player.value);
266 + console.log('VideoPlayer: player.value?.isDisposed:', player.value?.isDisposed);
267 +
268 + if (!player.value) {
269 + console.error('VideoPlayer: player.value 不存在,播放器可能还没初始化');
270 + return;
271 + }
272 +
273 + if (!player.value.isDisposed || typeof player.value.isDisposed !== 'function') {
274 + console.error('VideoPlayer: isDisposed 方法不存在');
275 + return;
276 + }
277 +
278 + if (player.value.isDisposed()) {
279 + console.error('VideoPlayer: 播放器已被销毁');
280 + return;
281 + }
282 +
283 + console.log('VideoPlayer: 尝试播放视频');
284 +
285 + // 检查视频元素状态
263 try { 286 try {
264 - player.value?.play(); 287 + const tech = player.value.tech(true);
265 - emit('onPlay', player.value); 288 + if (tech && tech.el) {
289 + const videoEl = tech.el();
290 + console.log('VideoPlayer: videoEl.readyState:', videoEl?.readyState, '(0=HAVE_NOTHING, 1=HAVE_METADATA, 2=HAVE_CURRENT_DATA, 3=HAVE_FUTURE_DATA, 4=HAVE_ENOUGH_DATA)');
291 + console.log('VideoPlayer: videoEl.paused:', videoEl?.paused);
292 + console.log('VideoPlayer: videoEl.duration:', videoEl?.duration);
293 + console.log('VideoPlayer: videoEl.src:', videoEl?.src);
294 + }
266 } catch (e) { 295 } catch (e) {
267 - console.warn('Video play error:', e); 296 + console.warn('VideoPlayer: 无法获取video元素:', e);
268 } 297 }
298 +
299 + player.value.play()
300 + .then(() => {
301 + console.log('VideoPlayer: play() 成功');
302 + })
303 + .catch(error => {
304 + console.error('VideoPlayer: play() 失败:', error.name, error.message);
305 + // 如果是因为自动播放策略失败,可以静音重试
306 + if (error.name === 'NotAllowedError') {
307 + console.log('VideoPlayer: 浏览器阻止自动播放,尝试静音播放');
308 + player.value.muted(true);
309 + player.value.play()
310 + .then(() => {
311 + console.log('VideoPlayer: 静音播放成功');
312 + })
313 + .catch(err => {
314 + console.error('VideoPlayer: 静音播放也失败:', err);
315 + });
269 } 316 }
317 + });
270 }, 318 },
271 getPlayer() { 319 getPlayer() {
272 return player.value; 320 return player.value;
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
22 </div> 22 </div>
23 </div> 23 </div>
24 <!-- 视频播放器 --> 24 <!-- 视频播放器 -->
25 - <VideoPlayer v-show="isPlaying" ref="videoPlayerRef" 25 + <VideoPlayer v-if="isPlaying" ref="videoPlayerRef"
26 :video-url="courseFile?.list?.length ? courseFile['list'][0]['url'] : ''" :autoplay="false" 26 :video-url="courseFile?.list?.length ? courseFile['list'][0]['url'] : ''" :autoplay="false"
27 :video-id="courseFile?.list?.length ? courseFile['list'][0]['meta_id'] : ''" 27 :video-id="courseFile?.list?.length ? courseFile['list'][0]['meta_id'] : ''"
28 @onPlay="handleVideoPlay" @onPause="handleVideoPause" /> 28 @onPlay="handleVideoPlay" @onPause="handleVideoPause" />
...@@ -307,11 +307,23 @@ const course_type_maps = ref({ ...@@ -307,11 +307,23 @@ const course_type_maps = ref({
307 307
308 // 开始播放视频 308 // 开始播放视频
309 const startPlay = async () => { 309 const startPlay = async () => {
310 + console.log('StudyDetailPage: startPlay 被调用');
310 isPlaying.value = true; 311 isPlaying.value = true;
312 +
313 + // 等待 VideoPlayer 组件挂载并初始化完成
311 await nextTick(); 314 await nextTick();
315 +
316 + // 需要额外等待 VideoPlayer 组件的 handleMounted 完成
317 + // 使用 setTimeout 确保播放器已经初始化
318 + setTimeout(() => {
319 + console.log('StudyDetailPage: videoPlayerRef.value:', videoPlayerRef.value);
320 + console.log('StudyDetailPage: typeof videoPlayerRef.value?.play:', typeof videoPlayerRef.value?.play);
312 if (videoPlayerRef.value) { 321 if (videoPlayerRef.value) {
313 videoPlayerRef.value.play(); 322 videoPlayerRef.value.play();
323 + } else {
324 + console.error('StudyDetailPage: videoPlayerRef.value 不存在');
314 } 325 }
326 + }, 300); // 增加延迟,确保播放器初始化完成
315 }; 327 };
316 328
317 // 处理视频播放状态 329 // 处理视频播放状态
......