menu
FLIDEO
search
?
expand_more
?
زائر
غير مسجّل
login
upload
space_dashboard
tv
settings
shield_person
Hub Control
language
EN
dark_mode
Dark
logout
play_arrow
chevron_left
chevron_right
←
←
FLIDEO
▶
✎
◉
◓
0
0
0
0
cloud_upload
MP4
—
—
image
upload
smart_button
close
play_circle
smart_display
article
open_in_new
P
B
I
H2
”
•
🔗
0
·
—
—
—
Google
⚡
Flideo Hub Control
←
ACLIB (VAST Video Ads)
ACLIB enabled
Run ACLIB autoTag for video ads (VAST)
ACLIB Zone ID
ACLIB Script URL
Save ACLIB settings
×
•
•
▶ Flowplayer
/* استخراج إطار من الفيديو بـCanvas +
(بلا أي مكتبة خارجية). يقبل File أو رابطًا مباشرًا. */ window.captureVideoFrame = function(source, atSecond = 1){ return new Promise((resolve, reject) => { const isUrl = typeof source === "string"; const video = document.createElement("video"); video.preload = "auto"; video.muted = true; video.playsInline = true; if(isUrl) video.crossOrigin = "anonymous"; const url = isUrl ? source : URL.createObjectURL(source); let done = false; const cleanup = () => { try{ video.removeAttribute("src"); video.load(); }catch(e){} if(!isUrl){ try{ URL.revokeObjectURL(url); }catch(e){} } }; const fail = (msg) => { if(done) return; done = true; cleanup(); reject(new Error(msg)); }; const grab = () => { if(done) return; try { const w = video.videoWidth, h = video.videoHeight; if(!w || !h) return fail("لا يمكن قراءة أبعاد الإطار"); done = true; // لا نعتبر النجاح محقّقًا إلا بعد قراءة الأبعاد const canvas = document.createElement("canvas"); canvas.width = w; canvas.height = h; canvas.getContext("2d").drawImage(video, 0, 0, w, h); cleanup(); try { canvas.toBlob(blob => { if(blob && blob.size) resolve(blob); else reject(new Error("تعذّر استخراج الصورة من الرابط")); }, "image/jpeg", 0.85); } catch(e){ reject(new Error("تعذّر استخراج الصورة من الرابط")); } } catch(e){ fail(e.message || "thumb error"); } }; video.onloadedmetadata = () => { const d = isFinite(video.duration) && video.duration > 0 ? video.duration : 0; const t = d ? Math.min(Math.max(atSecond, 0), Math.max(0, d - 0.1)) : Math.max(atSecond, 0); try { video.currentTime = t; } catch(e){ grab(); } }; video.onseeked = grab; // بديل احتياطي إن لم يُطلق حدث seek (فيديو قصير جداً أو بلا مدة معروفة) video.onloadeddata = () => { setTimeout(() => { if(!done) grab(); }, 700); }; video.onerror = () => fail("تعذّر تحميل الفيديو لاستخراج الصورة"); setTimeout(() => fail("انتهت المهلة أثناء استخراج الصورة"), 10000); video.src = url; }); };