Spaces:
Running
Running
fix: 24h-only slider, tap-to-show seek controls, multi-part probe
Browse files
app.py
CHANGED
|
@@ -393,30 +393,21 @@ def _bdp_relates(soup):
|
|
| 393 |
|
| 394 |
# ββ Video aggregator βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 395 |
def fetch_latest_videos():
|
| 396 |
-
"""Fetch
|
| 397 |
videos = []
|
| 398 |
-
# BDP carousel
|
| 399 |
try:
|
| 400 |
-
|
| 401 |
-
first_link = None
|
| 402 |
-
for a in soup.find_all("a", href=True):
|
| 403 |
-
href = a.get("href", "")
|
| 404 |
-
if "/video/" in href and re.search(r'-\d{6,}\.html', href):
|
| 405 |
-
first_link = href if href.startswith("http") else BASE_BDP + href; break
|
| 406 |
-
if first_link:
|
| 407 |
-
vid_id = _extract_bdp_video_id(first_link)
|
| 408 |
-
if vid_id:
|
| 409 |
-
embed = fetch_bdp_embed_data(vid_id)
|
| 410 |
-
if embed:
|
| 411 |
-
for rel in embed.get("related", []):
|
| 412 |
-
videos.append({"title": rel["title"], "link": rel["link"], "img": rel["poster"], "source": "bdp"})
|
| 413 |
-
except: pass
|
| 414 |
-
# 24h highlights
|
| 415 |
-
try:
|
| 416 |
-
h24 = scrape_24h_video_list()[:10]
|
| 417 |
for a in h24:
|
| 418 |
-
|
| 419 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 420 |
except: pass
|
| 421 |
return videos[:20]
|
| 422 |
|
|
@@ -542,7 +533,7 @@ def render_video_slider_html(videos):
|
|
| 542 |
<div class="vslide-thumb"><img src="{img}" alt="" class="bdp-lazy-img"><div class="vslide-play">βΆ</div>{src_badge}</div>
|
| 543 |
<p class="vslide-title">{title}</p></div>''')
|
| 544 |
return f'''<div class="vslide-wrap">
|
| 545 |
-
<div class="vslide-header"><span class="vslide-label">π¬ Video
|
| 546 |
<div class="vslide-nav"><button class="vslide-btn" onclick="window.bdpSlideScroll(-1)">β</button>
|
| 547 |
<button class="vslide-btn" onclick="window.bdpSlideScroll(1)">βΆ</button></div></div>
|
| 548 |
<div class="vslide-track" id="vslide-track">{''.join(items)}</div></div>'''
|
|
@@ -855,10 +846,10 @@ footer,.built-with{display:none!important}
|
|
| 855 |
.tiktok-unmute-hint{position:absolute;top:12px;right:12px;background:rgba(0,0,0,.6);color:#fff;font-size:12px;padding:6px 12px;border-radius:18px;cursor:pointer;z-index:4;backdrop-filter:blur(4px);transition:opacity .3s}
|
| 856 |
.tiktok-pause-icon{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:70px;height:70px;background:rgba(0,0,0,.5);border-radius:50%;color:#fff;font-size:28px;z-index:5;pointer-events:none;display:none;align-items:center;justify-content:center;line-height:70px;text-align:center}
|
| 857 |
.tiktok-slide.paused .tiktok-pause-icon{display:block}
|
| 858 |
-
.tiktok-seek-controls{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);display:flex;gap:
|
| 859 |
-
.tiktok-
|
| 860 |
-
.tiktok-seek-btn
|
| 861 |
-
.tiktok-seek-btn:active{transform:scale(.
|
| 862 |
.vslide-badge{position:absolute;top:6px;left:6px;font-size:9px;padding:1px 6px;border-radius:3px;font-weight:700;z-index:2}
|
| 863 |
.vslide-badge-24h{background:#e67e22;color:#fff}
|
| 864 |
"""
|
|
@@ -1044,14 +1035,28 @@ function initTikTokFullscreen(container){
|
|
| 1044 |
/* Start first video after short delay for HLS init */
|
| 1045 |
setTimeout(function(){activateSlide(0);},800);
|
| 1046 |
|
| 1047 |
-
/* Tap to pause/play */
|
| 1048 |
slides.forEach(function(sl){
|
| 1049 |
var v=sl.querySelector('.tiktok-video');
|
| 1050 |
if(v){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1051 |
v.addEventListener('click',function(e){
|
| 1052 |
e.preventDefault();
|
| 1053 |
-
if(
|
| 1054 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1055 |
});
|
| 1056 |
}
|
| 1057 |
});
|
|
|
|
| 393 |
|
| 394 |
# ββ Video aggregator βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 395 |
def fetch_latest_videos():
|
| 396 |
+
"""Fetch 24h highlight videos for the homepage slider."""
|
| 397 |
videos = []
|
|
|
|
| 398 |
try:
|
| 399 |
+
h24 = scrape_24h_video_list()[:20]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 400 |
for a in h24:
|
| 401 |
+
# Use og:image from article page if no thumbnail
|
| 402 |
+
img = a.get("img")
|
| 403 |
+
if not img:
|
| 404 |
+
try:
|
| 405 |
+
r = requests.get(a["link"], headers=HEADERS, timeout=8); r.encoding="utf-8"
|
| 406 |
+
og = BeautifulSoup(r.text,"lxml").find("meta",property="og:image")
|
| 407 |
+
if og: img = og.get("content","")
|
| 408 |
+
except: pass
|
| 409 |
+
if img:
|
| 410 |
+
videos.append({"title": a["title"], "link": a["link"], "img": img, "source": "24h"})
|
| 411 |
except: pass
|
| 412 |
return videos[:20]
|
| 413 |
|
|
|
|
| 533 |
<div class="vslide-thumb"><img src="{img}" alt="" class="bdp-lazy-img"><div class="vslide-play">βΆ</div>{src_badge}</div>
|
| 534 |
<p class="vslide-title">{title}</p></div>''')
|
| 535 |
return f'''<div class="vslide-wrap">
|
| 536 |
+
<div class="vslide-header"><span class="vslide-label">π¬ Video Highlight 24h</span>
|
| 537 |
<div class="vslide-nav"><button class="vslide-btn" onclick="window.bdpSlideScroll(-1)">β</button>
|
| 538 |
<button class="vslide-btn" onclick="window.bdpSlideScroll(1)">βΆ</button></div></div>
|
| 539 |
<div class="vslide-track" id="vslide-track">{''.join(items)}</div></div>'''
|
|
|
|
| 846 |
.tiktok-unmute-hint{position:absolute;top:12px;right:12px;background:rgba(0,0,0,.6);color:#fff;font-size:12px;padding:6px 12px;border-radius:18px;cursor:pointer;z-index:4;backdrop-filter:blur(4px);transition:opacity .3s}
|
| 847 |
.tiktok-pause-icon{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:70px;height:70px;background:rgba(0,0,0,.5);border-radius:50%;color:#fff;font-size:28px;z-index:5;pointer-events:none;display:none;align-items:center;justify-content:center;line-height:70px;text-align:center}
|
| 848 |
.tiktok-slide.paused .tiktok-pause-icon{display:block}
|
| 849 |
+
.tiktok-seek-controls{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);display:flex;gap:50px;z-index:6;pointer-events:auto;opacity:0;transition:opacity .3s}
|
| 850 |
+
.tiktok-slide.show-controls .tiktok-seek-controls{opacity:1}
|
| 851 |
+
.tiktok-seek-btn{background:rgba(0,0,0,.5);color:#fff;border:none;padding:10px 16px;border-radius:24px;font-size:13px;cursor:pointer;backdrop-filter:blur(6px);font-weight:600;transition:transform .1s}
|
| 852 |
+
.tiktok-seek-btn:active{transform:scale(.85)}
|
| 853 |
.vslide-badge{position:absolute;top:6px;left:6px;font-size:9px;padding:1px 6px;border-radius:3px;font-weight:700;z-index:2}
|
| 854 |
.vslide-badge-24h{background:#e67e22;color:#fff}
|
| 855 |
"""
|
|
|
|
| 1035 |
/* Start first video after short delay for HLS init */
|
| 1036 |
setTimeout(function(){activateSlide(0);},800);
|
| 1037 |
|
| 1038 |
+
/* Tap to pause/play + show/hide seek controls */
|
| 1039 |
slides.forEach(function(sl){
|
| 1040 |
var v=sl.querySelector('.tiktok-video');
|
| 1041 |
if(v){
|
| 1042 |
+
var hideTimer=null;
|
| 1043 |
+
function showControls(){
|
| 1044 |
+
sl.classList.add('show-controls');
|
| 1045 |
+
if(hideTimer) clearTimeout(hideTimer);
|
| 1046 |
+
hideTimer=setTimeout(function(){sl.classList.remove('show-controls');},3000);
|
| 1047 |
+
}
|
| 1048 |
v.addEventListener('click',function(e){
|
| 1049 |
e.preventDefault();
|
| 1050 |
+
if(sl.classList.contains('show-controls')){
|
| 1051 |
+
/* Second tap = pause/play */
|
| 1052 |
+
if(v.paused){tryPlay(v);sl.classList.remove('paused');}
|
| 1053 |
+
else{v.pause();sl.classList.add('paused');}
|
| 1054 |
+
sl.classList.remove('show-controls');
|
| 1055 |
+
if(hideTimer) clearTimeout(hideTimer);
|
| 1056 |
+
} else {
|
| 1057 |
+
/* First tap = show controls */
|
| 1058 |
+
showControls();
|
| 1059 |
+
}
|
| 1060 |
});
|
| 1061 |
}
|
| 1062 |
});
|