Skip to content

Commit c01cf75

Browse files
committed
Upload 观影.html
1 parent d21c897 commit c01cf75

1 file changed

Lines changed: 53 additions & 0 deletions

File tree

‎观影.html‎

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<!doctype html>
2+
<html lang="zh-CN">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
6+
<title>观影 WebHome</title>
7+
<style>
8+
:root{--text:#f7fbff;--muted:rgba(247,251,255,.68);--line:rgba(255,255,255,.16);--soft:rgba(42,50,58,.44);--panel:rgba(42,50,58,.62);--accent:#ff6b35;--accent2:#ffb86b;--radius:18px}*{box-sizing:border-box}html,body{margin:0;min-height:100%;background:transparent;color:var(--text);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Microsoft YaHei",Arial,sans-serif}html:not(.fm-native),html:not(.fm-native) body{background:#222a32}.app{min-height:100vh;padding:10px 10px 34px}.bar{display:flex;align-items:center;gap:8px}.brand{font-size:21px;font-weight:900;white-space:nowrap}.brand b{color:var(--accent2)}.search{flex:1;display:flex;gap:8px;align-items:center;background:rgba(255,255,255,.10);border:1px solid rgba(255,255,255,.14);border-radius:999px;padding:6px 7px 6px 13px}.search input{flex:1;min-width:0;background:transparent;border:0;outline:0;color:var(--text);font-size:15px}.search button,.btn{border:1px solid var(--line);background:var(--soft);color:var(--text);border-radius:999px;padding:8px 12px;font-size:14px;cursor:pointer}.search button,.primary{border-color:rgba(255,107,53,.45);background:linear-gradient(135deg,rgba(255,107,53,.9),rgba(255,184,107,.72));color:#17110d;font-weight:800}.tabs{display:flex;gap:8px;overflow:auto;padding:10px 2px 0;scrollbar-width:none}.tabs::-webkit-scrollbar{display:none}.tab{white-space:nowrap;border-radius:999px;padding:8px 14px;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.12);color:var(--muted)}.tab.active{background:linear-gradient(135deg,rgba(255,107,53,.55),rgba(255,184,107,.3));color:var(--text);border-color:rgba(255,184,107,.58);font-weight:800}.status{margin:10px 2px;color:var(--muted);font-size:14px}.grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px}.card{border-radius:15px;overflow:hidden;background:linear-gradient(180deg,rgba(255,255,255,.09),rgba(255,255,255,.045));border:1px solid rgba(255,255,255,.12);cursor:pointer}.poster{aspect-ratio:3/4;background:rgba(255,255,255,.08);position:relative}.poster img{width:100%;height:100%;object-fit:cover;display:block}.poster .noimg{height:100%;display:grid;place-items:center;color:var(--muted);font-size:28px}.badge{position:absolute;right:7px;top:7px;padding:3px 8px;border-radius:999px;background:rgba(0,0,0,.58);font-size:11px;font-weight:800}.meta{padding:8px 8px 10px}.name{font-weight:800;font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.remark{margin-top:4px;color:var(--muted);font-size:11px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.sheet{position:fixed;inset:0;z-index:40;display:none;background:transparent;overflow:auto;padding:12px}.sheet.active{display:block}.panel{background:linear-gradient(135deg,rgba(64,35,30,.72),rgba(30,24,24,.58));border:1px solid rgba(255,255,255,.10);border-radius:22px;padding:16px 12px 24px;margin-bottom:42px}.head{display:grid;grid-template-columns:38% 1fr;gap:14px}.pic{width:100%;aspect-ratio:3/4;object-fit:cover;border-radius:16px;background:rgba(255,255,255,.08)}.title{font-size:22px;font-weight:700;line-height:1.25;margin:0 0 8px}.info{font-size:14px;line-height:1.65;color:rgba(255,255,255,.75);max-height:230px;overflow:hidden}.pill{display:inline-block;margin:18px 0 10px;padding:8px 18px;border-radius:999px;background:rgba(255,255,255,.10);border:1px solid rgba(255,184,107,.55);font-size:15px;font-weight:800}.desc{font-size:15px;line-height:1.75;color:rgba(255,255,255,.72)}.line-tabs{display:flex;gap:8px;overflow:auto;margin:8px 0 10px}.line-tab{white-space:nowrap;border-radius:999px;padding:8px 12px;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.14);color:rgba(255,255,255,.82)}.line-tab.active{background:rgba(255,107,53,.36);border-color:rgba(255,184,107,.55);font-weight:800}.eps{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:9px}.ep{border-radius:12px;padding:10px 5px;background:rgba(255,255,255,.09);border:1px solid rgba(255,255,255,.14);color:rgba(255,255,255,.9);font-size:13px;text-align:center;min-height:42px}.empty{padding:34px 18px;text-align:center;color:var(--muted);background:var(--soft);border:1px dashed var(--line);border-radius:var(--radius)}.pager{display:flex;gap:8px;justify-content:center;margin:14px 0}.pager button{padding:8px 16px;border-radius:999px;background:rgba(255,255,255,.08);border:1px solid var(--line);color:var(--text)}.mask{position:fixed;inset:0;z-index:70;display:none;background:rgba(0,0,0,.35);padding:18px}.mask.active{display:grid;place-items:center}.cfg{width:min(560px,100%);background:rgba(35,42,50,.95);border:1px solid var(--line);border-radius:20px;padding:16px}.field{width:100%;min-height:42px;border-radius:12px;border:1px solid var(--line);background:rgba(255,255,255,.08);color:var(--text);padding:8px 10px;outline:0}@media(min-width:720px){.grid{grid-template-columns:repeat(5,minmax(0,1fr))}.app{padding:18px 28px 44px}.head{grid-template-columns:180px 1fr}.pic{width:180px}.eps{grid-template-columns:repeat(5,minmax(0,1fr))}}@media(min-width:1100px){.grid{grid-template-columns:repeat(7,minmax(0,1fr))}.app{max-width:1380px;margin:0 auto}.sheet{max-width:1180px;margin:0 auto}}
9+
</style>
10+
</head>
11+
<body>
12+
<div class="app"><div class="bar"><div class="brand">观<b>影</b></div><form class="search" id="searchForm"><input id="kw" placeholder="搜索电影、剧集、动漫…"><button>搜索</button></form><button class="btn" id="cfgBtn">配置</button></div><div class="tabs" id="tabs"></div><div class="status" id="status">准备加载…</div><main id="content"></main></div>
13+
<div class="sheet" id="sheet"><div class="panel" id="panel"></div></div>
14+
<div class="mask" id="cfgMask"><div class="cfg"><h3>观影配置</h3><p style="color:var(--muted);font-size:13px">如站点需要验证,请填入浏览器 Cookie。</p><textarea class="field" id="cookieInput" rows="5" placeholder="browser_verified=...; PHPSESSID=...; app_auth=..."></textarea><div style="display:flex;gap:8px;margin-top:12px"><button class="btn primary" id="saveCfg">保存</button><button class="btn" id="closeCfg">关闭</button></div></div></div>
15+
<script>
16+
(function(){
17+
'use strict';
18+
if(window.fongmiBridge||window.fm)document.documentElement.classList.add('fm-native');
19+
const HOST='https://www.xn--10vr61a3xc5x3b.com',IMG='https://s.tutu.pm/img',UA='Mozilla/5.0 (Linux; Android 16; Pixel 9 Pro Build/BP1A.250305.019) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.7743.101 Mobile Safari/537.36';
20+
const CLASSES=[['mv','电影'],['tv','剧集'],['ac','动漫']];
21+
let state={tid:'home',page:1,last:[],pageCount:1},currentDetail=null,cookie=localStorage.getItem('guanying_cookie')||'';
22+
const $=s=>document.querySelector(s),content=$('#content'),status=$('#status'),tabs=$('#tabs');
23+
function esc(s){return String(s||'').replace(/[&<>'"]/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;',"'":'&#39;','"':'"'}[c]))}
24+
function clean(s){return String(s||'').replace(/<[^>]+>/g,'').replace(/\s+/g,' ').trim()}
25+
function abs(u){try{return new URL(u,HOST+'/').href}catch(e){return u||''}}
26+
function b64e(o){let s=typeof o==='string'?o:JSON.stringify(o);return btoa(unescape(encodeURIComponent(s))).replace(/=+$/,'').replace(/\+/g,'-').replace(/\//g,'_')}
27+
function b64d(s){try{return JSON.parse(decodeURIComponent(escape(atob(String(s).replace(/-/g,'+').replace(/_/g,'/')+'='.repeat((4-String(s).length%4)%4))))) }catch(e){try{return decodeURIComponent(escape(atob(String(s).replace(/-/g,'+').replace(/_/g,'/')+'='.repeat((4-String(s).length%4)%4))))}catch(x){return s}}}
28+
function pic(d,i){return d&&i?`${IMG}/${d}/${i}/256.webp`:''}
29+
function headers(ref){let h={'User-Agent':UA,'Accept':'*/*','Referer':ref||HOST+'/','X-Requested-With':'XMLHttpRequest','Accept-Language':'zh-CN,zh;q=0.9'};if(cookie)h.Cookie=cookie;return h}
30+
async function req(u,ref){let url=u.startsWith('http')?u:HOST+u;status.textContent='加载:'+url;if(window.fm&&fm.req){let r=await fm.req(url,{method:'GET',headers:headers(ref),responseType:'text',timeout:25});if(!r.ok)throw new Error(r.error||('HTTP '+r.status));let t=r.body||'';if(/powSolve|"refresh"\s*:\s*1/.test(t)){await pow();r=await fm.req(url,{method:'GET',headers:headers(ref),responseType:'text',timeout:25});t=r.body||''}return t}let r=await fetch(url,{headers:headers(ref)});let t=await r.text();return t}
31+
async function jsonReq(u,ref){try{return JSON.parse(await req(u,ref)||'{}')}catch(e){return {}}}
32+
async function pow(){try{let d=await jsonReq('/res/pow');if(!d.N)return false;let n=BigInt('0x'+d.N),y=BigInt('0x'+d.x),t=parseInt(d.t||0);for(let i=0;i<t;i++)y=(y*y)%n;let body='y='+y.toString(16);if(window.fm&&fm.req){let r=await fm.req(HOST+'/res/pow',{method:'POST',headers:Object.assign(headers(HOST+'/'),{'Content-Type':'application/x-www-form-urlencoded'}),body,responseType:'text',timeout:25});return /success/.test(r.body||'')}await fetch(HOST+'/res/pow',{method:'POST',headers:Object.assign(headers(HOST+'/'),{'Content-Type':'application/x-www-form-urlencoded'}),body});return true}catch(e){return false}}
33+
function obj(h,k){let p='_obj.'+k,i=h.indexOf(p);if(i<0)return null;i=h.indexOf('=',i);if(i<0)return null;i++;while(i<h.length&&/\s/.test(h[i]))i++;let q=h[i];if(q!=='['&&q!=='{')return null;let end=q==='{'?'}':']',deep=0,ins=false,escp=false,out='';for(let j=i;j<h.length;j++){let c=h[j];out+=c;if(escp){escp=false;continue}if(c==='\\'){escp=true;continue}if(c==='"'){ins=!ins;continue}if(ins)continue;if(c===q)deep++;else if(c===end){deep--;if(deep===0)break}}out=out.replace(/\\\//g,'/').replace(/\\'/g,"'").replace(/,\s*([}\]])/g,'$1');try{return JSON.parse(out)}catch(e){return null}}
34+
function vod(name,i,d,remarks,extra){let it=Object.assign({title:name||'未知',id:String(i||''),dir:String(d||''),remarks:String(remarks||'')},extra||{});return{vod_id:b64e(it),vod_name:it.title,vod_pic:pic(it.dir,it.id),vod_remarks:it.remarks,_raw:it}}
35+
function listFromInlist(x){if(!x)return[];let arr=[];if(Array.isArray(x)){x.forEach(b=>arr=arr.concat(listFromInlist(b)));return arr}let ts=x.t||[],ids=x.i||[],ty=x.ty||'',gs=x.g||[],qs=x.q||[];ts.forEach((name,n)=>{let q=Array.isArray(qs[n])?qs[n].join(' '):'';arr.push(vod(name,ids[n]||'',ty,((gs[n]||'')+' '+q).trim()))});return arr}
36+
function listFromSearch(x){if(!x||typeof x!=='object')return[];let l=x.l||{},titles=l.title||l.t||[],ids=l.i||l.id||[],ds=l.d||l.dir||[],years=l.year||[];return titles.map((t,i)=>vod(t,ids[i]||'',ds[i]||'mv',years[i]||''))}
37+
async function suggest(tid){let kws={mv:['2025','电影','最新电影','人生'],tv:['剧集','2025','黑袍','庆余年'],ac:['动漫','星辰变','斗罗','瑞克'],home:['2025','星辰变','黑袍','人生']}[tid]||[tid],arr=[],seen=new Set();for(let kw of kws){let d=await jsonReq('/res/search_suggest?q='+encodeURIComponent(kw));if(!Array.isArray(d))continue;for(let v of d){let dr=String(v.dir||'mv');if(tid!=='home'&&tid&&dr!==tid)continue;let key=dr+String(v.id||'');if(seen.has(key))continue;seen.add(key);arr.push(vod(v.title||'',v.id||'',dr,v.year||'',v))}if(arr.length>=24)break}return arr}
38+
function renderTabs(){tabs.innerHTML=`<button class="tab ${state.tid==='home'?'active':''}" data-id="home">首页</button>`+CLASSES.map(x=>`<button class="tab ${state.tid===x[0]?'active':''}" data-id="${x[0]}">${x[1]}</button>`).join('');tabs.querySelectorAll('.tab').forEach(b=>b.onclick=()=>{state.tid=b.dataset.id;state.page=1;load()})}
39+
function card(v,i){return`<article class="card" data-i="${i}"><div class="poster">${v.vod_pic?`<img loading="lazy" referrerpolicy="no-referrer" src="${esc(v.vod_pic)}">`:'<div class="noimg">观</div>'}<span class="badge">${esc(v.vod_remarks||'资源')}</span></div><div class="meta"><div class="name">${esc(v.vod_name)}</div><div class="remark">${esc(v.vod_remarks||'点击查看')}</div></div></article>`}
40+
function renderGrid(list,pager){state.last=list;content.innerHTML=list.length?`<div class="grid">${list.map(card).join('')}</div>${pager?`<div class="pager"><button id="prev" ${state.page<=1?'disabled':''}>上一页</button><button id="next">下一页</button></div>`:''}`:'<div class="empty">暂无内容</div>';content.querySelectorAll('.card').forEach(c=>c.onclick=()=>openDetail(list[parseInt(c.dataset.i)]));let p=$('#prev'),n=$('#next');if(p)p.onclick=()=>{if(state.page>1){state.page--;load()}};if(n)n.onclick=()=>{state.page++;load()}}
41+
async function load(){renderTabs();content.innerHTML='<div class="empty">加载中…</div>';try{let list=[];if(state.tid==='home'){let h=await req('/');list=listFromInlist(obj(h,'inlist')).slice(0,24);if(!list.length)list=(await suggest('home')).slice(0,24);renderGrid(list,false);status.textContent='首页已加载'}else{if(state.page===1){let h=await req('/'+state.tid);list=listFromInlist(obj(h,'inlist'));let p=obj(h,'page')||{};state.pageCount=parseInt(p.pages||100)||100;if(!list.length)list=await suggest(state.tid)}else{let d=await jsonReq(`/res/change/${state.tid}/${state.page}`,HOST+'/'+state.tid);list=listFromInlist(d);if(!list.length)list=await suggest(state.tid)}renderGrid(list,true);status.textContent=`${(CLASSES.find(x=>x[0]===state.tid)||[])[1]} 第 ${state.page} 页 · ${list.length} 条`}}catch(e){content.innerHTML='<div class="empty">加载失败:'+esc(e.message)+'</div>';status.textContent='加载失败'}}
42+
async function search(q){q=clean(q);if(!q)return;renderTabs();content.innerHTML='<div class="empty">搜索中…</div>';try{let h=await req('/search?q='+encodeURIComponent(q));let list=listFromSearch(obj(h,'search'));if(!list.length){let d=await jsonReq('/res/search_suggest?q='+encodeURIComponent(q));list=Array.isArray(d)?d.map(v=>vod(v.title||'',v.id||'',v.dir||'mv',v.year||'',v)):[]}renderGrid(list,false);status.textContent=`搜索:${q} · ${list.length} 条`}catch(e){content.innerHTML='<div class="empty">搜索失败:'+esc(e.message)+'</div>'}}
43+
async function openDetail(v){$('#sheet').classList.add('active');$('#panel').innerHTML='<div class="empty">读取详情…</div>';try{let item=v._raw||b64d(v.vod_id),dr=item.dir||'mv',vid=item.id||'',h=await req(`/${dr}/${vid}`),d=obj(h,'d')||item,down=await jsonReq(`/res/downurl/${dr}/${vid}`,HOST+`/${dr}/${vid}`);let lines=buildLines(down);currentDetail={vod:{vod_id:v.vod_id,vod_name:d.title||item.title||v.vod_name,vod_pic:pic(dr,vid),vod_year:String(d.year||''),vod_area:Array.isArray(d.diqu)?d.diqu.join(' / '):'',vod_actor:Array.isArray(d.zhuyan)?d.zhuyan.join(' / '):'',vod_content:d.summary||'',vod_remarks:String(d.status||v.vod_remarks||'').replace(/<em>|<\/em>/g,'')},lines};let vod=currentDetail.vod;$('#panel').innerHTML=`<button class="btn" id="closeBtn">返回</button><div class="head"><img class="pic" referrerpolicy="no-referrer" src="${esc(vod.vod_pic)}" onerror="this.style.display='none'"><div><div class="title">${esc(vod.vod_name)}</div><div class="info"><div><b>年份:</b>${esc(vod.vod_year)}</div><div><b>地区:</b>${esc(vod.vod_area)}</div><div><b>演员:</b>${esc(vod.vod_actor)}</div><div><b>状态:</b>${esc(vod.vod_remarks)}</div></div></div></div><div class="pill">简介</div><div class="desc">${esc(vod.vod_content||'暂无简介')}</div><div class="pill">播放线路</div><div class="line-tabs" id="lineTabs">${lines.map((x,i)=>`<button class="line-tab ${i===0?'active':''}" data-line="${esc(x.name)}">${esc(x.name)}(${x.eps.length})</button>`).join('')}</div><div class="eps" id="eps"></div>`;$('#closeBtn').onclick=closeDetail;$('#lineTabs').querySelectorAll('.line-tab').forEach(b=>b.onclick=()=>{$('#lineTabs').querySelectorAll('.line-tab').forEach(x=>x.classList.remove('active'));b.classList.add('active');renderEpisodes(b.dataset.line)});renderEpisodes(lines[0]&&lines[0].name)}catch(e){$('#panel').innerHTML='<button class="btn" onclick="window.__gyClose()">返回</button><div class="empty">详情失败:'+esc(e.message)+'</div>'}}
44+
function buildLines(down){let pf=[];if(!down||typeof down!=='object')return[];let pan=down.panlist||{};if(pan.id){let groups={},tn=pan.tname||[];(pan.url||[]).forEach((u,i)=>{if(!u)return;let tp=(pan.type||[])[i]||0,name=Number.isInteger(tp)&&tp<tn.length?tn[tp]:'网盘',title=(pan.name||[])[i]||'网盘链接',pwd=(pan.p||[])[i]||'';u=String(u).replace(/\\\//g,'/');if(pwd&&!/pwd=/.test(u))u+=((u.includes('?')?'&':'?')+'pwd='+pwd);groups[name]=groups[name]||[];groups[name].push({name:title.replace(/[#\$]/g,' '),url:u,type:'pan'})});Object.keys(groups).forEach(k=>pf.push({name:k,eps:groups[k]}))}let dl=down.downlist&&down.downlist.list||{};if(dl.m){let eps=[];(dl.m||[]).slice(0,80).forEach((m,i)=>{let title=(dl.t||[])[i]||'磁力';eps.push({name:title.replace(/[#\$]/g,' '),url:'magnet:?xt=urn:btih:'+m+'&dn='+encodeURIComponent(title),type:'magnet'})});if(eps.length)pf.push({name:'磁力',eps})}(down.playlist||[]).forEach(line=>{if(!line||typeof line!=='object')return;let eps=(line.list||[]).map((n,i)=>({name:String(n),url:HOST+'/py/'+line.i+'/'+(i+1),type:'online'}));if(eps.length)pf.push({name:line.t||'在线',eps})});return pf}
45+
function renderEpisodes(line){let box=$('#eps'),ln=currentDetail&&currentDetail.lines.find(x=>x.name===line);let list=ln&&ln.eps||[];box.innerHTML=list.map((x,i)=>`<button class="ep" data-line="${esc(line)}" data-index="${i}">${esc(x.name)}</button>`).join('')||'<div class="empty">暂无资源</div>';box.querySelectorAll('.ep').forEach(b=>b.onclick=()=>playFull(b.dataset.line,parseInt(b.dataset.index),b.textContent))}
46+
async function playFull(lineName,index,mark){let d=currentDetail&&currentDetail.vod;if(!d)return;let lines=currentDetail.lines||[],ln=lines.find(x=>x.name===lineName)||lines[0],cur=ln.eps[index]||ln.eps[0];if(!cur)return;let from=[],urls=[];lines.forEach(l=>{from.push(l.name);urls.push((l.eps||[]).map(e=>`${e.name}$${playUrl(e.url,e.type)}`).join('#'))});let native=(ln.eps||[]).map(e=>({name:e.name,url:playUrl(e.url,e.type)})),u=playUrl(cur.url,cur.type);if(window.fm&&typeof fm.vodInline==='function'){await fm.vodInline({vod_id:d.vod_id,vod_name:d.vod_name,vod_pic:d.vod_pic,vod_remarks:d.vod_remarks,vod_content:d.vod_content,vod_play_from:from.join('$$$'),vod_play_url:urls.join('$$$'),play_from:lineName,mark:mark||cur.name,episodes:native,url:u});return}if(window.fm&&fm.play){await fm.play(u,d.vod_name+' '+(mark||cur.name));return}location.href=u}
47+
function playUrl(u,type){u=String(u||'');if(type==='pan'&&u.startsWith('http'))return u.startsWith('push://')?u:'push://'+u;return u}
48+
function closeDetail(){$('#sheet').classList.remove('active')}
49+
$('#searchForm').onsubmit=e=>{e.preventDefault();search($('#kw').value)};$('#cfgBtn').onclick=()=>{$('#cookieInput').value=cookie;$('#cfgMask').classList.add('active')};$('#closeCfg').onclick=()=>$('#cfgMask').classList.remove('active');$('#saveCfg').onclick=()=>{cookie=$('#cookieInput').value.trim();localStorage.setItem('guanying_cookie',cookie);$('#cfgMask').classList.remove('active');load()};window.__gyClose=closeDetail;pow().finally(load);
50+
})();
51+
</script>
52+
</body>
53+
</html>

0 commit comments

Comments
 (0)