diff --git a/frontend-ai/pages/index/index.vue b/frontend-ai/pages/index/index.vue index 41783c9..95d48e7 100644 --- a/frontend-ai/pages/index/index.vue +++ b/frontend-ai/pages/index/index.vue @@ -23,6 +23,10 @@ @@ -54,6 +58,7 @@ 📹 开始视频通话 + 本服务为AI生成内容,结果仅供参考 @@ -304,6 +309,20 @@ export default { display: block; } +/* AI生成提示标签 */ +::v-deep .ai-tag { + position: absolute; + top: 16upx; + left: 16upx; + padding: 6upx 16upx; + background: rgba(255, 165, 0, 0.85); + color: white; + font-size: 22upx; + border-radius: 20upx; + font-weight: 500; + z-index: 10; +} + /* 功能网格 */ .feature-grid { display: grid; @@ -387,11 +406,20 @@ export default { padding: 0 20upx; } +.ai-disclaimer { + display: block; + text-align: center; + font-size: 22upx; + color: rgba(100, 100, 100, 0.7); + margin-top: 16upx; + letter-spacing: 0.5upx; +} + .video-call-btn { width: 100%; padding: 36upx; background: linear-gradient(135deg, #8B7355 0%, #6D8B8B 100%); - color: white; + color: #ffffff !important; border: none; border-radius: 40upx; font-size: 32upx; diff --git a/frontend-ai/pages/phone-call/phone-call.vue b/frontend-ai/pages/phone-call/phone-call.vue index 42b8789..369efd8 100644 --- a/frontend-ai/pages/phone-call/phone-call.vue +++ b/frontend-ai/pages/phone-call/phone-call.vue @@ -55,6 +55,7 @@ 📞 开始视频通话 请先选择视频 + 本服务为AI生成内容,结果仅供参考 @@ -64,9 +65,9 @@ - - + + + + AI生成 + + 🎬 视频加载中... @@ -1047,7 +1053,7 @@ export default { width: 100%; padding: 32upx; background: linear-gradient(135deg, #8B7355 0%, #6D8B8B 100%); - color: white; + color: #ffffff !important; border: none; border-radius: 28upx; font-size: 30upx; @@ -1068,7 +1074,16 @@ export default { box-shadow: 0 2upx 8upx rgba(0, 0, 0, 0.08); opacity: 0.65; transform: none !important; - color: #999; + color: #ffffff !important; +} + +.ai-disclaimer { + display: block; + text-align: center; + font-size: 22upx; + color: rgba(100, 100, 100, 0.6); + margin-top: 16upx; + letter-spacing: 0.5upx; } /* 通话中阶段 */ @@ -1120,6 +1135,24 @@ export default { background: linear-gradient(135deg, #2c3e50 0%, #34495e 100%); } +/* AI生成提示标签 */ +.ai-tag { + position: absolute; + top: 20rpx; + right: 20rpx; + z-index: 100; + background: rgba(0, 0, 0, 0.6); + padding: 8rpx 20rpx; + border-radius: 30rpx; + backdrop-filter: blur(10rpx); +} + +.ai-tag-text { + font-size: 22rpx; + color: #fff; + font-weight: 500; +} + .placeholder-icon { font-size: 100rpx; margin-bottom: 20rpx; diff --git a/frontend-ai/pages/plaza/plaza.vue b/frontend-ai/pages/plaza/plaza.vue index 182b9ce..e90aef8 100644 --- a/frontend-ai/pages/plaza/plaza.vue +++ b/frontend-ai/pages/plaza/plaza.vue @@ -36,6 +36,10 @@ 🎬 {{ work.workTypeLabel }} + + + AI生成 + {{ work.title }} @@ -495,6 +499,19 @@ export default { font-size: 20upx; border-radius: 20upx; } + + /* AI生成提示标签 */ + .ai-tag { + position: absolute; + top: 12upx; + left: 12upx; + padding: 6upx 16upx; + background: rgba(255, 165, 0, 0.85); + color: white; + font-size: 20upx; + border-radius: 20upx; + font-weight: 500; + } } .work-info { diff --git a/frontend-ai/pages/revival/revival-history.vue b/frontend-ai/pages/revival/revival-history.vue index 72645cd..c7852c2 100644 --- a/frontend-ai/pages/revival/revival-history.vue +++ b/frontend-ai/pages/revival/revival-history.vue @@ -43,6 +43,10 @@ 已缓存 + + + AI生成 + @@ -964,6 +968,25 @@ export default { font-weight: 500; } +/* AI生成提示标签 */ +.ai-tag { + position: absolute; + top: 12upx; + left: 12upx; + padding: 6upx 16upx; + background: rgba(255, 165, 0, 0.85); + color: white; + font-size: 20upx; + border-radius: 20upx; + font-weight: 500; + z-index: 10; +} + +.ai-tag-text { + font-size: 20upx; + font-weight: 500; +} + .video-info { padding: 20upx 16upx 16upx; background: linear-gradient(180deg, #FFFFFF 0%, #FDFBF9 100%); diff --git a/frontend-ai/pages/revival/revival-original.vue b/frontend-ai/pages/revival/revival-original.vue index 0af0cf7..adaace6 100644 --- a/frontend-ai/pages/revival/revival-original.vue +++ b/frontend-ai/pages/revival/revival-original.vue @@ -162,6 +162,7 @@ {{ loadingText }} 🎬 开始生成视频 + 本服务为AI生成内容,结果仅供参考 @@ -174,33 +175,40 @@ - + 🎉 生成成功! - + + + + + + AI生成 + + - + + 本服务为AI生成内容,结果仅供参考 ✅ 合成成功! @@ -2252,7 +2253,7 @@ export default { max-width: 100%; padding: 26upx; background: linear-gradient(135deg, #6D8B8B 0%, #8B7355 100%); - color: white; + color: #ffffff !important; border: none; border-radius: 24upx; font-size: 30upx; @@ -2276,6 +2277,16 @@ export default { opacity: 0.5; transform: none !important; box-shadow: 0 4upx 12upx rgba(139, 115, 85, 0.15) !important; + color: #ffffff !important; +} + +.ai-disclaimer { + display: block; + text-align: center; + font-size: 22upx; + color: rgba(100, 100, 100, 0.6); + margin-top: 16upx; + letter-spacing: 0.5upx; } .small-btn { diff --git a/frontend-ai/pages/upload-audio/upload-audio.vue b/frontend-ai/pages/upload-audio/upload-audio.vue index 5b98697..7da69ca 100644 --- a/frontend-ai/pages/upload-audio/upload-audio.vue +++ b/frontend-ai/pages/upload-audio/upload-audio.vue @@ -75,17 +75,18 @@ - - - - + + + + 本服务为AI生成内容,结果仅供参考 + @@ -866,12 +867,21 @@ export default { margin-bottom: 30upx; } +.ai-disclaimer { + display: block; + text-align: center; + font-size: 22upx; + color: rgba(100, 100, 100, 0.6); + margin-top: 16upx; + letter-spacing: 0.5upx; +} + .submit-btn { width: 100%; height: 90upx; background: linear-gradient(135deg, #8B7355 0%, #6D8B8B 100%); border-radius: 45upx; - color: white; + color: #ffffff !important; font-size: 32upx; font-weight: 600; border: none; @@ -880,6 +890,7 @@ export default { &[disabled] { opacity: 0.5; box-shadow: none; + color: #ffffff !important; } } diff --git a/frontend-ai/pages/video-call-new/video-call-new.vue b/frontend-ai/pages/video-call-new/video-call-new.vue index b81d73a..4ece576 100644 --- a/frontend-ai/pages/video-call-new/video-call-new.vue +++ b/frontend-ai/pages/video-call-new/video-call-new.vue @@ -156,6 +156,11 @@ 📹 视频加载中... + + + + AI生成 + @@ -3762,6 +3767,24 @@ export default { } } +/* AI生成提示标签 */ +.ai-tag { + position: absolute; + top: 100rpx; + right: 24rpx; + z-index: 100; + background: rgba(0, 0, 0, 0.6); + padding: 8rpx 20rpx; + border-radius: 30rpx; + backdrop-filter: blur(10rpx); +} + +.ai-tag-text { + font-size: 22rpx; + color: #fff; + font-weight: 500; +} + /* 点跳动动画 */ @keyframes dotBounce { 0%, 80%, 100% { diff --git a/frontend-ai/pages/video-call/video-call.vue b/frontend-ai/pages/video-call/video-call.vue index ac5cfbf..2cd550c 100644 --- a/frontend-ai/pages/video-call/video-call.vue +++ b/frontend-ai/pages/video-call/video-call.vue @@ -34,6 +34,11 @@ @timeupdate="onVideoTimeUpdate" > + + + AI生成 + + 📹 视频加载中... @@ -843,6 +848,24 @@ export default { z-index: 1; } +/* AI生成提示标签 */ +.ai-tag { + position: absolute; + top: 100rpx; + right: 24rpx; + z-index: 100; + background: rgba(0, 0, 0, 0.6); + padding: 8rpx 20rpx; + border-radius: 30rpx; + backdrop-filter: blur(10rpx); +} + +.ai-tag-text { + font-size: 22rpx; + color: #fff; + font-weight: 500; +} + .video-player { width: 100%; height: 100%; diff --git a/frontend-ai/pages/video-gen/video-gen.vue b/frontend-ai/pages/video-gen/video-gen.vue index 38dcc12..063ab52 100644 --- a/frontend-ai/pages/video-gen/video-gen.vue +++ b/frontend-ai/pages/video-gen/video-gen.vue @@ -67,6 +67,7 @@ ⏳ 生成中... 🎬 生成视频 + 本服务为AI生成内容,结果仅供参考 @@ -80,12 +81,19 @@ ✅ 生成成功 - + + + + + + AI生成 + + @@ -481,7 +489,7 @@ export default { width: 100%; padding: 30rpx; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - color: white; + color: #ffffff !important; border: none; border-radius: 15rpx; font-size: 32rpx; @@ -490,6 +498,16 @@ export default { .generate-btn[disabled] { opacity: 0.6; + color: #ffffff !important; +} + +.ai-disclaimer { + display: block; + text-align: center; + font-size: 22rpx; + color: rgba(100, 100, 100, 0.6); + margin-top: 16rpx; + letter-spacing: 0.5rpx; } .progress-section { @@ -526,13 +544,43 @@ export default { margin: 0 20rpx 20rpx; } -.result-video { +.result-section { + position: relative; +} + +.video-container { + position: relative; width: 100%; height: 500rpx; border-radius: 15rpx; + overflow: hidden; margin: 20rpx 0; } +.result-video { + width: 100%; + height: 100%; + border-radius: 15rpx; +} + +/* AI生成提示标签 */ +.ai-tag { + position: absolute; + top: 16rpx; + right: 16rpx; + z-index: 100; + background: rgba(0, 0, 0, 0.6); + padding: 8rpx 20rpx; + border-radius: 30rpx; + backdrop-filter: blur(10rpx); +} + +.ai-tag-text { + font-size: 22rpx; + color: #fff; + font-weight: 500; +} + .result-actions { display: flex; gap: 20rpx; diff --git a/frontend-ai/pages/video-player/video-player.vue b/frontend-ai/pages/video-player/video-player.vue index 8998204..9678989 100644 --- a/frontend-ai/pages/video-player/video-player.vue +++ b/frontend-ai/pages/video-player/video-player.vue @@ -62,6 +62,11 @@ + + + + AI生成 + @@ -1700,4 +1705,22 @@ export default { transform: scale(0.95); background: rgba(255, 255, 255, 0.15); } + +/* AI生成提示标签 */ +.ai-tag { + position: absolute; + top: 140rpx; + right: 24rpx; + z-index: 100; + background: rgba(0, 0, 0, 0.6); + padding: 8rpx 20rpx; + border-radius: 30rpx; + backdrop-filter: blur(10rpx); +} + +.ai-tag-text { + font-size: 22rpx; + color: #fff; + font-weight: 500; +} diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/index/index.js b/frontend-ai/unpackage/dist/build/mp-weixin/pages/index/index.js index ee807e5..fdc4354 100644 --- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/index/index.js +++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/index/index.js @@ -1 +1 @@ -"use strict";const e=require("../../common/vendor.js"),a=require("../../config/api.js"),o={components:{VideoSelectModal:()=>"../../components/VideoSelectModal.js"},data:()=>({apiBase:a.API_BASE,title:"时光意境 · AI亲人重逢",showVideoSelect:!1,banners:[]}),onLoad(){this.loadHomeBanners()},methods:{resolveUrl(e){return e?e.startsWith("http://")||e.startsWith("https://")?e:`${this.apiBase}${e}`:""},async loadHomeBanners(){try{const e=await a.request({url:"/api/system/home-banners",method:"GET"}),o=e&&e.success?e.data:[];Array.isArray(o)?this.banners=o.filter((e=>e&&e.url&&!1!==e.enabled)).sort(((e,a)=>(Number(e.sort)||0)-(Number(a.sort)||0))):this.banners=[]}catch(e){this.banners=[]}},handleBannerClick(a){if(a&&a.link){if(String(a.link).startsWith("/pages/"))return void e.index.navigateTo({url:a.link});e.index.setClipboardData({data:String(a.link)}),e.index.showToast({title:"已复制链接",icon:"none"})}},checkLogin(){const a=e.index.getStorageSync("token"),o=e.index.getStorageSync("userId");return!(!a||!o)},goVoiceClone(){e.index.switchTab({url:"/pages/revival/revival",fail:()=>{e.index.navigateTo({url:"/pages/revival/revival"})}})},goPhotoRevival(){e.index.navigateTo({url:"/pages/revival/revival-original"})},goPlaza(){e.index.navigateTo({url:"/pages/plaza/plaza"})},startVideoCall(){this.checkLogin()?this.showVideoSelect=!0:e.index.showModal({title:"提示",content:"请先登录后再使用此功能",confirmText:"去登录",cancelText:"取消",success:a=>{a.confirm&&e.index.navigateTo({url:"/pages/login/login"})}})},goAICall(){e.index.switchTab({url:"/pages/phone-call/phone-call",fail:()=>{e.index.navigateTo({url:"/pages/phone-call/phone-call"})}})},handleVideoSelect(a){console.log("[Index] 选择视频:",a),e.index.navigateTo({url:`/pages/video-call-new/video-call-new?videoId=${a.id}&videoName=${encodeURIComponent(a.name||"复活视频")}&videoUrl=${encodeURIComponent(a.videoUrl||a.local_video_path||a.video_url)}&voiceId=${a.voice_id||a.voiceId}`})},goShortDrama(){e.index.navigateTo({url:"/pages/short-drama/short-drama"})}}};if(!Array){e.resolveComponent("VideoSelectModal")()}const i=e._export_sfc(o,[["render",function(a,o,i,n,t,l){return{a:`${t.apiBase}/static/bg.png`,b:e.f(t.banners,((a,o,i)=>({a:l.resolveUrl(a.url),b:e.o((e=>l.handleBannerClick(a)),o),c:o}))),c:e.o(((...e)=>l.goPlaza&&l.goPlaza(...e))),d:e.o(((...e)=>l.goPhotoRevival&&l.goPhotoRevival(...e))),e:e.o(((...e)=>l.goShortDrama&&l.goShortDrama(...e))),f:e.o(((...e)=>l.goAICall&&l.goAICall(...e))),g:e.o(((...e)=>l.startVideoCall&&l.startVideoCall(...e))),h:e.o((e=>t.showVideoSelect=!1)),i:e.o(l.handleVideoSelect),j:e.p({show:t.showVideoSelect})}}],["__scopeId","data-v-e85e9fe9"]]);wx.createPage(i); +"use strict";const e=require("../../common/vendor.js"),a=require("../../config/api.js"),o={components:{VideoSelectModal:()=>"../../components/VideoSelectModal.js"},data:()=>({apiBase:a.API_BASE,title:"时光意境 · AI亲人重逢",showVideoSelect:!1,banners:[]}),onLoad(){this.loadHomeBanners()},methods:{resolveUrl(e){return e?e.startsWith("http://")||e.startsWith("https://")?e:`${this.apiBase}${e}`:""},async loadHomeBanners(){try{const e=await a.request({url:"/api/system/home-banners",method:"GET"}),o=e&&e.success?e.data:[];Array.isArray(o)?this.banners=o.filter((e=>e&&e.url&&!1!==e.enabled)).sort(((e,a)=>(Number(e.sort)||0)-(Number(a.sort)||0))):this.banners=[]}catch(e){this.banners=[]}},handleBannerClick(a){if(a&&a.link){if(String(a.link).startsWith("/pages/"))return void e.index.navigateTo({url:a.link});e.index.setClipboardData({data:String(a.link)}),e.index.showToast({title:"已复制链接",icon:"none"})}},checkLogin(){const a=e.index.getStorageSync("token"),o=e.index.getStorageSync("userId");return!(!a||!o)},goVoiceClone(){e.index.switchTab({url:"/pages/revival/revival",fail:()=>{e.index.navigateTo({url:"/pages/revival/revival"})}})},goPhotoRevival(){e.index.navigateTo({url:"/pages/revival/revival-original"})},goPlaza(){e.index.navigateTo({url:"/pages/plaza/plaza"})},startVideoCall(){this.checkLogin()?this.showVideoSelect=!0:e.index.showModal({title:"提示",content:"请先登录后再使用此功能",confirmText:"去登录",cancelText:"取消",success:a=>{a.confirm&&e.index.navigateTo({url:"/pages/login/login"})}})},goAICall(){e.index.switchTab({url:"/pages/phone-call/phone-call",fail:()=>{e.index.navigateTo({url:"/pages/phone-call/phone-call"})}})},handleVideoSelect(a){console.log("[Index] 选择视频:",a),e.index.navigateTo({url:`/pages/video-call-new/video-call-new?videoId=${a.id}&videoName=${encodeURIComponent(a.name||"复活视频")}&videoUrl=${encodeURIComponent(a.videoUrl||a.local_video_path||a.video_url)}&voiceId=${a.voice_id||a.voiceId}`})},goShortDrama(){e.index.navigateTo({url:"/pages/short-drama/short-drama"})}}};if(!Array){e.resolveComponent("VideoSelectModal")()}const i=e._export_sfc(o,[["render",function(a,o,i,n,t,l){return{a:`${t.apiBase}/static/bg.png`,b:e.f(t.banners,((a,o,i)=>({a:l.resolveUrl(a.url),b:e.o((e=>l.handleBannerClick(a)),o),c:o}))),c:e.o(((...e)=>l.goPlaza&&l.goPlaza(...e))),d:e.o(((...e)=>l.goPhotoRevival&&l.goPhotoRevival(...e))),e:e.o(((...e)=>l.goShortDrama&&l.goShortDrama(...e))),f:e.o(((...e)=>l.goAICall&&l.goAICall(...e))),g:e.o(((...e)=>l.startVideoCall&&l.startVideoCall(...e))),h:e.o((e=>t.showVideoSelect=!1)),i:e.o(l.handleVideoSelect),j:e.p({show:t.showVideoSelect})}}],["__scopeId","data-v-d7e89d74"]]);wx.createPage(i); diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/index/index.wxml b/frontend-ai/unpackage/dist/build/mp-weixin/pages/index/index.wxml index a203606..15f3679 100644 --- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/index/index.wxml +++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/index/index.wxml @@ -1 +1 @@ -用科技温暖记忆,让告别不留遗憾🖼️作品广场📸照片复活🎬看短剧📹视频通话只需简单三步,即可与记忆中的亲人温暖"重逢" \ No newline at end of file +用科技温暖记忆,让告别不留遗憾🖼️作品广场📸照片复活🎬看短剧📹视频通话本服务为AI生成内容,结果仅供参考只需简单三步,即可与记忆中的亲人温暖"重逢" \ No newline at end of file diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/index/index.wxss b/frontend-ai/unpackage/dist/build/mp-weixin/pages/index/index.wxss index 9d25b68..ce0f4dc 100644 --- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/index/index.wxss +++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/index/index.wxss @@ -1 +1 @@ -.memorial-bg.data-v-e85e9fe9{position:relative;min-height:100vh;overflow:hidden}.bg-image.data-v-e85e9fe9{position:fixed;top:0;left:0;width:100%;height:100%;z-index:0}.memorial-content.data-v-e85e9fe9{position:relative;z-index:2;padding:60rpx 30rpx 100rpx;max-width:1200rpx;margin:0 auto}.header.data-v-e85e9fe9{background:transparent;color:#2c2c2c;padding:40rpx 0 50rpx;text-align:center;position:relative;margin-bottom:20rpx}.header.data-v-e85e9fe9:after{content:"";position:absolute;bottom:0;left:50%;transform:translate(-50%);width:200rpx;height:3rpx;background:linear-gradient(90deg,transparent,#8B7355,transparent)}.header .logo.data-v-e85e9fe9{font-size:64rpx;font-weight:700;margin-bottom:24rpx;color:#8b7355;letter-spacing:2rpx;display:block;line-height:1.2}.header .tagline.data-v-e85e9fe9{font-size:32rpx;color:#666;font-weight:300;margin:0 auto;display:block;line-height:1.5}.memorial-quote.data-v-e85e9fe9{text-align:center;margin:30rpx 0 70rpx;padding:22rpx;background:rgba(255,255,255,.6);border-radius:30rpx;-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx);box-shadow:0 8rpx 30rpx rgba(0,0,0,.06)}.data-v-e85e9fe9 .banner-swiper{width:100%;height:900rpx;border-radius:22rpx;overflow:hidden}.data-v-e85e9fe9 .banner-item{width:100%;height:100%}.data-v-e85e9fe9 .banner-image{width:100%;height:100%;display:block}.feature-grid.data-v-e85e9fe9{display:grid;grid-template-columns:repeat(4,1fr);gap:12rpx;margin:30rpx 0;align-items:stretch}.data-v-e85e9fe9 .feature-item{background:rgba(255,255,255,.9);border-radius:18rpx;padding:10rpx 8rpx;text-align:center;transition:all .3s cubic-bezier(.175,.885,.32,1.275);box-shadow:0 8rpx 24rpx rgba(0,0,0,.08);-webkit-backdrop-filter:blur(20rpx);backdrop-filter:blur(20rpx);border:2rpx solid rgba(255,255,255,.8);position:relative;overflow:hidden;display:flex;flex-direction:column;align-items:center;justify-content:center;aspect-ratio:1;min-height:0}.data-v-e85e9fe9 .feature-item:before{content:"";position:absolute;top:0;left:0;right:0;height:4rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b);transform:scaleX(0);transition:transform .3s}.data-v-e85e9fe9 .feature-item:active{transform:translateY(-8rpx) scale(.98);box-shadow:0 16rpx 40rpx rgba(0,0,0,.12)}.data-v-e85e9fe9 .feature-item:active:before{transform:scaleX(1)}.data-v-e85e9fe9 .feature-item .feature-icon{font-size:32rpx;margin-bottom:8rpx;color:#8b7355;height:56rpx;width:56rpx;line-height:56rpx;border-radius:50%;background:rgba(139,115,85,.1);display:inline-block;transition:all .3s;flex-shrink:0}.data-v-e85e9fe9 .feature-item:active .feature-icon{background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff;transform:scale(1.1)}.data-v-e85e9fe9 .feature-item .feature-name{font-size:18rpx;font-weight:600;color:#2c2c2c;display:block;line-height:1.3}.video-call-section.data-v-e85e9fe9{margin:50rpx 0 40rpx;padding:0 20rpx}.video-call-btn.data-v-e85e9fe9{width:100%;padding:36rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff;border:none;border-radius:40rpx;font-size:32rpx;font-weight:700;box-shadow:0 16rpx 40rpx rgba(139,115,85,.3);transition:all .3s;position:relative;overflow:hidden;display:flex;align-items:center;justify-content:center;gap:16rpx}.video-call-btn.data-v-e85e9fe9:before{content:"";position:absolute;top:0;left:0;right:0;bottom:0;background:linear-gradient(135deg,rgba(255,255,255,.2) 0%,transparent 100%)}.video-call-btn.data-v-e85e9fe9:active{transform:translateY(-4rpx);box-shadow:0 20rpx 50rpx rgba(139,115,85,.4)}.video-call-btn .btn-icon.data-v-e85e9fe9{font-size:40rpx}.video-call-btn .btn-text.data-v-e85e9fe9{font-size:32rpx;font-weight:700}.cta-section.data-v-e85e9fe9{text-align:center;margin:70rpx 0 40rpx;padding:40rpx 30rpx;background:rgba(255,255,255,.5);border-radius:30rpx;-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx)}.cta-section .cta-text.data-v-e85e9fe9{font-size:30rpx;color:#666;margin:0 auto;line-height:1.8;display:block;font-style:italic;opacity:.9}@media (max-width: 750px){.memorial-content.data-v-e85e9fe9{padding:50rpx 24rpx 80rpx}.header.data-v-e85e9fe9{padding:30rpx 0 40rpx}.header .logo.data-v-e85e9fe9{font-size:56rpx;margin-bottom:20rpx}.header .tagline.data-v-e85e9fe9{font-size:28rpx}.memorial-quote.data-v-e85e9fe9{margin:50rpx 0 60rpx;padding:18rpx}.banner-swiper.data-v-e85e9fe9{height:360rpx}.feature-grid.data-v-e85e9fe9{grid-template-columns:repeat(2,1fr);gap:12rpx;margin:50rpx 0}.feature-item.data-v-e85e9fe9{padding:12rpx 10rpx;aspect-ratio:1.25;border-radius:16rpx}.feature-item .feature-icon.data-v-e85e9fe9{font-size:40rpx;height:64rpx;width:64rpx;line-height:64rpx;margin-bottom:8rpx}.feature-item .feature-name.data-v-e85e9fe9{font-size:22rpx}.video-call-section.data-v-e85e9fe9{margin:40rpx 0 30rpx;padding:0 16rpx}.video-call-btn.data-v-e85e9fe9{padding:32rpx}.video-call-btn .btn-icon.data-v-e85e9fe9{font-size:36rpx}.video-call-btn .btn-text.data-v-e85e9fe9{font-size:28rpx}.cta-section.data-v-e85e9fe9{margin:60rpx 0 30rpx;padding:32rpx 24rpx}.cta-section .cta-text.data-v-e85e9fe9{font-size:28rpx}} +.memorial-bg.data-v-d7e89d74{position:relative;min-height:100vh;overflow:hidden}.bg-image.data-v-d7e89d74{position:fixed;top:0;left:0;width:100%;height:100%;z-index:0}.memorial-content.data-v-d7e89d74{position:relative;z-index:2;padding:60rpx 30rpx 100rpx;max-width:1200rpx;margin:0 auto}.header.data-v-d7e89d74{background:transparent;color:#2c2c2c;padding:40rpx 0 50rpx;text-align:center;position:relative;margin-bottom:20rpx}.header.data-v-d7e89d74:after{content:"";position:absolute;bottom:0;left:50%;transform:translate(-50%);width:200rpx;height:3rpx;background:linear-gradient(90deg,transparent,#8B7355,transparent)}.header .logo.data-v-d7e89d74{font-size:64rpx;font-weight:700;margin-bottom:24rpx;color:#8b7355;letter-spacing:2rpx;display:block;line-height:1.2}.header .tagline.data-v-d7e89d74{font-size:32rpx;color:#666;font-weight:300;margin:0 auto;display:block;line-height:1.5}.memorial-quote.data-v-d7e89d74{text-align:center;margin:30rpx 0 70rpx;padding:22rpx;background:rgba(255,255,255,.6);border-radius:30rpx;-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx);box-shadow:0 8rpx 30rpx rgba(0,0,0,.06)}.data-v-d7e89d74 .banner-swiper{width:100%;height:900rpx;border-radius:22rpx;overflow:hidden}.data-v-d7e89d74 .banner-item{width:100%;height:100%}.data-v-d7e89d74 .banner-image{width:100%;height:100%;display:block}.data-v-d7e89d74 .ai-tag{position:absolute;top:16rpx;left:16rpx;padding:6rpx 16rpx;background:rgba(255,165,0,.85);color:#fff;font-size:22rpx;border-radius:20rpx;font-weight:500;z-index:10}.feature-grid.data-v-d7e89d74{display:grid;grid-template-columns:repeat(4,1fr);gap:12rpx;margin:30rpx 0;align-items:stretch}.data-v-d7e89d74 .feature-item{background:rgba(255,255,255,.9);border-radius:18rpx;padding:10rpx 8rpx;text-align:center;transition:all .3s cubic-bezier(.175,.885,.32,1.275);box-shadow:0 8rpx 24rpx rgba(0,0,0,.08);-webkit-backdrop-filter:blur(20rpx);backdrop-filter:blur(20rpx);border:2rpx solid rgba(255,255,255,.8);position:relative;overflow:hidden;display:flex;flex-direction:column;align-items:center;justify-content:center;aspect-ratio:1;min-height:0}.data-v-d7e89d74 .feature-item:before{content:"";position:absolute;top:0;left:0;right:0;height:4rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b);transform:scaleX(0);transition:transform .3s}.data-v-d7e89d74 .feature-item:active{transform:translateY(-8rpx) scale(.98);box-shadow:0 16rpx 40rpx rgba(0,0,0,.12)}.data-v-d7e89d74 .feature-item:active:before{transform:scaleX(1)}.data-v-d7e89d74 .feature-item .feature-icon{font-size:32rpx;margin-bottom:8rpx;color:#8b7355;height:56rpx;width:56rpx;line-height:56rpx;border-radius:50%;background:rgba(139,115,85,.1);display:inline-block;transition:all .3s;flex-shrink:0}.data-v-d7e89d74 .feature-item:active .feature-icon{background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff;transform:scale(1.1)}.data-v-d7e89d74 .feature-item .feature-name{font-size:18rpx;font-weight:600;color:#2c2c2c;display:block;line-height:1.3}.video-call-section.data-v-d7e89d74{margin:50rpx 0 40rpx;padding:0 20rpx}.ai-disclaimer.data-v-d7e89d74{display:block;text-align:center;font-size:22rpx;color:rgba(100,100,100,.7);margin-top:16rpx;letter-spacing:.5rpx}.video-call-btn.data-v-d7e89d74{width:100%;padding:36rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff!important;border:none;border-radius:40rpx;font-size:32rpx;font-weight:700;box-shadow:0 16rpx 40rpx rgba(139,115,85,.3);transition:all .3s;position:relative;overflow:hidden;display:flex;align-items:center;justify-content:center;gap:16rpx}.video-call-btn.data-v-d7e89d74:before{content:"";position:absolute;top:0;left:0;right:0;bottom:0;background:linear-gradient(135deg,rgba(255,255,255,.2) 0%,transparent 100%)}.video-call-btn.data-v-d7e89d74:active{transform:translateY(-4rpx);box-shadow:0 20rpx 50rpx rgba(139,115,85,.4)}.video-call-btn .btn-icon.data-v-d7e89d74{font-size:40rpx}.video-call-btn .btn-text.data-v-d7e89d74{font-size:32rpx;font-weight:700}.cta-section.data-v-d7e89d74{text-align:center;margin:70rpx 0 40rpx;padding:40rpx 30rpx;background:rgba(255,255,255,.5);border-radius:30rpx;-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx)}.cta-section .cta-text.data-v-d7e89d74{font-size:30rpx;color:#666;margin:0 auto;line-height:1.8;display:block;font-style:italic;opacity:.9}@media (max-width: 750px){.memorial-content.data-v-d7e89d74{padding:50rpx 24rpx 80rpx}.header.data-v-d7e89d74{padding:30rpx 0 40rpx}.header .logo.data-v-d7e89d74{font-size:56rpx;margin-bottom:20rpx}.header .tagline.data-v-d7e89d74{font-size:28rpx}.memorial-quote.data-v-d7e89d74{margin:50rpx 0 60rpx;padding:18rpx}.banner-swiper.data-v-d7e89d74{height:360rpx}.feature-grid.data-v-d7e89d74{grid-template-columns:repeat(2,1fr);gap:12rpx;margin:50rpx 0}.feature-item.data-v-d7e89d74{padding:12rpx 10rpx;aspect-ratio:1.25;border-radius:16rpx}.feature-item .feature-icon.data-v-d7e89d74{font-size:40rpx;height:64rpx;width:64rpx;line-height:64rpx;margin-bottom:8rpx}.feature-item .feature-name.data-v-d7e89d74{font-size:22rpx}.video-call-section.data-v-d7e89d74{margin:40rpx 0 30rpx;padding:0 16rpx}.video-call-btn.data-v-d7e89d74{padding:32rpx}.video-call-btn .btn-icon.data-v-d7e89d74{font-size:36rpx}.video-call-btn .btn-text.data-v-d7e89d74{font-size:28rpx}.cta-section.data-v-d7e89d74{margin:60rpx 0 30rpx;padding:32rpx 24rpx}.cta-section .cta-text.data-v-d7e89d74{font-size:28rpx}} diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/phone-call/phone-call.js b/frontend-ai/unpackage/dist/build/mp-weixin/pages/phone-call/phone-call.js index 3a7740a..37b6f1e 100644 --- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/phone-call/phone-call.js +++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/phone-call/phone-call.js @@ -1 +1 @@ -"use strict";const e=require("../../common/vendor.js"),t=require("../../config/api.js"),o=require("../../common/assets.js"),i={data:()=>({API_BASE:t.API_BASE,lastUserId:null,loading:!1,videos:[],selectedVideoId:"",selectedVideoName:"",selectedVideoUrl:"",selectedVoiceId:"",selectedDialect:"",selectedLanguageHint:"",selectedLanguageHintLabel:"",languageHintOptions:["中文(zh)","英文(en)","法语(fr)","德语(de)","日语(ja)","韩语(ko)","俄语(ru)"],dialectOptions:["广东话","东北话","甘肃话","贵州话","河南话","湖北话","江西话","闽南话","宁夏话","山西话","陕西话","山东话","上海话","四川话","天津话","云南话"],callStarted:!1,callStatus:"视频通话中",callDuration:"00:00",callStartTime:null,durationTimer:null,messages:[],scrollTop:0,isRecording:!1,isProcessing:!1,isSpeaking:!1,processingText:"处理中...",recorderManager:null,audioFilePath:"",audioContext:null,showSettingsDialog:!1,dialogMemoryIdentity:"",dialogMemoryInfo:"",dialogMemoryCatchphrase:""}),onLoad(){console.log("[PhoneCall] 页面加载");const t=e.index.getStorageSync("userId");this.lastUserId=t,this.loadVideos(),this.initRecorder(),this.initAudioContext()},onShow(){console.log("[PhoneCall] 页面显示");const t=e.index.getStorageSync("userId");this.lastUserId=t,this.callStarted||this.$nextTick((()=>{setTimeout((()=>{this.loadVideos()}),100)}))},onUnload(){this.cleanup()},methods:{async loadVideos(){this.loading=!0;const t=e.index.getStorageSync("userId")||"",o=e.index.getStorageSync("token")||"";e.index.request({url:`${this.API_BASE}/api/photo-revival/videos`,method:"GET",header:{"X-User-Id":t,Authorization:o?`Bearer ${o}`:""},success:e=>{if(console.log("[PhoneCall] 视频列表响应状态码:",e.statusCode),console.log("[PhoneCall] 视频列表响应数据:",e.data),console.log("[PhoneCall] 数据类型:",typeof e.data),200===e.statusCode){let t=[];Array.isArray(e.data)?t=e.data:e.data&&Array.isArray(e.data.data)?t=e.data.data:e.data&&e.data.videos&&Array.isArray(e.data.videos)&&(t=e.data.videos),t=t.filter((e=>{const t=e.name&&(e.name.startsWith("生成失败")||e.name.startsWith("生成失败:")),o=e.edited_video_url||e.video_url||e.local_video_path||e.videoUrl||e.localVideoPath,i=o&&""!==o.trim();return!t&&i})),this.videos=t,console.log("[PhoneCall] 加载视频列表成功:",this.videos.length),console.log("[PhoneCall] 视频列表:",this.videos)}else console.error("[PhoneCall] 响应状态码异常:",e.statusCode)},fail:t=>{console.error("[PhoneCall] 加载视频列表失败:",t),e.index.showToast({title:"加载失败",icon:"none"})},complete:()=>{this.loading=!1}})},selectVideo(e){console.log("[PhoneCall] 选择视频:",e),this.selectedVideoId=e.id,this.selectedVideoName=e.name||"复活视频",this.selectedVideoUrl=e.edited_video_url||e.local_video_path||e.video_url,this.selectedVoiceId=e.voice_id,this.selectedDialect="",this.selectedLanguageHint="",this.selectedLanguageHintLabel="",console.log("[PhoneCall] 选择视频:",this.selectedVideoId,"名称:",this.selectedVideoName),console.log("[PhoneCall] 视频URL:",this.selectedVideoUrl)},onDialectChange(e){this.selectedDialect=this.dialectOptions[e.detail.value]||""},onLanguageHintChange(e){const t=this.languageHintOptions[e.detail.value]||"";this.selectedLanguageHintLabel=t;const o=t.match(/\(([^)]+)\)/);this.selectedLanguageHint=o&&o[1]?o[1]:""},startCall(){if(!this.selectedVideoId)return void e.index.showToast({title:"请先选择视频",icon:"none"});console.log("[PhoneCall] 准备视频通话,视频ID:",this.selectedVideoId);const t=this.videos.find((e=>e.id===this.selectedVideoId));if(!t)return void e.index.showToast({title:"视频信息丢失",icon:"none"});const o=t.edited_video_url||t.videoUrl||t.local_video_path||t.video_url||t.localVideoPath||"",i=t.name||"复活视频",s=this.selectedVoiceId||"";console.log("[PhoneCall] 跳转参数:",{videoId:this.selectedVideoId,videoName:i,videoUrl:o,voiceId:s}),e.index.navigateTo({url:`/pages/video-call-new/video-call-new?videoId=${this.selectedVideoId}&videoName=${encodeURIComponent(i)}&videoUrl=${encodeURIComponent(o)}&voiceId=${s}`,success:()=>{console.log("[PhoneCall] 跳转到视频通话页面成功")},fail:t=>{console.error("[PhoneCall] 跳转失败:",t),e.index.showToast({title:"跳转失败",icon:"none"})}})},closeSettingsDialog(){this.showSettingsDialog=!1},confirmSettings(){this.showSettingsDialog=!1},startCallTimer(){this.callStartTime=Date.now(),this.durationTimer=setInterval((()=>{const e=Math.floor((Date.now()-this.callStartTime)/1e3),t=Math.floor(e/60).toString().padStart(2,"0"),o=(e%60).toString().padStart(2,"0");this.callDuration=`${t}:${o}`}),1e3)},initRecorder(){this.recorderManager=e.index.getRecorderManager(),this.recorderManager.onStart((()=>{console.log("[PhoneCall] 开始录音")})),this.recorderManager.onStop((e=>{console.log("[PhoneCall] 录音完成:",e.tempFilePath),this.audioFilePath=e.tempFilePath,this.processConversation()})),this.recorderManager.onError((t=>{console.error("[PhoneCall] 录音失败:",t),this.isRecording=!1,e.index.showToast({title:"录音失败",icon:"none"})}))},initAudioContext(){this.audioContext=e.index.createInnerAudioContext(),this.audioContext.onPlay((()=>{console.log("[PhoneCall] 开始播放AI回复"),this.isSpeaking=!0,this.callStatus="对方正在说话...",e.index.vibrateShort({type:"light"})})),this.audioContext.onEnded((()=>{console.log("[PhoneCall] AI回复播放完成"),this.isSpeaking=!1,this.callStatus="通话中"})),this.audioContext.onError((e=>{console.error("[PhoneCall] 音频播放失败:",e),this.isSpeaking=!1,this.callStatus="通话中"}))},startRecording(){this.isProcessing||(this.isRecording=!0,this.recorderManager.start({format:"mp3",sampleRate:16e3}),this.callStatus="正在录音...",e.index.vibrateShort({type:"medium"}))},stopRecording(){this.isRecording&&(this.isRecording=!1,this.recorderManager.stop(),this.isProcessing=!0,this.processingText="识别中...",this.callStatus="处理中...")},async processConversation(){try{this.processingText="正在识别...";const t=e.index.getStorageSync("userId")||"",o=e.index.getStorageSync("token")||"";e.index.uploadFile({url:`${this.API_BASE}/api/conversation/talk`,filePath:this.audioFilePath,name:"audio",header:{"X-User-Id":t,Authorization:o?`Bearer ${o}`:""},formData:(()=>{const e=this.selectedVoiceId,t=(()=>{const t=(e||"").trim();if(!t)return"CLONE";return["Cherry","Kai","Mochi","Bunny","Jada","Dylan","Li","Marcus","Roy","Peter","Sunny","Eric","Rocky","Kiki"].includes(t)||t.startsWith("BV")||t.endsWith("_streaming")||t.endsWith("_offline")||t.endsWith("_bigtts")?"OFFICIAL":"CLONE"})(),o={voiceId:e,voiceType:t};return this.selectedDialect&&(o.dialect=this.selectedDialect),this.selectedLanguageHint&&(o.languageHints=this.selectedLanguageHint),o})(),success:e=>{if(console.log("[PhoneCall] 对话响应:",e),200!==e.statusCode)throw new Error("对话请求失败");{const t=JSON.parse(e.data);if(!t.success)throw new Error(t.message||"对话失败");this.addMessage("user",t.recognizedText),this.addMessage("ai",t.aiResponse),this.playAIResponse(t.audioFile)}},fail:t=>{console.error("[PhoneCall] 对话失败:",t),e.index.showToast({title:"对话失败",icon:"none"}),this.isProcessing=!1,this.callStatus="通话中"}})}catch(t){console.error("[PhoneCall] 对话失败:",t),e.index.showToast({title:"对话失败: "+t.message,icon:"none"}),this.isProcessing=!1,this.callStatus="通话中"}},playAIResponse(e){this.processingText="正在回复...",this.audioContext.src=`${this.API_BASE}/api/conversation/audio/${e}`,this.audioContext.play(),this.isProcessing=!1},addMessage(e,t){const o=new Date,i=`${o.getHours()}:${o.getMinutes().toString().padStart(2,"0")}`;this.messages.push({role:e,content:t,time:i}),this.$nextTick((()=>{this.scrollTop=999999}))},handleClearHistory(){e.index.showModal({title:"确认清空",content:"确定要清空对话历史吗?",success:t=>{if(t.confirm){const t=e.index.getStorageSync("userId")||"",o=e.index.getStorageSync("token")||"";e.index.request({url:`${this.API_BASE}/api/conversation/clear-history`,method:"POST",header:{"X-User-Id":t,Authorization:o?`Bearer ${o}`:""},success:t=>{t.data.success&&(this.messages=[],e.index.showToast({title:"已清空",icon:"success"}))}})}}})},endCall(){e.index.showModal({title:"结束通话",content:`通话时长:${this.callDuration}\n确定要结束通话吗?`,confirmColor:"#eb3349",success:t=>{t.confirm&&(e.index.vibrateShort({type:"heavy"}),e.index.showLoading({title:"正在挂断...",mask:!0}),setTimeout((()=>{e.index.hideLoading(),this.cleanup(),e.index.showToast({title:"通话已结束",icon:"success",duration:1500,success:()=>{setTimeout((()=>{e.index.navigateBack()}),1500)}})}),800))}})},goToRevival(){console.log("[PhoneCall] 跳转到复活照片页面"),e.index.navigateTo({url:"/pages/revival/revival-original",success:()=>{console.log("[PhoneCall] 跳转成功")},fail:e=>{console.error("[PhoneCall] 跳转失败:",e)}})},cleanup(){this.durationTimer&&clearInterval(this.durationTimer),this.audioContext&&this.audioContext.destroy(),this.recorderManager&&this.recorderManager.stop()},formatTime(e){if(!e)return"";let t=e;String(e).length<=10&&(t=1e3*e);const o=new Date(t);if(isNaN(o.getTime()))return"时间格式错误";return`${o.getFullYear()}年${String(o.getMonth()+1).padStart(2,"0")}月${String(o.getDate()).padStart(2,"0")}日 ${String(o.getHours()).padStart(2,"0")}:${String(o.getMinutes()).padStart(2,"0")}`}}};const s=e._export_sfc(i,[["render",function(t,i,s,a,n,l){return e.e({a:e.o(((...e)=>l.goToRevival&&l.goToRevival(...e))),b:!n.callStarted},n.callStarted?e.e({j:n.selectedVideoUrl},n.selectedVideoUrl?{k:n.selectedVideoUrl}:{},{l:e.t(n.selectedVideoName),m:e.t(n.callStatus),n:n.isSpeaking||n.isRecording?1:"",o:e.t(n.callDuration),p:e.f(n.messages,((t,o,i)=>({a:e.t("user"===t.role?"👤":"🤖"),b:e.t(t.content),c:e.t(t.time),d:o,e:e.n(t.role)}))),q:0===n.messages.length},(n.messages.length,{}),{r:n.scrollTop,s:n.selectedVoiceId&&n.selectedVoiceId.startsWith("cosyvoice-v3-plus-")},n.selectedVoiceId&&n.selectedVoiceId.startsWith("cosyvoice-v3-plus-")?{t:e.t(n.selectedDialect||"请选择方言(可选)"),v:n.dialectOptions,w:e.o(((...e)=>l.onDialectChange&&l.onDialectChange(...e)))}:{},{x:n.selectedVoiceId&&n.selectedVoiceId.startsWith("cosyvoice-v3-plus-")},n.selectedVoiceId&&n.selectedVoiceId.startsWith("cosyvoice-v3-plus-")?{y:e.t(n.selectedLanguageHintLabel||"请选择语言(可选)"),z:n.languageHintOptions,A:e.o(((...e)=>l.onLanguageHintChange&&l.onLanguageHintChange(...e)))}:{},{B:!n.isRecording&&!n.isProcessing},n.isRecording||n.isProcessing?{}:{C:e.o(((...e)=>l.startRecording&&l.startRecording(...e))),D:e.o(((...e)=>l.stopRecording&&l.stopRecording(...e)))},{E:n.isRecording},n.isRecording?{F:e.o(((...e)=>l.stopRecording&&l.stopRecording(...e)))}:{},{G:n.isProcessing},n.isProcessing?{H:e.t(n.processingText)}:{},{I:o._imports_0,J:e.o(((...e)=>l.handleClearHistory&&l.handleClearHistory(...e))),K:e.o(((...e)=>l.endCall&&l.endCall(...e)))}):e.e({c:n.loading},n.loading?{}:n.videos.length>0?{e:e.f(n.videos,((t,o,i)=>e.e({a:e.t(t.name||"复活视频"),b:e.t(t.text||"暂无描述"),c:e.t(l.formatTime(t.create_time)),d:n.selectedVideoId===t.id},(n.selectedVideoId,t.id,{}),{e:t.id,f:e.n(n.selectedVideoId===t.id?"selected":""),g:e.o((e=>l.selectVideo(t)),t.id)})))}:{},{d:n.videos.length>0,f:n.videos.length>0},n.videos.length>0?e.e({g:n.selectedVideoId},(n.selectedVideoId,{}),{h:!n.selectedVideoId,i:e.o(((...e)=>l.startCall&&l.startCall(...e)))}):{}),{L:n.showSettingsDialog},n.showSettingsDialog?{M:e.o(((...e)=>l.closeSettingsDialog&&l.closeSettingsDialog(...e))),N:n.dialogMemoryIdentity,O:e.o((e=>n.dialogMemoryIdentity=e.detail.value)),P:n.dialogMemoryInfo,Q:e.o((e=>n.dialogMemoryInfo=e.detail.value)),R:n.dialogMemoryCatchphrase,S:e.o((e=>n.dialogMemoryCatchphrase=e.detail.value)),T:e.o(((...e)=>l.closeSettingsDialog&&l.closeSettingsDialog(...e))),U:e.o(((...e)=>l.confirmSettings&&l.confirmSettings(...e))),V:e.o((()=>{})),W:e.o(((...e)=>l.closeSettingsDialog&&l.closeSettingsDialog(...e)))}:{})}],["__scopeId","data-v-70ab4376"]]);wx.createPage(s); +"use strict";const e=require("../../common/vendor.js"),t=require("../../config/api.js"),o=require("../../common/assets.js"),i={data:()=>({API_BASE:t.API_BASE,lastUserId:null,loading:!1,videos:[],selectedVideoId:"",selectedVideoName:"",selectedVideoUrl:"",selectedVoiceId:"",selectedDialect:"",selectedLanguageHint:"",selectedLanguageHintLabel:"",languageHintOptions:["中文(zh)","英文(en)","法语(fr)","德语(de)","日语(ja)","韩语(ko)","俄语(ru)"],dialectOptions:["广东话","东北话","甘肃话","贵州话","河南话","湖北话","江西话","闽南话","宁夏话","山西话","陕西话","山东话","上海话","四川话","天津话","云南话"],callStarted:!1,callStatus:"视频通话中",callDuration:"00:00",callStartTime:null,durationTimer:null,messages:[],scrollTop:0,isRecording:!1,isProcessing:!1,isSpeaking:!1,processingText:"处理中...",recorderManager:null,audioFilePath:"",audioContext:null,showSettingsDialog:!1,dialogMemoryIdentity:"",dialogMemoryInfo:"",dialogMemoryCatchphrase:""}),onLoad(){console.log("[PhoneCall] 页面加载");const t=e.index.getStorageSync("userId");this.lastUserId=t,this.loadVideos(),this.initRecorder(),this.initAudioContext()},onShow(){console.log("[PhoneCall] 页面显示");const t=e.index.getStorageSync("userId");this.lastUserId=t,this.callStarted||this.$nextTick((()=>{setTimeout((()=>{this.loadVideos()}),100)}))},onUnload(){this.cleanup()},methods:{async loadVideos(){this.loading=!0;const t=e.index.getStorageSync("userId")||"",o=e.index.getStorageSync("token")||"";e.index.request({url:`${this.API_BASE}/api/photo-revival/videos`,method:"GET",header:{"X-User-Id":t,Authorization:o?`Bearer ${o}`:""},success:e=>{if(console.log("[PhoneCall] 视频列表响应状态码:",e.statusCode),console.log("[PhoneCall] 视频列表响应数据:",e.data),console.log("[PhoneCall] 数据类型:",typeof e.data),200===e.statusCode){let t=[];Array.isArray(e.data)?t=e.data:e.data&&Array.isArray(e.data.data)?t=e.data.data:e.data&&e.data.videos&&Array.isArray(e.data.videos)&&(t=e.data.videos),t=t.filter((e=>{const t=e.name&&(e.name.startsWith("生成失败")||e.name.startsWith("生成失败:")),o=e.edited_video_url||e.video_url||e.local_video_path||e.videoUrl||e.localVideoPath,i=o&&""!==o.trim();return!t&&i})),this.videos=t,console.log("[PhoneCall] 加载视频列表成功:",this.videos.length),console.log("[PhoneCall] 视频列表:",this.videos)}else console.error("[PhoneCall] 响应状态码异常:",e.statusCode)},fail:t=>{console.error("[PhoneCall] 加载视频列表失败:",t),e.index.showToast({title:"加载失败",icon:"none"})},complete:()=>{this.loading=!1}})},selectVideo(e){console.log("[PhoneCall] 选择视频:",e),this.selectedVideoId=e.id,this.selectedVideoName=e.name||"复活视频",this.selectedVideoUrl=e.edited_video_url||e.local_video_path||e.video_url,this.selectedVoiceId=e.voice_id,this.selectedDialect="",this.selectedLanguageHint="",this.selectedLanguageHintLabel="",console.log("[PhoneCall] 选择视频:",this.selectedVideoId,"名称:",this.selectedVideoName),console.log("[PhoneCall] 视频URL:",this.selectedVideoUrl)},onDialectChange(e){this.selectedDialect=this.dialectOptions[e.detail.value]||""},onLanguageHintChange(e){const t=this.languageHintOptions[e.detail.value]||"";this.selectedLanguageHintLabel=t;const o=t.match(/\(([^)]+)\)/);this.selectedLanguageHint=o&&o[1]?o[1]:""},startCall(){if(!this.selectedVideoId)return void e.index.showToast({title:"请先选择视频",icon:"none"});console.log("[PhoneCall] 准备视频通话,视频ID:",this.selectedVideoId);const t=this.videos.find((e=>e.id===this.selectedVideoId));if(!t)return void e.index.showToast({title:"视频信息丢失",icon:"none"});const o=t.edited_video_url||t.videoUrl||t.local_video_path||t.video_url||t.localVideoPath||"",i=t.name||"复活视频",s=this.selectedVoiceId||"";console.log("[PhoneCall] 跳转参数:",{videoId:this.selectedVideoId,videoName:i,videoUrl:o,voiceId:s}),e.index.navigateTo({url:`/pages/video-call-new/video-call-new?videoId=${this.selectedVideoId}&videoName=${encodeURIComponent(i)}&videoUrl=${encodeURIComponent(o)}&voiceId=${s}`,success:()=>{console.log("[PhoneCall] 跳转到视频通话页面成功")},fail:t=>{console.error("[PhoneCall] 跳转失败:",t),e.index.showToast({title:"跳转失败",icon:"none"})}})},closeSettingsDialog(){this.showSettingsDialog=!1},confirmSettings(){this.showSettingsDialog=!1},startCallTimer(){this.callStartTime=Date.now(),this.durationTimer=setInterval((()=>{const e=Math.floor((Date.now()-this.callStartTime)/1e3),t=Math.floor(e/60).toString().padStart(2,"0"),o=(e%60).toString().padStart(2,"0");this.callDuration=`${t}:${o}`}),1e3)},initRecorder(){this.recorderManager=e.index.getRecorderManager(),this.recorderManager.onStart((()=>{console.log("[PhoneCall] 开始录音")})),this.recorderManager.onStop((e=>{console.log("[PhoneCall] 录音完成:",e.tempFilePath),this.audioFilePath=e.tempFilePath,this.processConversation()})),this.recorderManager.onError((t=>{console.error("[PhoneCall] 录音失败:",t),this.isRecording=!1,e.index.showToast({title:"录音失败",icon:"none"})}))},initAudioContext(){this.audioContext=e.index.createInnerAudioContext(),this.audioContext.onPlay((()=>{console.log("[PhoneCall] 开始播放AI回复"),this.isSpeaking=!0,this.callStatus="对方正在说话...",e.index.vibrateShort({type:"light"})})),this.audioContext.onEnded((()=>{console.log("[PhoneCall] AI回复播放完成"),this.isSpeaking=!1,this.callStatus="通话中"})),this.audioContext.onError((e=>{console.error("[PhoneCall] 音频播放失败:",e),this.isSpeaking=!1,this.callStatus="通话中"}))},startRecording(){this.isProcessing||(this.isRecording=!0,this.recorderManager.start({format:"mp3",sampleRate:16e3}),this.callStatus="正在录音...",e.index.vibrateShort({type:"medium"}))},stopRecording(){this.isRecording&&(this.isRecording=!1,this.recorderManager.stop(),this.isProcessing=!0,this.processingText="识别中...",this.callStatus="处理中...")},async processConversation(){try{this.processingText="正在识别...";const t=e.index.getStorageSync("userId")||"",o=e.index.getStorageSync("token")||"";e.index.uploadFile({url:`${this.API_BASE}/api/conversation/talk`,filePath:this.audioFilePath,name:"audio",header:{"X-User-Id":t,Authorization:o?`Bearer ${o}`:""},formData:(()=>{const e=this.selectedVoiceId,t=(()=>{const t=(e||"").trim();if(!t)return"CLONE";return["Cherry","Kai","Mochi","Bunny","Jada","Dylan","Li","Marcus","Roy","Peter","Sunny","Eric","Rocky","Kiki"].includes(t)||t.startsWith("BV")||t.endsWith("_streaming")||t.endsWith("_offline")||t.endsWith("_bigtts")?"OFFICIAL":"CLONE"})(),o={voiceId:e,voiceType:t};return this.selectedDialect&&(o.dialect=this.selectedDialect),this.selectedLanguageHint&&(o.languageHints=this.selectedLanguageHint),o})(),success:e=>{if(console.log("[PhoneCall] 对话响应:",e),200!==e.statusCode)throw new Error("对话请求失败");{const t=JSON.parse(e.data);if(!t.success)throw new Error(t.message||"对话失败");this.addMessage("user",t.recognizedText),this.addMessage("ai",t.aiResponse),this.playAIResponse(t.audioFile)}},fail:t=>{console.error("[PhoneCall] 对话失败:",t),e.index.showToast({title:"对话失败",icon:"none"}),this.isProcessing=!1,this.callStatus="通话中"}})}catch(t){console.error("[PhoneCall] 对话失败:",t),e.index.showToast({title:"对话失败: "+t.message,icon:"none"}),this.isProcessing=!1,this.callStatus="通话中"}},playAIResponse(e){this.processingText="正在回复...",this.audioContext.src=`${this.API_BASE}/api/conversation/audio/${e}`,this.audioContext.play(),this.isProcessing=!1},addMessage(e,t){const o=new Date,i=`${o.getHours()}:${o.getMinutes().toString().padStart(2,"0")}`;this.messages.push({role:e,content:t,time:i}),this.$nextTick((()=>{this.scrollTop=999999}))},handleClearHistory(){e.index.showModal({title:"确认清空",content:"确定要清空对话历史吗?",success:t=>{if(t.confirm){const t=e.index.getStorageSync("userId")||"",o=e.index.getStorageSync("token")||"";e.index.request({url:`${this.API_BASE}/api/conversation/clear-history`,method:"POST",header:{"X-User-Id":t,Authorization:o?`Bearer ${o}`:""},success:t=>{t.data.success&&(this.messages=[],e.index.showToast({title:"已清空",icon:"success"}))}})}}})},endCall(){e.index.showModal({title:"结束通话",content:`通话时长:${this.callDuration}\n确定要结束通话吗?`,confirmColor:"#eb3349",success:t=>{t.confirm&&(e.index.vibrateShort({type:"heavy"}),e.index.showLoading({title:"正在挂断...",mask:!0}),setTimeout((()=>{e.index.hideLoading(),this.cleanup(),e.index.showToast({title:"通话已结束",icon:"success",duration:1500,success:()=>{setTimeout((()=>{e.index.navigateBack()}),1500)}})}),800))}})},goToRevival(){console.log("[PhoneCall] 跳转到复活照片页面"),e.index.navigateTo({url:"/pages/revival/revival-original",success:()=>{console.log("[PhoneCall] 跳转成功")},fail:e=>{console.error("[PhoneCall] 跳转失败:",e)}})},cleanup(){this.durationTimer&&clearInterval(this.durationTimer),this.audioContext&&this.audioContext.destroy(),this.recorderManager&&this.recorderManager.stop()},formatTime(e){if(!e)return"";let t=e;String(e).length<=10&&(t=1e3*e);const o=new Date(t);if(isNaN(o.getTime()))return"时间格式错误";return`${o.getFullYear()}年${String(o.getMonth()+1).padStart(2,"0")}月${String(o.getDate()).padStart(2,"0")}日 ${String(o.getHours()).padStart(2,"0")}:${String(o.getMinutes()).padStart(2,"0")}`}}};const s=e._export_sfc(i,[["render",function(t,i,s,a,n,l){return e.e({a:e.o(((...e)=>l.goToRevival&&l.goToRevival(...e))),b:!n.callStarted},n.callStarted?e.e({k:n.selectedVideoUrl},n.selectedVideoUrl?{l:n.selectedVideoUrl}:{},{m:!n.selectedVideoUrl},(n.selectedVideoUrl,{}),{n:e.t(n.selectedVideoName),o:e.t(n.callStatus),p:n.isSpeaking||n.isRecording?1:"",q:e.t(n.callDuration),r:e.f(n.messages,((t,o,i)=>({a:e.t("user"===t.role?"👤":"🤖"),b:e.t(t.content),c:e.t(t.time),d:o,e:e.n(t.role)}))),s:0===n.messages.length},(n.messages.length,{}),{t:n.scrollTop,v:n.selectedVoiceId&&n.selectedVoiceId.startsWith("cosyvoice-v3-plus-")},n.selectedVoiceId&&n.selectedVoiceId.startsWith("cosyvoice-v3-plus-")?{w:e.t(n.selectedDialect||"请选择方言(可选)"),x:n.dialectOptions,y:e.o(((...e)=>l.onDialectChange&&l.onDialectChange(...e)))}:{},{z:n.selectedVoiceId&&n.selectedVoiceId.startsWith("cosyvoice-v3-plus-")},n.selectedVoiceId&&n.selectedVoiceId.startsWith("cosyvoice-v3-plus-")?{A:e.t(n.selectedLanguageHintLabel||"请选择语言(可选)"),B:n.languageHintOptions,C:e.o(((...e)=>l.onLanguageHintChange&&l.onLanguageHintChange(...e)))}:{},{D:!n.isRecording&&!n.isProcessing},n.isRecording||n.isProcessing?{}:{E:e.o(((...e)=>l.startRecording&&l.startRecording(...e))),F:e.o(((...e)=>l.stopRecording&&l.stopRecording(...e)))},{G:n.isRecording},n.isRecording?{H:e.o(((...e)=>l.stopRecording&&l.stopRecording(...e)))}:{},{I:n.isProcessing},n.isProcessing?{J:e.t(n.processingText)}:{},{K:o._imports_0,L:e.o(((...e)=>l.handleClearHistory&&l.handleClearHistory(...e))),M:e.o(((...e)=>l.endCall&&l.endCall(...e)))}):e.e({c:n.loading},n.loading?{}:n.videos.length>0?{e:e.f(n.videos,((t,o,i)=>e.e({a:e.t(t.name||"复活视频"),b:e.t(t.text||"暂无描述"),c:e.t(l.formatTime(t.create_time)),d:n.selectedVideoId===t.id},(n.selectedVideoId,t.id,{}),{e:t.id,f:e.n(n.selectedVideoId===t.id?"selected":""),g:e.o((e=>l.selectVideo(t)),t.id)})))}:{},{d:n.videos.length>0,f:n.videos.length>0},n.videos.length>0?e.e({g:n.selectedVideoId},(n.selectedVideoId,{}),{h:!n.selectedVideoId,i:e.o(((...e)=>l.startCall&&l.startCall(...e)))}):{},{j:n.videos.length>0},(n.videos.length,{})),{N:n.showSettingsDialog},n.showSettingsDialog?{O:e.o(((...e)=>l.closeSettingsDialog&&l.closeSettingsDialog(...e))),P:n.dialogMemoryIdentity,Q:e.o((e=>n.dialogMemoryIdentity=e.detail.value)),R:n.dialogMemoryInfo,S:e.o((e=>n.dialogMemoryInfo=e.detail.value)),T:n.dialogMemoryCatchphrase,U:e.o((e=>n.dialogMemoryCatchphrase=e.detail.value)),V:e.o(((...e)=>l.closeSettingsDialog&&l.closeSettingsDialog(...e))),W:e.o(((...e)=>l.confirmSettings&&l.confirmSettings(...e))),X:e.o((()=>{})),Y:e.o(((...e)=>l.closeSettingsDialog&&l.closeSettingsDialog(...e)))}:{})}],["__scopeId","data-v-a48cd222"]]);wx.createPage(s); diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/phone-call/phone-call.wxml b/frontend-ai/unpackage/dist/build/mp-weixin/pages/phone-call/phone-call.wxml index bdffbe1..267c0c1 100644 --- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/phone-call/phone-call.wxml +++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/phone-call/phone-call.wxml @@ -1 +1 @@ -🎬 选择复活视频选择一个已生成的复活视频开始视频通话⏳ 加载视频列表...🎬{{video.a}}{{video.b}}{{video.c}}🎬暂无复活视频请先点击上方"复活照片"生成视频🎬视频加载中...{{l}}{{m}}{{o}}{{msg.a}}{{msg.b}}{{msg.c}}💬按住下方按钮开始说话方言{{t}}语言提示(可选){{y}}💡 仅处理第一个值;不设置不生效💭 通话设置设置对话记忆,让AI更真实地模拟对方身份性格特点{{j}}/500⏱️ 视频时长{{d.a}}秒 📝 视频名称(可选){{r}}✅ 生成成功💡 使用提示• 支持 JPG、PNG 格式的照片• 提示词支持中文,可描述动作、表情、场景等• 视频时长支持 2-12 秒• 生成时间约 1-3 分钟,请耐心等待• 使用火山引擎 doubao-seedance-1.0-pro 模型 \ No newline at end of file +🎬 AI图生视频火山引擎 · doubao-seedance-1.0-pro{{b}}📸 上传照片📷点击上传照片支持 JPG、PNG 格式✍️ 提示词(可选){{j}}/500⏱️ 视频时长{{d.a}}秒 📝 视频名称(可选)本服务为AI生成内容,结果仅供参考{{r}}✅ 生成成功AI生成💡 使用提示• 支持 JPG、PNG 格式的照片• 提示词支持中文,可描述动作、表情、场景等• 视频时长支持 2-12 秒• 生成时间约 1-3 分钟,请耐心等待• 使用火山引擎 doubao-seedance-1.0-pro 模型 \ No newline at end of file diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-gen/video-gen.wxss b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-gen/video-gen.wxss index 7762d57..1eda904 100644 --- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-gen/video-gen.wxss +++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-gen/video-gen.wxss @@ -1 +1 @@ -.video-gen-page.data-v-2ed74c00{min-height:100vh;background:linear-gradient(135deg,#667eea,#764ba2);padding:20rpx}.header.data-v-2ed74c00{text-align:center;padding:40rpx 20rpx;color:#fff}.title.data-v-2ed74c00{font-size:48rpx;font-weight:700;display:block;margin-bottom:10rpx}.subtitle.data-v-2ed74c00{font-size:28rpx;opacity:.9}.message.data-v-2ed74c00{margin:20rpx;padding:20rpx;border-radius:10rpx;text-align:center;font-size:28rpx}.message.success.data-v-2ed74c00{background:#d4edda;color:#155724}.message.error.data-v-2ed74c00{background:#f8d7da;color:#721c24}.message.info.data-v-2ed74c00{background:#d1ecf1;color:#0c5460}.content.data-v-2ed74c00{height:calc(100vh - 200rpx);padding:20rpx}.section.data-v-2ed74c00{background:#fff;border-radius:20rpx;padding:30rpx;margin-bottom:20rpx}.section-title.data-v-2ed74c00{font-size:32rpx;font-weight:700;margin-bottom:20rpx;color:#333}.upload-area.data-v-2ed74c00{border:2rpx dashed #ddd;border-radius:15rpx;min-height:400rpx;display:flex;align-items:center;justify-content:center;background:#f8f9fa}.upload-placeholder.data-v-2ed74c00{text-align:center}.upload-icon.data-v-2ed74c00{font-size:80rpx;display:block;margin-bottom:20rpx}.upload-text.data-v-2ed74c00{font-size:32rpx;color:#666;display:block;margin-bottom:10rpx}.upload-hint.data-v-2ed74c00{font-size:24rpx;color:#999}.preview-image.data-v-2ed74c00{width:100%;max-height:400rpx;border-radius:15rpx}.prompt-input.data-v-2ed74c00{width:100%;min-height:200rpx;padding:20rpx;border:1rpx solid #e0e0e0;border-radius:10rpx;font-size:28rpx;background:#f8f9fa}.char-count.data-v-2ed74c00{text-align:right;font-size:24rpx;color:#999;margin-top:10rpx}.duration-selector.data-v-2ed74c00{display:flex;flex-wrap:wrap;gap:15rpx}.duration-item.data-v-2ed74c00{flex:0 0 calc(25% - 12rpx);padding:20rpx;text-align:center;border:2rpx solid #e0e0e0;border-radius:10rpx;font-size:28rpx;background:#f8f9fa}.duration-item.active.data-v-2ed74c00{background:#667eea;color:#fff;border-color:#667eea}.name-input.data-v-2ed74c00{width:100%;padding:20rpx;border:1rpx solid #e0e0e0;border-radius:10rpx;font-size:28rpx;background:#f8f9fa}.action-section.data-v-2ed74c00{padding:0 20rpx;margin-bottom:20rpx}.generate-btn.data-v-2ed74c00{width:100%;padding:30rpx;background:linear-gradient(135deg,#667eea,#764ba2);color:#fff;border:none;border-radius:15rpx;font-size:32rpx;font-weight:700}.generate-btn[disabled].data-v-2ed74c00{opacity:.6}.progress-section.data-v-2ed74c00{background:#fff;border-radius:20rpx;padding:30rpx;margin:0 20rpx 20rpx}.progress-text.data-v-2ed74c00{text-align:center;font-size:28rpx;color:#666;margin-bottom:20rpx}.progress-bar.data-v-2ed74c00{height:20rpx;background:#e0e0e0;border-radius:10rpx;overflow:hidden}.progress-fill.data-v-2ed74c00{height:100%;background:linear-gradient(90deg,#667eea,#764ba2);transition:width .3s}.result-section.data-v-2ed74c00{background:#fff;border-radius:20rpx;padding:30rpx;margin:0 20rpx 20rpx}.result-video.data-v-2ed74c00{width:100%;height:500rpx;border-radius:15rpx;margin:20rpx 0}.result-actions.data-v-2ed74c00{display:flex;gap:20rpx}.action-btn.data-v-2ed74c00{flex:1;padding:25rpx;background:#667eea;color:#fff;border:none;border-radius:10rpx;font-size:28rpx}.action-btn.secondary.data-v-2ed74c00{background:#6c757d}.tips-section.data-v-2ed74c00{background:rgba(255,255,255,.95);border-radius:20rpx;padding:30rpx;margin:0 20rpx 40rpx}.tips-title.data-v-2ed74c00{font-size:32rpx;font-weight:700;margin-bottom:20rpx;color:#333}.tip-item.data-v-2ed74c00{font-size:26rpx;color:#666;line-height:1.8;margin-bottom:10rpx} +.video-gen-page.data-v-041223dc{min-height:100vh;background:linear-gradient(135deg,#667eea,#764ba2);padding:20rpx}.header.data-v-041223dc{text-align:center;padding:40rpx 20rpx;color:#fff}.title.data-v-041223dc{font-size:48rpx;font-weight:700;display:block;margin-bottom:10rpx}.subtitle.data-v-041223dc{font-size:28rpx;opacity:.9}.message.data-v-041223dc{margin:20rpx;padding:20rpx;border-radius:10rpx;text-align:center;font-size:28rpx}.message.success.data-v-041223dc{background:#d4edda;color:#155724}.message.error.data-v-041223dc{background:#f8d7da;color:#721c24}.message.info.data-v-041223dc{background:#d1ecf1;color:#0c5460}.content.data-v-041223dc{height:calc(100vh - 200rpx);padding:20rpx}.section.data-v-041223dc{background:#fff;border-radius:20rpx;padding:30rpx;margin-bottom:20rpx}.section-title.data-v-041223dc{font-size:32rpx;font-weight:700;margin-bottom:20rpx;color:#333}.upload-area.data-v-041223dc{border:2rpx dashed #ddd;border-radius:15rpx;min-height:400rpx;display:flex;align-items:center;justify-content:center;background:#f8f9fa}.upload-placeholder.data-v-041223dc{text-align:center}.upload-icon.data-v-041223dc{font-size:80rpx;display:block;margin-bottom:20rpx}.upload-text.data-v-041223dc{font-size:32rpx;color:#666;display:block;margin-bottom:10rpx}.upload-hint.data-v-041223dc{font-size:24rpx;color:#999}.preview-image.data-v-041223dc{width:100%;max-height:400rpx;border-radius:15rpx}.prompt-input.data-v-041223dc{width:100%;min-height:200rpx;padding:20rpx;border:1rpx solid #e0e0e0;border-radius:10rpx;font-size:28rpx;background:#f8f9fa}.char-count.data-v-041223dc{text-align:right;font-size:24rpx;color:#999;margin-top:10rpx}.duration-selector.data-v-041223dc{display:flex;flex-wrap:wrap;gap:15rpx}.duration-item.data-v-041223dc{flex:0 0 calc(25% - 12rpx);padding:20rpx;text-align:center;border:2rpx solid #e0e0e0;border-radius:10rpx;font-size:28rpx;background:#f8f9fa}.duration-item.active.data-v-041223dc{background:#667eea;color:#fff;border-color:#667eea}.name-input.data-v-041223dc{width:100%;padding:20rpx;border:1rpx solid #e0e0e0;border-radius:10rpx;font-size:28rpx;background:#f8f9fa}.action-section.data-v-041223dc{padding:0 20rpx;margin-bottom:20rpx}.generate-btn.data-v-041223dc{width:100%;padding:30rpx;background:linear-gradient(135deg,#667eea,#764ba2);color:#fff!important;border:none;border-radius:15rpx;font-size:32rpx;font-weight:700}.generate-btn[disabled].data-v-041223dc{opacity:.6;color:#fff!important}.ai-disclaimer.data-v-041223dc{display:block;text-align:center;font-size:22rpx;color:rgba(100,100,100,.6);margin-top:16rpx;letter-spacing:.5rpx}.progress-section.data-v-041223dc{background:#fff;border-radius:20rpx;padding:30rpx;margin:0 20rpx 20rpx}.progress-text.data-v-041223dc{text-align:center;font-size:28rpx;color:#666;margin-bottom:20rpx}.progress-bar.data-v-041223dc{height:20rpx;background:#e0e0e0;border-radius:10rpx;overflow:hidden}.progress-fill.data-v-041223dc{height:100%;background:linear-gradient(90deg,#667eea,#764ba2);transition:width .3s}.result-section.data-v-041223dc{background:#fff;border-radius:20rpx;padding:30rpx;margin:0 20rpx 20rpx}.result-section.data-v-041223dc{position:relative}.video-container.data-v-041223dc{position:relative;width:100%;height:500rpx;border-radius:15rpx;overflow:hidden;margin:20rpx 0}.result-video.data-v-041223dc{width:100%;height:100%;border-radius:15rpx}.ai-tag.data-v-041223dc{position:absolute;top:16rpx;right:16rpx;z-index:100;background:rgba(0,0,0,.6);padding:8rpx 20rpx;border-radius:30rpx;-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx)}.ai-tag-text.data-v-041223dc{font-size:22rpx;color:#fff;font-weight:500}.result-actions.data-v-041223dc{display:flex;gap:20rpx}.action-btn.data-v-041223dc{flex:1;padding:25rpx;background:#667eea;color:#fff;border:none;border-radius:10rpx;font-size:28rpx}.action-btn.secondary.data-v-041223dc{background:#6c757d}.tips-section.data-v-041223dc{background:rgba(255,255,255,.95);border-radius:20rpx;padding:30rpx;margin:0 20rpx 40rpx}.tips-title.data-v-041223dc{font-size:32rpx;font-weight:700;margin-bottom:20rpx;color:#333}.tip-item.data-v-041223dc{font-size:26rpx;color:#666;line-height:1.8;margin-bottom:10rpx} diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-player/video-player.js b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-player/video-player.js index f021743..b53dc19 100644 --- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-player/video-player.js +++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-player/video-player.js @@ -1 +1 @@ -"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{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{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{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{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-d19743cf"]]);wx.createPage(o); +"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{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{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{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{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); diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-player/video-player.wxml b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-player/video-player.wxml index f525620..885d2da 100644 --- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-player/video-player.wxml +++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-player/video-player.wxml @@ -1 +1 @@ -← 返回{{b}}⚠️视频加载失败{{d}}重新加载返回{{h}}{{j}} \ No newline at end of file +← 返回{{b}}⚠️视频加载失败{{d}}重新加载返回{{h}}{{j}}AI生成 \ No newline at end of file diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-player/video-player.wxss b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-player/video-player.wxss index 074c329..5754827 100644 --- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-player/video-player.wxss +++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-player/video-player.wxss @@ -1 +1 @@ -.player-container.data-v-d19743cf{width:100%;height:100vh;background:#000;display:flex;flex-direction:column;position:relative}.loading-overlay.data-v-d19743cf{position:absolute;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.8);display:flex;align-items:center;justify-content:center;z-index:999}.loading-content.data-v-d19743cf{text-align:center;display:flex;flex-direction:column;align-items:center;gap:20rpx}.loading-spinner.data-v-d19743cf{width:80rpx;height:80rpx;border:6rpx solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:spin-d19743cf 1s linear infinite}@keyframes spin-d19743cf{to{transform:rotate(360deg)}}.loading-text.data-v-d19743cf{color:#fff;font-size:32rpx;font-weight:700}.loading-hint.data-v-d19743cf{color:rgba(255,255,255,.7);font-size:24rpx;margin-top:10rpx}.progress-bar.data-v-d19743cf{width:400rpx;height:8rpx;background:rgba(255,255,255,.2);border-radius:4rpx;overflow:hidden;margin-top:20rpx}.progress-fill.data-v-d19743cf{height:100%;background:linear-gradient(90deg,#667eea,#764ba2);border-radius:4rpx;transition:width .3s ease}.header.data-v-d19743cf{background:rgba(0,0,0,.8);padding:60rpx 40rpx 20rpx;padding-top:calc(60rpx + constant(safe-area-inset-top));padding-top:calc(60rpx + env(safe-area-inset-top));display:flex;justify-content:space-between;align-items:center;color:#fff;position:absolute;top:0;left:0;right:0;z-index:100}.back-btn.data-v-d19743cf{font-size:32rpx;padding:16rpx;cursor:pointer}.title.data-v-d19743cf{font-size:32rpx;font-weight:700;flex:1;text-align:center}.placeholder.data-v-d19743cf{width:80rpx}.video-player.data-v-d19743cf{width:100%;height:100vh;background:#000}.play-overlay.data-v-d19743cf{position:absolute;top:0;left:0;right:0;bottom:0;z-index:50;display:flex;align-items:center;justify-content:center}.play-button.data-v-d19743cf{width:140rpx;height:140rpx;border-radius:999rpx;background:rgba(0,0,0,.45);position:relative}.play-button.data-v-d19743cf:after{content:"";position:absolute;top:50%;left:54%;transform:translate(-50%,-50%);width:0;height:0;border-top:22rpx solid transparent;border-bottom:22rpx solid transparent;border-left:34rpx solid #fff}.error-overlay.data-v-d19743cf{position:absolute;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.95);display:flex;align-items:center;justify-content:center;z-index:1000}.error-content.data-v-d19743cf{text-align:center;padding:60rpx;display:flex;flex-direction:column;align-items:center;gap:24rpx}.error-icon.data-v-d19743cf{font-size:120rpx;margin-bottom:20rpx}.error-title.data-v-d19743cf{color:#fff;font-size:36rpx;font-weight:700}.error-message.data-v-d19743cf{color:rgba(255,255,255,.7);font-size:28rpx;line-height:1.6}.error-actions.data-v-d19743cf{display:flex;gap:24rpx;margin-top:40rpx}.error-btn.data-v-d19743cf{padding:24rpx 48rpx;border-radius:12rpx;font-size:28rpx;cursor:pointer;transition:all .3s ease}.retry-btn.data-v-d19743cf{background:linear-gradient(135deg,#667eea,#764ba2);color:#fff}.retry-btn.data-v-d19743cf:active{transform:scale(.95);opacity:.8}.back-btn-error.data-v-d19743cf{background:rgba(255,255,255,.1);color:#fff;border:2rpx solid rgba(255,255,255,.3)}.back-btn-error.data-v-d19743cf:active{transform:scale(.95);background:rgba(255,255,255,.15)} +.player-container.data-v-60f68b50{width:100%;height:100vh;background:#000;display:flex;flex-direction:column;position:relative}.loading-overlay.data-v-60f68b50{position:absolute;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.8);display:flex;align-items:center;justify-content:center;z-index:999}.loading-content.data-v-60f68b50{text-align:center;display:flex;flex-direction:column;align-items:center;gap:20rpx}.loading-spinner.data-v-60f68b50{width:80rpx;height:80rpx;border:6rpx solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:spin-60f68b50 1s linear infinite}@keyframes spin-60f68b50{to{transform:rotate(360deg)}}.loading-text.data-v-60f68b50{color:#fff;font-size:32rpx;font-weight:700}.loading-hint.data-v-60f68b50{color:rgba(255,255,255,.7);font-size:24rpx;margin-top:10rpx}.progress-bar.data-v-60f68b50{width:400rpx;height:8rpx;background:rgba(255,255,255,.2);border-radius:4rpx;overflow:hidden;margin-top:20rpx}.progress-fill.data-v-60f68b50{height:100%;background:linear-gradient(90deg,#667eea,#764ba2);border-radius:4rpx;transition:width .3s ease}.header.data-v-60f68b50{background:rgba(0,0,0,.8);padding:60rpx 40rpx 20rpx;padding-top:calc(60rpx + constant(safe-area-inset-top));padding-top:calc(60rpx + env(safe-area-inset-top));display:flex;justify-content:space-between;align-items:center;color:#fff;position:absolute;top:0;left:0;right:0;z-index:100}.back-btn.data-v-60f68b50{font-size:32rpx;padding:16rpx;cursor:pointer}.title.data-v-60f68b50{font-size:32rpx;font-weight:700;flex:1;text-align:center}.placeholder.data-v-60f68b50{width:80rpx}.video-player.data-v-60f68b50{width:100%;height:100vh;background:#000}.play-overlay.data-v-60f68b50{position:absolute;top:0;left:0;right:0;bottom:0;z-index:50;display:flex;align-items:center;justify-content:center}.play-button.data-v-60f68b50{width:140rpx;height:140rpx;border-radius:999rpx;background:rgba(0,0,0,.45);position:relative}.play-button.data-v-60f68b50:after{content:"";position:absolute;top:50%;left:54%;transform:translate(-50%,-50%);width:0;height:0;border-top:22rpx solid transparent;border-bottom:22rpx solid transparent;border-left:34rpx solid #fff}.error-overlay.data-v-60f68b50{position:absolute;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.95);display:flex;align-items:center;justify-content:center;z-index:1000}.error-content.data-v-60f68b50{text-align:center;padding:60rpx;display:flex;flex-direction:column;align-items:center;gap:24rpx}.error-icon.data-v-60f68b50{font-size:120rpx;margin-bottom:20rpx}.error-title.data-v-60f68b50{color:#fff;font-size:36rpx;font-weight:700}.error-message.data-v-60f68b50{color:rgba(255,255,255,.7);font-size:28rpx;line-height:1.6}.error-actions.data-v-60f68b50{display:flex;gap:24rpx;margin-top:40rpx}.error-btn.data-v-60f68b50{padding:24rpx 48rpx;border-radius:12rpx;font-size:28rpx;cursor:pointer;transition:all .3s ease}.retry-btn.data-v-60f68b50{background:linear-gradient(135deg,#667eea,#764ba2);color:#fff}.retry-btn.data-v-60f68b50:active{transform:scale(.95);opacity:.8}.back-btn-error.data-v-60f68b50{background:rgba(255,255,255,.1);color:#fff;border:2rpx solid rgba(255,255,255,.3)}.back-btn-error.data-v-60f68b50:active{transform:scale(.95);background:rgba(255,255,255,.15)}.ai-tag.data-v-60f68b50{position:absolute;top:140rpx;right:24rpx;z-index:100;background:rgba(0,0,0,.6);padding:8rpx 20rpx;border-radius:30rpx;-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx)}.ai-tag-text.data-v-60f68b50{font-size:22rpx;color:#fff;font-weight:500} diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/project.private.config.json b/frontend-ai/unpackage/dist/build/mp-weixin/project.private.config.json index 2941c87..132e29a 100644 --- a/frontend-ai/unpackage/dist/build/mp-weixin/project.private.config.json +++ b/frontend-ai/unpackage/dist/build/mp-weixin/project.private.config.json @@ -1,6 +1,6 @@ { "libVersion": "3.12.1", - "projectname": "mp-weixin", + "projectname": "frontend-ai", "setting": { "urlCheck": true, "coverView": true,