/* Native video + text, styled and contained by the existing detail panel. */ (function(){ 'use strict'; const base=new URL('../',document.currentScript.src).pathname; const text=(value,max=2000)=>typeof value==='string'?value.trim().slice(0,max):''; const time=value=>{const n=Math.max(0,Math.floor(Number(value)||0));return Math.floor(n/60)+':'+String(n%60).padStart(2,'0');}; function node(tag,cls,value){const e=document.createElement(tag);if(cls)e.className=cls;if(value)e.textContent=value;return e;} function release(container){ for(const video of container.querySelectorAll('video[data-library-preview]')){ video.previewDisposed=true;video.pause();video.removeAttribute('src');video.load(); } } function render(container,data,{match={},startTime,autoplay=false,canPlay=()=>true}={}){ const card=node('article','detail-card video-detail-card'); const title=text(data.title,200)||'视频预览'; const project=text(data.project_name,160)||text(match.title,160).replace(/^待归类\s*[·::]\s*/,''); card.append(node('span','kicker','视频资料 · '+time(data.duration)),node('h3','',title)); if(project&&project!==title)card.append(node('p','video-detail-project',project)); const player=node('div','video-detail-player'),video=node('video','video-detail-media'); video.dataset.libraryPreview=String(data.video_id);video.controls=true;video.playsInline=true; video.preload='metadata';video.setAttribute('controlsList','nodownload');video.setAttribute('aria-label',title); if(data.thumbnail_url)video.poster=new URL(base+data.thumbnail_url,location.origin).href; const status=node('p','video-detail-status','正在加载视频…');status.setAttribute('role','status'); const retry=node('button','text-link','重新加载视频');retry.type='button';retry.hidden=true; const actions=node('div','video-detail-actions'); const clip=node('button','text-link',''),all=node('button','text-link','从头播放'); clip.type=all.type='button'; let desired=Number(startTime??data.start_time)||0,wantsPlay=autoplay,failed=false; desired=Number.isFinite(desired)?Math.max(0,desired):0; const matchStart=desired;clip.textContent='播放匹配片段 · '+time(matchStart); const valid=()=>video.isConnected&&!video.previewDisposed; function play(){ if(!valid()||!canPlay())return; window.NewsBroadcast?.stop(); Promise.resolve(video.play()).catch(error=>{ if(!valid()||error.name==='AbortError')return; if(error.name==='NotAllowedError')status.textContent='视频已就绪,点击播放按钮开始。'; else{failed=true;status.textContent='视频暂时无法播放,可以重新加载。';retry.hidden=false;} }); } function seek(){ const max=Number.isFinite(video.duration)?Math.max(0,video.duration-.05):desired; try{video.currentTime=Math.min(desired,max);}catch{} } function jump(value){ desired=value;wantsPlay=true; if(failed){failed=false;retry.hidden=true;status.textContent='正在重新加载视频…';video.load();} else if(video.readyState>=1){seek();play();} } video.addEventListener('loadedmetadata',()=>{ if(!valid())return;seek();status.textContent=matchStart?'已定位到 '+time(matchStart)+',可播放或全屏观看。':'视频已就绪,可播放或全屏观看。'; if(wantsPlay)play(); }); video.addEventListener('playing',()=>{if(!valid()||!canPlay()){video.pause();return;}failed=false;retry.hidden=true;status.textContent='正在播放';}); video.addEventListener('waiting',()=>{if(valid()&&!failed)status.textContent='正在缓冲…';}); video.addEventListener('pause',()=>{if(valid()&&!failed&&video.readyState>=1&&!video.ended)status.textContent='已暂停';}); video.addEventListener('ended',()=>{if(valid())status.textContent='播放完毕,可重播或选择其他视频。';}); video.addEventListener('error',()=>{if(valid()){failed=true;status.textContent='视频暂时无法播放,可以重新加载。';retry.hidden=false;video.removeAttribute('poster');}}); clip.addEventListener('click',()=>jump(matchStart));all.addEventListener('click',()=>jump(0)); retry.addEventListener('click',()=>{failed=false;retry.hidden=true;wantsPlay=true;status.textContent='正在重新加载视频…';video.load();}); video.src=new URL(base+data.preview_url,location.origin).href; player.append(video);actions.append(clip,all); card.append(player,status,actions,retry); const description=text(data.description)||text(match.summary)||text(match.evidence); card.append(node('h4','','内容介绍'),node('p','body-text',description||'暂无文字介绍,可通过视频了解现场内容。')); const evidence=text(match.evidence),limitation=text(match.limitation); if(evidence&&evidence!==description)card.append(node('h4','','匹配依据'),node('p','body-text',evidence)); if(limitation)card.append(node('p','video-detail-note',limitation)); else card.append(node('p','video-detail-note',data.download_allowed?'公开视频预览':'可公开预览 · 原片未开放下载')); container.append(card); return video; } window.VideoDetail={render,release,time}; })();