2 lines
31 KiB
JavaScript
2 lines
31 KiB
JavaScript
"use strict";const i=require("../../common/vendor.js"),e=require("../../config/api.js"),t={computed:{showLoadingOverlay(){return!this.hasVideoError&&(!this.videoEnded&&!this.pausedByAudioEnd&&(!this.localVideoPath||!this.isVideoPlaying&&(!(this.userPaused&&!this.videoHasStarted&&!this.isVideoDownloading&&!this.videoWaiting)&&(!(!this.isVideoDownloading||this.videoHasStarted)||(!this.videoHasStarted||!(this.lastVideoTime>0)&&!!this.videoWaiting)))))},shouldShowPlayButton(){return!this.videoHasStarted||!this.isLoopingRestart&&!this.videoWaiting&&(!this.isVideoPlaying&&!!this.userPaused)},loadingText(){return this.isVideoDownloading?this.downloadProgress>0?`下载中 ${this.downloadProgress}%`:"准备下载...":this.videoWaiting?"缓冲中...":"加载中..."},loadingHint(){return this.waitingNeedsUserAction?"点击屏幕重试":this.isVideoDownloading&&this.downloadProgress>0?"首次播放需要下载,请稍候":""},videoError(){return this.hasVideoError},errorMessage(){return this.videoErrorMessage||"请检查网络连接后重试"}},data:()=>({API_BASE:e.API_BASE,videoId:"",videoUrl:"",audioUrl:"",videoTitle:"视频播放",audioInVideo:!1,hasAudio:!1,audioContext:null,videoContext:null,audioDuration:0,videoDuration:0,isAudioPlaying:!1,videoLoopTimer:null,audioStarted:!1,audioReady:!1,audioEnded:!1,pendingAudioStart:!1,pendingVideoPlay:!1,audioStartDelaySec:1,lastVideoTime:0,enableSilencePause:!1,silenceSegments:[],silenceLoaded:!1,pausedBySilence:!1,lastAudioTime:0,isLoopingRestart:!1,userPaused:!1,pausedByAudioEnd:!1,videoEndedWaitingAudio:!1,videoWaiting:!1,videoEnded:!1,lastVideoTimeUpdateAt:0,playbackWatchdogTimer:null,lastWaitingRecoverAt:0,localVideoPath:"",isVideoDownloading:!1,isVideoReady:!1,downloadProgress:0,downloadTask:null,pendingCacheSaveTempPath:"",pendingCacheSaveTimer:null,waitingTimer:null,waitingSince:0,waitingNeedsUserAction:!1,videoHasStarted:!1,isVideoPlaying:!1,appNetworkFallbackTimer:null,appFallbackTriggered:!1,appNetworkFallbackDelayMs:900,hasShownStorageLimitToast:!1,cacheKey:"",audioCacheKey:"",audioStartTime:0,videoStartTime:0,audioPauseTime:0,hasVideoError:!1,videoErrorMessage:"",retryCount:0,maxRetryCount:3,isRestarting:!1}),onLoad(e){console.log("[VideoPlayer] 接收参数:",e),console.log("[VideoPlayer] BUILD_MARK_NO_EXTERNAL_AUDIO=2026-01-08-01");const t="1"===e.audioInVideo||"true"===e.audioInVideo;if(void 0!==e.id&&null!==e.id&&""!==String(e.id).trim()&&(this.videoId=String(e.id).trim()),e.videoUrl?this.videoUrl=decodeURIComponent(e.videoUrl):e.url&&(this.videoUrl=decodeURIComponent(e.url)),void 0!==e.audioDelay&&null!==e.audioDelay&&""!==String(e.audioDelay).trim()){const i=Number(e.audioDelay);!Number.isNaN(i)&&i>=0&&(this.audioStartDelaySec=i)}if(void 0!==e.silencePause&&null!==e.silencePause&&""!==String(e.silencePause).trim()){const i=String(e.silencePause).trim();this.enableSilencePause="1"===i||"true"===i}if(this.videoUrl=this.normalizeMediaUrl(this.videoUrl),this.videoEnded=!1,this.userPaused=!0,this.videoId)this.loadVideoFromDb(t,e);else{const i=!(!this.videoUrl||-1===this.videoUrl.indexOf("/static/videos/revival_")),e=t||i;this.audioInVideo=e,console.log("[VideoPlayer] audioInVideo判定: audioInVideoParam=",t,"matchInVideo=",i,"videoUrl=",this.videoUrl),this.cacheKey=this.generateCacheKey(this.videoUrl),this.loadVideo()}e.title&&(this.videoTitle=decodeURIComponent(e.title)),this.hasAudio=!1,this.audioUrl="",audioInVideo?(this.hasAudio=!0,console.log("[VideoPlayer] audioInVideo=1,使用视频自带音轨")):e.audioUrl&&console.log("[VideoPlayer] 已忽略外部 audioUrl 参数(禁用外部音频)"),this.$nextTick((()=>{this.videoContext=i.index.createVideoContext("videoPlayer",this)}))},onUnload(){this.stopVideoLoop(),this.stopPlaybackWatchdog(),this.pendingCacheSaveTimer&&(clearTimeout(this.pendingCacheSaveTimer),this.pendingCacheSaveTimer=null),this.waitingTimer&&(clearTimeout(this.waitingTimer),this.waitingTimer=null);try{this.downloadTask&&"function"==typeof this.downloadTask.abort&&this.downloadTask.abort()}catch(i){}this.downloadTask=null,this.audioContext&&(this.audioContext.stop(),this.audioContext.destroy())},methods:{handleLoadingOverlayClick(){if(!this.videoWaiting)return;if(!this.videoContext)return;if(this.userPaused)return;if(this.videoEnded)return;if(!this.audioInVideo&&this.hasAudio&&this.audioContext&&!this.audioEnded)try{this.isAudioPlaying&&(this.audioPauseTime=this.audioContext.currentTime,this.audioContext.pause())}catch(t){}const i=Number(this.lastVideoTime)||0,e=Math.max(0,i-.3);console.log("[VideoPlayer] waiting手动重试: seekTo=",e);try{this.videoContext.seek&&this.videoContext.seek(e)}catch(t){}setTimeout((()=>{this.videoContext&&this.videoContext.play&&this.videoContext.play()}),120)},scheduleSaveVideoToCache(e,t){if(!e)return;this.pendingCacheSaveTempPath=e,this.pendingCacheSaveTimer&&(clearTimeout(this.pendingCacheSaveTimer),this.pendingCacheSaveTimer=null);const o="number"==typeof t?t:1600;this.pendingCacheSaveTimer=setTimeout((()=>{this.pendingCacheSaveTimer=null;const e=this.pendingCacheSaveTempPath;e&&(this.isVideoPlaying||this.videoWaiting?this.scheduleSaveVideoToCache(e,2e3):(this.pendingCacheSaveTempPath="",i.index.saveFile({tempFilePath:e,success:e=>{const t=e.savedFilePath;console.log("[VideoPlayer] 视频已缓存:",t),i.index.setStorageSync(this.cacheKey,t);const o=i.index.getStorageSync("video_cache_info")||{};o[this.cacheKey]={path:t,url:this.videoUrl,time:Date.now()},i.index.setStorageSync("video_cache_info",o)},fail:()=>{console.log("[VideoPlayer] 视频缓存失败,使用临时文件播放")}})))}),Math.max(300,o))},async loadVideoFromDb(e,t){try{const t=i.index.getStorageSync("token")||"",o=i.index.getStorageSync("userId")||"",s=`${this.API_BASE}/api/photo-revival/videos/${encodeURIComponent(this.videoId)}`;console.log("[VideoPlayer] 从数据库加载视频详情:",s);const d=await new Promise(((e,d)=>{i.index.request({url:s,method:"GET",header:{"X-User-Id":o,Authorization:t?`Bearer ${t}`:""},success:e,fail:d})})),a=d&&d.data?d.data:null,n=a&&a.success&&a.video||{},h=n.edited_video_url||n.local_video_path||n.video_url||"";h?(this.videoUrl=this.normalizeMediaUrl(String(h)),console.log("[VideoPlayer] 使用数据库视频URL:",this.videoUrl)):console.log("[VideoPlayer] 数据库未返回视频URL,回退使用参数videoUrl:",this.videoUrl);const r=!(!this.videoUrl||-1===this.videoUrl.indexOf("/static/videos/revival_")),l=e||r;this.audioInVideo=l,console.log("[VideoPlayer] audioInVideo判定(DB): audioInVideoParam=",e,"matchInVideo=",r,"videoUrl=",this.videoUrl),this.cacheKey=this.generateCacheKey(this.videoUrl),this.loadVideo()}catch(o){console.error("[VideoPlayer] 数据库加载视频详情失败,回退使用参数videoUrl:",o);const i=!(!this.videoUrl||-1===this.videoUrl.indexOf("/static/videos/revival_")),t=e||i;this.audioInVideo=t,this.cacheKey=this.generateCacheKey(this.videoUrl),this.loadVideo()}},handleTogglePlay(){if(this.videoContext){if(this.videoEnded||this.pausedByAudioEnd){console.log("[VideoPlayer] 视频已结束,从头播放"),this.isRestarting=!0,this.videoEnded=!1,this.audioEnded=!1,this.pausedByAudioEnd=!1,this.videoEndedWaitingAudio=!1,this.videoWaiting=!1,this.userPaused=!1,this.videoHasStarted=!1,this.lastVideoTime=0,this.isVideoPlaying=!1,this.retryCount=0,this.stopPlaybackWatchdog();try{this.videoContext.stop&&this.videoContext.stop()}catch(e){}try{this.videoContext.seek&&this.videoContext.seek(0)}catch(e){}return setTimeout((()=>{this.videoContext&&this.videoContext.play&&this.videoContext.play(),setTimeout((()=>{this.isRestarting=!1}),500)}),100),void(i.index.vibrateShort&&i.index.vibrateShort({type:"light"}))}if(this.isVideoPlaying)return this.userPaused=!0,this.videoContext.pause(),void(i.index.vibrateShort&&i.index.vibrateShort({type:"light"}));this.userPaused=!1,this.videoContext.play(),i.index.vibrateShort&&i.index.vibrateShort({type:"light"})}else this.$nextTick((()=>{this.videoContext=i.index.createVideoContext("videoPlayer",this),this.userPaused=!1,this.videoContext&&this.videoContext.play&&this.videoContext.play()}))},startPlaybackWatchdog(){this.playbackWatchdogTimer||(this.lastVideoTimeUpdateAt=Date.now(),this.playbackWatchdogTimer=setInterval((()=>{if(!this.videoContext)return;if(this.userPaused)return;if(this.videoEnded)return;if(!this.videoHasStarted)return;if(this.audioEnded)return;const i=Date.now();this.isVideoPlaying&&this.lastVideoTimeUpdateAt&&i-this.lastVideoTimeUpdateAt>2500&&(console.log("[VideoPlayer] 检测到视频疑似卡住(无timeupdate),尝试恢复播放。lastVideoTime=",this.lastVideoTime),this.videoContext.play())}),1500))},stopPlaybackWatchdog(){this.playbackWatchdogTimer&&(clearInterval(this.playbackWatchdogTimer),this.playbackWatchdogTimer=null)},goBack(){try{const e=getCurrentPages?getCurrentPages():[];if(e&&e.length>1)return void i.index.navigateBack()}catch(e){}i.index.switchTab({url:"/pages/history/history"})},generateCacheKey(i){let e=0;for(let t=0;t<i.length;t++){e=(e<<5)-e+i.charCodeAt(t),e&=e}return"video_"+Math.abs(e)},generateAudioCacheKey(i){let e=0;for(let t=0;t<i.length;t++){e=(e<<5)-e+i.charCodeAt(t),e&=e}return"audio_"+Math.abs(e)},normalizeMediaUrl(i){return i?i.startsWith("/")?`${this.API_BASE}${i}`:i.startsWith("http://115.190.167.176:20002")?i.replace("http://115.190.167.176:20002",this.API_BASE):i:i},toPlayableLocalPath(i){if(!i)return i;try{if("undefined"!=typeof plus&&plus.io&&"function"==typeof plus.io.convertLocalFileSystemURL)return plus.io.convertLocalFileSystemURL(i)}catch(e){}return i},loadVideo(){if(!this.videoUrl)return;this.videoHasStarted=!1,this.videoWaiting=!1,this.videoEnded=!1;const e=i.index.getStorageSync(this.cacheKey);if(e)console.log("[VideoPlayer] 找到缓存视频:",e),i.index.getSavedFileInfo({filePath:e,success:t=>{console.log("[VideoPlayer] 缓存文件有效,直接使用"),this.localVideoPath=this.toPlayableLocalPath(e),this.isVideoReady=!0,this.isVideoDownloading=!1,this.$nextTick((()=>{this.videoContext||(this.videoContext=i.index.createVideoContext("videoPlayer",this)),setTimeout((()=>{this.videoContext&&(this.userPaused||this.videoEnded||this.videoHasStarted||this.videoContext.play&&this.videoContext.play())}),80)}))},fail:()=>{console.log("[VideoPlayer] 缓存文件已失效,重新下载"),i.index.removeStorageSync(this.cacheKey),this.localVideoPath=this.videoUrl,this.downloadAndCacheVideo(),this.isVideoReady=!0,this.$nextTick((()=>{this.videoContext||(this.videoContext=i.index.createVideoContext("videoPlayer",this)),setTimeout((()=>{this.videoContext&&(this.userPaused||this.videoEnded||this.videoHasStarted||this.videoContext.play&&this.videoContext.play())}),80)}))}});else{if(console.log("[VideoPlayer] 无缓存,先在线播放,后台下载缓存"),"undefined"!=typeof plus)return void this.tryAppNetworkPlaybackThenFallback();this.localVideoPath=this.videoUrl,this.isVideoReady=!0,this.$nextTick((()=>{this.videoContext||(this.videoContext=i.index.createVideoContext("videoPlayer",this)),setTimeout((()=>{this.videoContext&&(this.userPaused||this.videoEnded||this.videoHasStarted||this.videoContext.play&&this.videoContext.play())}),80)}))}},tryAppNetworkPlaybackThenFallback(){this.appFallbackTriggered=!1,this.appNetworkFallbackTimer&&(clearTimeout(this.appNetworkFallbackTimer),this.appNetworkFallbackTimer=null),this.localVideoPath=this.videoUrl,this.isVideoReady=!0,this.$nextTick((()=>{this.videoContext||(this.videoContext=i.index.createVideoContext("videoPlayer",this)),setTimeout((()=>{this.videoContext&&(this.userPaused||this.videoEnded||this.videoHasStarted||this.videoContext.play&&this.videoContext.play())}),80)}));const e=Number(this.appNetworkFallbackDelayMs)||900;this.appNetworkFallbackTimer=setTimeout((()=>{this.videoHasStarted||this.appFallbackTriggered||(console.log("[VideoPlayer] App网络直连未能快速开始播放,切换为下载兜底"),this.appFallbackTriggered=!0,this.downloadForPlaybackAndCache())}),Math.max(300,e))},downloadForPlaybackAndCache(){console.log("[VideoPlayer] App无缓存:先下载临时文件播放,再写入缓存:",this.videoUrl),this.isVideoDownloading=!0,this.downloadProgress=0;const e=i.index.downloadFile({url:this.videoUrl,success:e=>{if(200!==e.statusCode)return console.error("[VideoPlayer] App临时下载失败,状态码:",e.statusCode),this.isVideoDownloading=!1,this.isVideoReady=!0,this.localVideoPath=this.videoUrl,void(this.downloadTask=null);const t=e.tempFilePath;this.localVideoPath=this.toPlayableLocalPath(t),this.isVideoReady=!0,this.isVideoDownloading=!1,this.downloadTask=null,this.$nextTick((()=>{this.videoContext||(this.videoContext=i.index.createVideoContext("videoPlayer",this)),setTimeout((()=>{this.videoContext&&(this.userPaused||this.videoEnded||this.videoHasStarted||this.videoContext.play&&this.videoContext.play())}),80)})),this.scheduleSaveVideoToCache(t,1800)},fail:i=>{console.error("[VideoPlayer] App临时下载失败:",i),this.isVideoDownloading=!1,this.isVideoReady=!0,this.localVideoPath=this.videoUrl,this.downloadTask=null}});this.downloadTask=e||null,this.downloadTask&&"function"==typeof this.downloadTask.onProgressUpdate&&this.downloadTask.onProgressUpdate((i=>{i&&"number"==typeof i.progress&&(this.downloadProgress=Math.max(0,Math.min(100,Math.floor(i.progress))))}))},downloadAndCacheVideo(){},initAudio(){if(!this.audioUrl)return;this.audioContext=i.index.createInnerAudioContext(),this.audioContext.src=this.audioUrl,this.audioContext.autoplay=!1,this.audioReady=!1,this.audioEnded=!1,this.pausedBySilence=!1,this.lastAudioTime=0,this.lastAudioTimeUpdateAt=0,this.silenceSegments=[],this.silenceLoaded=!1,this.audioCacheKey=this.generateAudioCacheKey(this.audioUrl);const e=i.index.getStorageSync(this.audioCacheKey);e&&i.index.getSavedFileInfo({filePath:e,success:()=>{console.log("[VideoPlayer] 找到缓存音频:",e),this.audioContext&&(this.audioContext.src=e)},fail:()=>{i.index.removeStorageSync(this.audioCacheKey)}}),e||i.index.downloadFile({url:this.audioUrl,timeout:6e4,success:e=>{200===e.statusCode&&this.audioContext&&i.index.saveFile({tempFilePath:e.tempFilePath,success:e=>{const t=e.savedFilePath;console.log("[VideoPlayer] 音频已缓存:",t),i.index.setStorageSync(this.audioCacheKey,t),this.audioContext&&(this.audioContext.src=t)},fail:()=>{console.log("[VideoPlayer] 音频缓存失败,使用临时文件播放"),this.audioContext.src=e.tempFilePath}})},fail:i=>{console.error("[VideoPlayer] 音频下载失败,回退到URL直连:",i)}}),this.enableSilencePause&&this.fetchSilenceSegments(),this.audioContext.onCanplay((()=>{this.audioReady=!0;const i=Number(this.audioContext.duration);if(!Number.isNaN(i)&&i>0&&(this.audioDuration=i),console.log("[VideoPlayer] 音频时长:",this.audioDuration,"秒"),!this.audioStarted&&!this.audioEnded&&this.videoHasStarted&&this.lastVideoTime>=this.audioStartDelaySec){const i=Math.max(0,(this.lastVideoTime||0)-(this.audioStartDelaySec||0));return console.log("[VideoPlayer] 音频已就绪且视频已到达延迟点,开始播放音频,seek=",i),void this.startAudioFromVideoTime(i)}})),setTimeout((()=>{if(this.audioContext){const i=Number(this.audioContext.duration);!Number.isNaN(i)&&i>0&&(this.audioDuration=i),console.log("[VideoPlayer] 音频时长(延迟校准):",this.audioDuration,"秒")}}),200),this.audioContext.onPlay((()=>{console.log("[VideoPlayer] 音频开始播放"),this.isAudioPlaying=!0})),this.audioContext.onTimeUpdate&&this.audioContext.onTimeUpdate((()=>{if(!this.audioContext)return;const i=Number(this.audioContext.currentTime)||0;this.lastAudioTime=i,this.lastAudioTimeUpdateAt=Date.now(),this.enableSilencePause&&this.handleAudioTimeUpdate(i)})),this.audioContext.onPause((()=>{console.log("[VideoPlayer] 音频被暂停,当前位置:",this.audioContext.currentTime,"秒"),this.isAudioPlaying=!1})),this.audioContext.onStop((()=>{console.log("[VideoPlayer] 音频被停止"),this.isAudioPlaying=!1})),this.audioContext.onWaiting((()=>{console.log("[VideoPlayer] 音频加载中...")})),this.audioContext.onError((i=>{console.error("[VideoPlayer] 音频播放失败:",i)})),this.audioContext.onEnded((()=>{console.log("[VideoPlayer] 音频播放结束,总时长:",this.audioContext.duration,"秒,播放到:",this.audioContext.currentTime,"秒"),this.isAudioPlaying=!1,this.audioEnded=!0,this.pausedBySilence=!1,this.videoEndedWaitingAudio=!1,this.stopVideoLoop();const i=Number(this.audioContext.currentTime)||0,e=Math.max(i,Number(this.lastAudioTime)||0),t=Number(this.audioDuration)||Number(this.audioContext.duration)||0,o=t>0&&(e>=t-.6||e/t>=.95),s=this.videoDuration&&this.lastVideoTime>=this.videoDuration-.3;this.videoContext&&(o||s)?(console.log("[VideoPlayer] 音频结束,联动停止视频。audioEndedForSure=",o,"videoNearEnd=",s),this.videoWaiting=!1,this.userPaused=!0,this.pausedByAudioEnd=!0,this.stopPlaybackWatchdog(),this.videoContext.pause(),setTimeout((()=>{this.videoContext&&this.audioEnded&&this.pausedByAudioEnd&&this.videoContext.pause&&this.videoContext.pause()}),180),this.isVideoPlaying=!1):console.log("[VideoPlayer] 音频 onEnded 触发但无法确认已到结尾,跳过联动停止视频。audioDur=",t,"audioCur=",i,"lastAudioTime=",this.lastAudioTime)}))},fetchSilenceSegments(){if(!this.audioUrl)return;const e=i.index.getStorageSync("userId")||"",t=i.index.getStorageSync("token")||"";t&&i.index.request({url:`${this.API_BASE}/api/video/silence-detect`,method:"POST",timeout:12e4,header:{"X-User-Id":e,Authorization:t?`Bearer ${t}`:"","Content-Type":"application/json"},data:{audioUrl:this.audioUrl},success:i=>{var e,t,o,s,d;if(!(200===i.statusCode&&(!0===(null==(e=i.data)?void 0:e.success)||"true"===(null==(t=i.data)?void 0:t.success)||1===(null==(o=i.data)?void 0:o.success)||"1"===(null==(s=i.data)?void 0:s.success))))return void console.warn("[VideoPlayer] 静音检测失败:",i.data);const a=Array.isArray(null==(d=i.data)?void 0:d.segments)?i.data.segments:[];this.silenceSegments=a.map((i=>({start:Number(i.start)||0,end:Number(i.end)||0}))).filter((i=>i.end>i.start)).sort(((i,e)=>i.start-e.start)),this.silenceLoaded=!0,console.log("[VideoPlayer] 静音区间数量:",this.silenceSegments.length)},fail:i=>{console.error("[VideoPlayer] 静音检测请求失败:",i)}})},handleAudioTimeUpdate(i){if(!this.videoContext||!this.hasAudio)return;if(!this.enableSilencePause)return;if(!this.silenceLoaded||0===this.silenceSegments.length)return;if(this.audioEnded)return;let e=!1;for(const t of this.silenceSegments){if(i>=t.start&&i<t.end){e=!0;break}if(i<t.start)break}e?this.pausedBySilence||(this.pausedBySilence=!0,console.log("[VideoPlayer] 进入停顿区间,暂停视频"),this.videoContext.pause()):this.pausedBySilence&&(this.pausedBySilence=!1,console.log("[VideoPlayer] 结束停顿,继续播放视频"),this.videoContext.play())},startAudioFromVideoTime(i){if(!this.audioContext||!this.hasAudio)return;if(this.audioEnded)return;if(!this.audioReady)return this.pendingAudioStart=!0,void console.log("[VideoPlayer] 音频未就绪,等待 onCanplay 后启动");this.pendingAudioStart=!1,this.audioStarted=!0,this.audioContext.seek&&this.audioContext.seek(Math.max(0,i||0));const e=this.audioContext.duration||this.audioDuration;console.log("[VideoPlayer] 实际音频时长:",e,"秒"),this.audioContext.playbackRate=1,console.log("[VideoPlayer] 使用正常速度播放音频"),this.audioStartTime=Date.now(),this.videoStartTime=Date.now()-1e3*i,console.log("[VideoPlayer] 准备播放音频,URL:",this.audioUrl),this.audioContext.play()},retryVideo(){if(this.hasVideoError=!1,this.videoErrorMessage="",this.retryCount++,console.log("[VideoPlayer] 用户手动重试,第",this.retryCount,"次"),this.cacheKey)try{i.index.removeStorageSync(this.cacheKey)}catch(e){}this.localVideoPath="",this.isVideoReady=!1,this.videoHasStarted=!1,this.videoWaiting=!1,this.videoEnded=!1,this.$nextTick((()=>{this.loadVideo()}))},onVideoError(e){console.error("[VideoPlayer] 视频加载失败:",e),e&&e.detail&&e.detail.errMsg&&String(e.detail.errMsg);const t=e&&e.detail&&void 0!==e.detail.errCode&&null!==e.detail.errCode?String(e.detail.errCode):"",o=this.localVideoPath||this.videoUrl||"";if(this.videoWaiting=!1,this.videoEnded||this.pausedByAudioEnd)console.log("[VideoPlayer] 视频已结束,忽略错误事件,不重试");else if(this.videoDuration>0&&this.lastVideoTime>=this.videoDuration-1)console.log("[VideoPlayer] 视频已播放到结尾,忽略错误事件,不重试");else{if("undefined"!=typeof plus&&!this.appFallbackTriggered&&o===this.videoUrl)return console.log("[VideoPlayer] App网络直连播放失败,切换为下载兜底"),this.appFallbackTriggered=!0,void this.downloadForPlaybackAndCache();if(this.retryCount<this.maxRetryCount)return this.retryCount++,console.log("[VideoPlayer] 自动重试,第",this.retryCount,"次"),void setTimeout((()=>{if(this.videoEnded||this.pausedByAudioEnd)console.log("[VideoPlayer] 重试前检测到视频已结束,取消重试");else if(this.videoDuration>0&&this.lastVideoTime>=this.videoDuration-1)console.log("[VideoPlayer] 重试前检测到视频已播放到结尾,取消重试");else{if(this.cacheKey)try{i.index.removeStorageSync(this.cacheKey)}catch(e){}this.isRestarting=!0,this.isVideoPlaying=!1,this.videoWaiting=!1,this.localVideoPath=this.videoUrl,this.isVideoReady=!0,this.$nextTick((()=>{this.videoContext||(this.videoContext=i.index.createVideoContext("videoPlayer",this)),setTimeout((()=>{!this.videoContext||this.userPaused||this.videoEnded||this.videoContext.play&&this.videoContext.play(),setTimeout((()=>{this.isRestarting=!1}),800)}),100)}))}}),1e3*this.retryCount);this.hasVideoError=!0,this.videoErrorMessage=t?`错误代码: ${t}`:"网络连接失败或视频格式不支持"}},onVideoLoadedMetadata(i){i&&i.detail&&i.detail.duration&&(this.videoDuration=i.detail.duration,console.log("[VideoPlayer] 视频时长:",this.videoDuration,"秒")),this.videoWaiting=!1},onVideoPlay(){if(console.log("[VideoPlayer] 视频开始播放"),this.hasVideoError){console.log("[VideoPlayer] 视频加载失败,阻止播放");try{this.videoContext&&this.videoContext.pause&&this.videoContext.pause()}catch(i){}}else if(this.appNetworkFallbackTimer&&(clearTimeout(this.appNetworkFallbackTimer),this.appNetworkFallbackTimer=null),this.waitingNeedsUserAction=!1,this.waitingTimer&&(clearTimeout(this.waitingTimer),this.waitingTimer=null),this.videoEnded&&this.pausedByAudioEnd){console.log("[VideoPlayer] 视频已结束且被音频结束暂停,阻止继续播放");try{this.videoContext&&this.videoContext.pause&&this.videoContext.pause()}catch(i){}}else{if(this.videoHasStarted=!0,this.isVideoPlaying=!0,this.videoWaiting=!1,this.lastVideoTimeUpdateAt=Date.now(),this.startPlaybackWatchdog(),this.audioEnded&&this.pausedByAudioEnd&&this.videoContext)return console.log("[VideoPlayer] 音频已结束,阻止视频继续播放"),this.videoWaiting=!1,this.userPaused=!0,this.videoContext.pause(),void(this.isVideoPlaying=!1);if(this.hasAudio&&this.audioContext)if(0!==this.audioStartDelaySec||this.audioStarted||this.audioEnded){if(!this.audioReady)return this.pendingAudioStart=!0,void console.log("[VideoPlayer] 音频未就绪,等待音频就绪后在指定延迟点播放");!this.audioStarted||this.isAudioPlaying||this.audioEnded||(console.log("[VideoPlayer] 恢复音频播放,当前位置:",this.audioContext.currentTime,"秒"),this.audioContext.play())}else{if(this.audioReady){const i=Math.max(0,this.lastVideoTime||0);return console.log("[VideoPlayer] 无延迟模式:视频开始播放,启动音频,seek=",i),void this.startAudioFromVideoTime(i)}this.pendingAudioStart=!0}}},onVideoPause(){if(console.log("[VideoPlayer] 视频暂停"),!this.isLoopingRestart)return this.videoWaiting||!this.userPaused?(console.log("[VideoPlayer] 非用户暂停(可能缓冲/系统暂停),不联动暂停音频"),void(this.isVideoPlaying=!1)):void(this.audioContext&&this.hasAudio&&this.isAudioPlaying&&(console.log("[VideoPlayer] 暂停音频,当前位置:",this.audioContext.currentTime,"秒"),this.audioPauseTime=this.audioContext.currentTime,this.audioContext.pause()))},onVideoWaiting(){const i=Date.now();if(this.isVideoPlaying&&this.lastVideoTimeUpdateAt&&i-this.lastVideoTimeUpdateAt<500)return void console.log("[VideoPlayer] 视频正在播放中,忽略偶发 waiting 事件");if(this.videoWaiting=!0,this.waitingNeedsUserAction=!1,this.waitingSince=i,console.log("[VideoPlayer] 视频缓冲中(waiting),lastVideoTime=",this.lastVideoTime),!this.videoContext)return;if(this.waitingTimer&&(clearTimeout(this.waitingTimer),this.waitingTimer=null),this.waitingTimer=setTimeout((()=>{if(this.waitingTimer=null,!this.videoWaiting)return;if(!this.videoContext)return;if(this.userPaused)return;if(this.videoEnded)return;if(!this.audioInVideo&&this.hasAudio&&!this.audioEnded)return void(this.waitingNeedsUserAction=!0);const i=Number(this.lastVideoTime)||0,e=Math.max(0,i-.3);console.log("[VideoPlayer] waiting超时自动恢复: seekTo=",e);try{this.videoContext.seek&&this.videoContext.seek(e)}catch(t){}setTimeout((()=>{this.videoContext&&this.videoContext.play&&this.videoContext.play()}),120)}),6e3),"undefined"!=typeof plus&&!this.videoHasStarted&&!this.appFallbackTriggered&&this.localVideoPath===this.videoUrl)return console.log("[VideoPlayer] App首帧 waiting,立即切换为下载兜底"),this.appFallbackTriggered=!0,void this.downloadForPlaybackAndCache();if(this.videoEnded)return;if(this.videoEndedWaitingAudio&&this.hasAudio&&!this.audioEnded)return void console.log("[VideoPlayer] 视频已结束且音频未结束:忽略 waiting");if(!this.audioInVideo&&this.hasAudio&&!this.audioEnded)return void console.log("[VideoPlayer] 存在音频且未结束,跳过 waiting 自动恢复,以避免音频被系统 stop");const e=Date.now();this.lastWaitingRecoverAt&&e-this.lastWaitingRecoverAt<1500||(this.lastWaitingRecoverAt=e,setTimeout((()=>{this.videoContext&&(this.userPaused||this.videoEnded||this.pausedBySilence||this.audioEnded||(console.log("[VideoPlayer] waiting后尝试恢复视频播放"),this.videoContext.play()))}),600))},onVideoEnded(){if(console.log("[VideoPlayer] 视频播放结束","lastVideoTime=",this.lastVideoTime,"videoDuration=",this.videoDuration,"audioEnded=",this.audioEnded,"isRestarting=",this.isRestarting),this.isRestarting)return void console.log("[VideoPlayer] 正在重新播放,忽略 ended 事件");if(this.hasVideoError||this.retryCount>=this.maxRetryCount)return console.log("[VideoPlayer] 视频加载失败或重试次数已达上限,阻止自动重播"),this.isVideoPlaying=!1,this.videoEnded=!0,void this.stopPlaybackWatchdog();if(this.isVideoPlaying=!1,this.videoEnded=!0,this.stopPlaybackWatchdog(),this.audioInVideo){this.videoWaiting=!1,this.userPaused=!0,this.pausedByAudioEnd=!0,this.audioEnded=!0,this.stopPlaybackWatchdog(),this.stopVideoLoop();try{this.videoContext&&this.videoContext.seek&&this.videoDuration&&this.videoContext.seek(Math.max(0,Number(this.videoDuration)-.05))}catch(s){}return void(this.videoContext&&this.videoContext.pause&&this.videoContext.pause())}if(this.hasAudio&&this.audioContext&&!this.audioEnded){this.videoEndedWaitingAudio=!0,this.videoWaiting=!1,console.log("[VideoPlayer] 音频未结束:视频停在末帧等待音频播完(不循环不重播)");try{this.videoContext&&this.videoContext.seek&&this.videoDuration&&this.videoContext.seek(Math.max(0,Number(this.videoDuration)-.05))}catch(s){}return void(this.videoContext&&this.videoContext.pause&&this.videoContext.pause())}if(this.hasAudio&&this.audioContext&&!this.audioEnded){const i=Number(this.audioContext.currentTime)||0,e=Math.max(i,Number(this.lastAudioTime)||0),t=Number(this.audioDuration)||Number(this.audioContext.duration)||0;if(t>0&&(e>=t-.6||e/t>=.95))return console.log("[VideoPlayer] 检测到音频已到结尾(兜底推断),停止视频循环并暂停视频。audioCurStable=",e,"audioDur=",t),this.audioEnded=!0,this.stopVideoLoop(),void(this.videoContext&&this.videoContext.pause&&this.videoContext.pause())}const e=Number(this.videoDuration)||0,t=Number(this.lastVideoTime)||0,o=!e&&t>0&&t<3||e>0&&t>0&&t<Math.max(1.5,e-.8);if(!this.audioEnded&&o){console.warn("[VideoPlayer] 检测到视频疑似提前结束,尝试清理缓存并重新加载。vt=",t,"vd=",e,"cacheKey=",this.cacheKey);try{this.cacheKey&&i.index.removeStorageSync(this.cacheKey)}catch(s){}return this.localVideoPath=this.videoUrl,this.isVideoReady=!0,this.isVideoDownloading=!1,this.downloadAndCacheVideo(),void this.$nextTick((()=>{this.videoContext||(this.videoContext=i.index.createVideoContext("videoPlayer",this)),setTimeout((()=>{this.videoContext&&this.videoContext.play&&this.videoContext.play()}),120)}))}},onTimeUpdate(i){if(!i||!i.detail)return;const e=i.detail.currentTime;if(this.lastVideoTime=e,this.lastVideoTimeUpdateAt=Date.now(),!this.videoHasStarted&&(Number(e)||0)>0&&(this.videoHasStarted=!0),!this.userPaused&&(Number(e)||0)>0&&(this.isVideoPlaying=!0),this.videoWaiting&&(console.log("[VideoPlayer] timeupdate 清除 waiting 状态,currentTime=",e),this.videoWaiting=!1,this.waitingNeedsUserAction=!1),this.waitingTimer&&(clearTimeout(this.waitingTimer),this.waitingTimer=null),this.isVideoPlaying||this.userPaused||(this.isVideoPlaying=!0),this.hasAudio&&this.audioContext&&!this.audioStarted&&!this.audioEnded&&e>=this.audioStartDelaySec){if(this.audioReady){const i=Math.max(0,(e||0)-(this.audioStartDelaySec||0));return console.log("[VideoPlayer] 视频到达延迟点,开始播放音频,seek=",i),void this.startAudioFromVideoTime(i)}this.pendingAudioStart=!0}},startVideoLoop(){this.videoLoopTimer||console.log("[VideoPlayer] 视频循环已启动")},stopVideoLoop(){this.videoLoopTimer&&(clearInterval(this.videoLoopTimer),this.videoLoopTimer=null,console.log("[VideoPlayer] 视频循环已停止"))}}};const o=i._export_sfc(t,[["render",function(e,t,o,s,d,a){return i.e({a:i.o(((...i)=>a.goBack&&a.goBack(...i))),b:i.t(d.videoTitle),c:a.videoError},a.videoError?{d:i.t(a.errorMessage),e:i.o(((...i)=>a.retryVideo&&a.retryVideo(...i))),f:i.o(((...i)=>a.goBack&&a.goBack(...i)))}:{},{g:a.showLoadingOverlay&&!a.videoError},a.showLoadingOverlay&&!a.videoError?i.e({h:i.t(a.loadingText),i:a.loadingHint},a.loadingHint?{j:i.t(a.loadingHint)}:{},{k:d.isVideoDownloading&&d.downloadProgress>0},d.isVideoDownloading&&d.downloadProgress>0?{l:d.downloadProgress+"%"}:{},{m:i.o(((...i)=>a.handleLoadingOverlayClick&&a.handleLoadingOverlayClick(...i)))}):{},{n:d.localVideoPath},d.localVideoPath?{o:d.localVideoPath,p:!!d.audioUrl,q:i.o(((...i)=>a.onVideoError&&a.onVideoError(...i))),r:i.o(((...i)=>a.onVideoPlay&&a.onVideoPlay(...i))),s:i.o(((...i)=>a.onVideoPause&&a.onVideoPause(...i))),t:i.o(((...i)=>a.onVideoWaiting&&a.onVideoWaiting(...i))),v:i.o(((...i)=>a.onVideoEnded&&a.onVideoEnded(...i))),w:i.o(((...i)=>a.onTimeUpdate&&a.onTimeUpdate(...i))),x:i.o(((...i)=>a.onVideoLoadedMetadata&&a.onVideoLoadedMetadata(...i)))}:{},{y:d.localVideoPath&&!a.showLoadingOverlay},d.localVideoPath&&!a.showLoadingOverlay?i.e({z:a.shouldShowPlayButton},(a.shouldShowPlayButton,{}),{A:i.o(((...i)=>a.handleTogglePlay&&a.handleTogglePlay(...i)))}):{})}],["__scopeId","data-v-60f68b50"]]);wx.createPage(o);
|