Deși ideea unui element HTML video specific a fost sugerată de peste un deceniu în urmă, începem doar să vedem că acest lucru a devenit realitate! Uitați toate aceste "HTML5 2012" mumbo-jumbo; adevărul este că poți folosi video
element în proiectele tale chiar acum! Trebuie doar să fiți conștienți de o mulțime de cerințe înainte de a lua fără minte plonjare.
document.createElement ( 'video')
. Destul de ciudat, acest lucru pare să ducă la conștientizarea IE. Da - este destul de ciudat, dar am ajuns să ne așteptăm la asta din Internet Explorer, nu? Pentru a accelera acest proces, Remy Sharp a creat HTML5 Shiv, care, de altfel, remediază unele probleme de tipărire atunci când lucrează cu elemente HTML5. Pur și simplu descărcați scriptul și trimiteți-l în cadrul cap
secțiune a documentului dvs..ogg
format, în timp ce browserele Webkit pot reda mp4
Videoclipuri. De fapt, aceasta este o simplificare superioară; totuși, acest lucru se va face pentru moment. Cu toate acestea, este suficient să spunem că sunt acceptate mai multe tipuri de videoclipuri, printre care codecul V8 de ultimă generație al companiei Google. Ca și în cazul oricărui proiect, primul nostru pas este să creăm marja necesară pentru proiectul nostru.
Player HTML5 personalizat HTML5 Video
Mai întâi, găsiți niște videoclipuri cu care să lucrați. Video-ul "Big Bunny Buck" de tip open-source este ceea ce voi folosi. Sunt sigur că ați văzut-o deja în uz pe internet. Afișarea acestui marcaj în browser vă poate lăsa cu un semn de întrebare peste cap.
Nu-i asa? Asta e? Arată doar o imagine. Care este problema? Ei bine, în mod implicit, asta e tot ce am cerut. Trebuie să specificăm dacă să afișăm sau nu comenzile, să afișăm un poster etc. Să facem asta acum; vă revizuiți video
element, după cum urmează:
Chiar de pe liliac, observăm că nu există citate în jurul atributelor. După cum se dovedește, ele nu sunt necesare. Cu ani în urmă, a fost considerată o practică proastă de a le exclude, acest lucru nu mai este cazul. În acest moment, nu este decât o preferință personală. Deci, dacă vă simțiți mai bine să le adăugați, atunci, prin toate mijloacele, faceți acest lucru.
Desigur, nu avem ce să folosim controalele implicite ale browserului. Ca atare, trebuie să punem în aplicare propriile noastre controale-marcă-up. Înainte de a progresa, ați fi putut să vă întrebați: "Atunci, care este scopul adăugării controale
atributul la toate? Răspunsul este că trebuie să luăm în considerare și să compensăm faptul că este posibil ca JavaScript să fie dezactivat pe computerul privitorului. În aceste cazuri, dacă nu am adăugat controale
atribut, au văzut doar ceea ce pare a fi o imagine.
Luați întotdeauna în considerare posibilitatea ca JavaScript să fie dezactivat.
div
cu un id de "videoControls" este locul în care vom adăuga butoanele și logo-ul necesar. Un truc mic este folosirea funcției "& # x25BA;" pentru a crea butonul de redare. Nu vă faceți griji prea mult despre "progress" div; vom examina această secțiune mai detaliat mai târziu în acest tutorial. Răspunsul scurt este că acesta este containerul pentru bara noastră de progres. În cele din urmă, adăugăm a buton
care va comuta întreaga funcționalitate a ecranului, precum și sigla Tuts +.
Nu-ți face griji; deși se pare că am creat acum un al doilea set de controale (și unstyled la asta), vom elimina în cele din urmă controalele implicite cu JavaScript. Cu toate acestea, captura de ecran de mai sus ar trebui să se potrivească propriei dvs. previzualizări, dacă urmăriți de-a lungul.
Odată cu completarea marcajului, putem trece acum la partea distractivă! Creați un folder nou, numit "js", și adăugați un fișier nou: videoPlayer.js
. Apoi, să fim băieți și fete bune și să ne înfășurăm codul într-o funcție anonimă invocată de sine, pentru a preveni crearea unor variabile globale inutile.
(funcție (fereastră, document) (acest document)
Puteți renunța la argumente dacă doriți, este o mică îmbunătățire cu două avantaje:
acest
(obiectul Window global) și document
, ne împiedică motorul JavaScript să trebuiască să filtreze și să urmărească acele obiecte în jos. Acest lucru poate fi o mare comoditate pentru proiectele mai mari, dar oferă un avantaj foarte mic de performanță. fereastră
și document
pot fi acum reprezentate prin ceva asemănător A
și b
. Apoi, să continuăm să păstrăm codul cât mai curat posibil prin crearea unui video player
obiect care va conține toate metodele noastre. Vom crea, de asemenea, un init
care va fi sunată imediat când pagina se încarcă.
(functie (fereastra, documentul) var videoPlayer = init: function () ; videoPlayer.init (); (acest document))
Pe măsură ce vom manipula cu siguranță elemente pe pagină, hai să mergem mai departe și să menționăm locația acestora în cadrul variabilelor. Chiar înainte de a declara variabila "videoPlayer", prepend:
var video = document.getElementsByTagName ("video") [0], videoControls = document.getElementById ('videoControls'), play = document.getElementById (progress '), progressContainer = document.getElementById progressHolder = document.getElementById ("progres_box"), playProgressBar = document.getElementById ("play_progress"), fullScreenToggleButton = document.getElementById ("fullScreen");
Dacă lucrați de-a lungul (și sper că sunteți), faceți ceva timp pentru a afla exact ce se referă la aceste variabile. Reveniți la marja dvs., dacă este necesar. Am apucat elementul video, controalele video div, butonul de redare, butonul de comutare pe ecran complet și cele trei progrese. Am "cache" locația acestor elemente, deoarece nu există niciun motiv pentru a traversa DOM în mod inutil de fiecare dată când avem nevoie să accesăm unul dintre aceste elemente!
init
Metodă Să începem să scriem niște coduri reale. În cadrul init
metoda, inserați în fragmentul următor:
init: function () // este egal cu obiectul videoPlayer. var that = acest lucru; // Declanșator CSS util pentru JS. document.documentElement.className = 'js'; // Scapa de controalele implicite, pentru că vom folosi propriile noastre. video.removeAttribute ( 'controale'); // Când datele meta sunt gata, afișați comenzile video.addEventListener ('loadeddata', this.initializeControls, false);
O modalitate neclară pe care o facem ca elemente de stil bazate pe dacă JavaScript este activat este aplicarea unei clase de "js" la documentElement
, sau html
element.
// Declanșator CSS util pentru JS. document.documentElement.className = 'js';
Acest lucru ne permite să scriem apoi CSS cum ar fi:
.js #container / * acest stil redă numai dacă JS este activat * /
Amintiți-vă problema cu cele două seturi de comenzi video? Să remediem asta acum. Acesta este unul ușor; vom folosi pur și simplu removeAttribute
metoda, și să scapi de controale
.
// Scapa de controalele implicite, pentru că vom folosi propriile noastre. video.removeAttribute ( 'controale');
Să adăugăm acum primul nostru eveniment HTML5: loadeddata
. Acest eveniment se declanșează atunci când browserul finalizează încărcarea datelor meta pentru videoclip. Acesta este un loc excelent pentru a efectua orice proceduri inițiale, cum ar fi afișarea comenzilor personalizate.
// Când datele meta sunt gata, afișați comenzile video.addEventListener ('loadeddata', this.initializeControls, false);
Dacă știți un pic de JavaScript, s-ar putea să vă faceți griji că nu compensăm Internet Explorer. Pentru cei care nu știu, IE8 și mai jos nu recunosc addEventListener
. În schimb, în modul în care este obișnuit, IE folosește propriile sale attachEvent
. Totuși, asta se schimbă în versiunea nouă a browserului. Cum IE8 și de mai jos nu înțeleg video
element, putem ignora attachEvent
eveniment în întregime.
Cand loadeddata
incendii eveniment, numim metoda "initializeControls" care urmeaza a fi creata. În cadrul unei metode obiect, nu putem să ne referim la "initializeControls" de la sine. Trebuie să menționăm mai întâi obiectul însuși: prin urmare, this.initializeControls
.
Să mergem mai departe și să creăm acea metodă acum.
initializeControls: function () // Cand toate informatiile meta au fost incarcate, arata controalele videoPlayer.showHideControls ();
După cum sa menționat anterior, dacă scrieți propriul player personalizat, utilizați această metodă pentru a efectua orice proceduri inițiale suplimentare. Pentru moment, această metodă va apela o altă metodă, showHideControls
. Această nouă metodă va afișa sau ascunde comenzile atunci când utilizatorul se deplasează peste videoclip.
showHideControls: function () // Afișează și ascunde playerul video. video.addEventListener ('mouseover', funcția () videoControls.style.opacity = 1;, false); videoControls.addEventListener ('mouseover', funcția () videoControls.style.opacity = 1;, false); video.addEventListener ('mouseout', funcție () videoControls.style.opacity = 0;, false); videoControls.addEventListener ('mouseout', funcția () videoControls.style.opacity = 0;, false);
Această metodă leagă patru playere de evenimente la playerul video și elementele de control, reprezentate de video
și videoControls
variabile, respectiv. Acest cod este simplu: atunci când treceți mouse-ul video, schimbați opacitatea comenzilor video la 1. În mod invers, când este dezactivată, ascundeți comenzile din vizualizare. Acest cod presupune, de asemenea, implicit, în foaia de stil, controlul video opacitate
este setat la zero.
Amintiți-vă: când este posibil, întotdeauna să delegeți stilul fișierului nostru CSS, mai degrabă decât să îl adăugați direct cu JavaScript. Pe lângă avantajele de performanță și reducerea refluxurilor / repetărilor, această practică aderă corect la separarea prezentării de logică. Cu toate acestea, din când în când, nu veți avea altă opțiune decât să adăugați stilul în fișierul JavaScript și, în aceste cazuri, este în regulă.
Acum am ascuns comenzile implicite, dar nu am atasat nici o logica acestor diferite butoane personalizate. Asta trebuie să facem în continuare.
Reveniți la init
și adăugați un apel la o nouă metodă.
// Când se joacă, se apasă butoanele de pauză. this.handleButtonPresses ();
Sunteți, desigur, liberi să numiți aceste metode cum doriți, dar cel puțin încercați să le numiți în așa fel încât să fie ușor de înțeles exact care este scopul funcției.
handleButtonPress: funcția () // Când se face clic pe butonul video sau de redare, redați / întrerupeți videoclipul. video.addEventListener ("faceți clic pe", this.playPause, false); play.addEventListener ('click', this.playPause, false); // Când apăsați butonul de redare, // comutați la simbolul "Pauză". video.addEventListener ('play', function () play.title = 'Pause'; play.innerHTML = '& # X2590; & # x2590;„; , fals); // Când apăsați butonul de pauză, // comutați la simbolul "Redare". video.addEventListener ('pauză', funcție () play.title = 'Play'; play.innerHTML = '& # x25BA;', false); // După încheierea videoclipului, opriți-l. video.addEventListener ('a terminat', funcția () this.currentTime = 0; this.pause ();, false);
În cadrul acestei metode, atașăm din nou o mână de evenimente noi care sunt disponibile pentru video
element: Joaca
, pauză
, și încheiat
.
Rețineți că, de exemplu,
Joaca
evenimentul nu se declanșează când faceți clic pe butonul de redare pe care l-am creat. Nu, în schimb, se declanșează când începe chiar redarea videoclipului. Aceasta este o distincție importantă de reținut.
Pentru a declanșa evenimentele enumerate mai sus, adăugăm un alt ascultător al evenimentului la butonul de redare și ascultăm atunci când utilizatorul face clic pe el.
// Când se face clic pe butonul video sau pe redare, redați / întrerupeți videoclipul. play.addEventListener ('click', this.playPause, false);
playPause: funcția () if (video.paused || video.ended) if (video.ended) video.currentTime = 0; video.play (); altceva video.pause ();
Să vorbim prin codul de mai sus în general - vorbește. Când a fost apelată această metodă - în cazul nostru, atunci când butonul de redare a fost primul clic - a fost oprită sau la sfârșitul videoclipului? Dacă acesta din urmă este necesar, trebuie să resetăm timpul videoclipului la 0, astfel încât acesta să poată reda din nou începutul. Apoi, trebuie să jucăm videoclipul: video.play ()
.
Acum, dacă videoclipul nu a fost întrerupt sau la final - ceea ce înseamnă că videoclipul era în curs de redare la apăsarea butonului de redare, ar trebui să facem opusul și să oprim în schimb videoclipul: video.pause ()
.
playPause
metoda detaliată mai sus, gestionează procesul de redare sau de întrerupere a videoclipului. Dar, cu siguranță, trebuie să oferim utilizatorilor un feedback despre ceea ce face butonul de împingere, nu-i așa? Categoric; pentru a face acest lucru, vom comuta între codul de caractere "play" și "pauză" de fiecare dată când se face clic pe buton. Deci, în mod esențial, acest singur buton se ocupă atât de redare, cât și de pauză.
Dacă te referi la ascultătorii evenimentului de acum un moment, am adăugat deja această funcție.
// Când apăsați butonul de redare, // comutați la simbolul "Pauză". video.addEventListener ('play', function () play.title = 'Pause'; play.innerHTML = '& # X2590; & # x2590;„; , fals); // Când apăsați butonul de pauză, // comutați la simbolul "Redare". video.addEventListener ('pauză', funcție () play.title = 'Play'; play.innerHTML = '& # x25BA;', false);
Destul de simplu, nu? Dacă este apăsat butonul de redare, butonul clic
evenimentul apare pe butonul de redare, care solicită video.play ()
. Această metodă redă apoi videoclipul și declanșează Joaca
eveniment. Joaca
evenimentul apoi modifică valoarea butonului la un simbol de pauză și actualizează și atributul titlu. În cele din urmă, când acest proces are loc din nou, facem opusul.
Am menționat-o în paragraful de deschidere al acestui tutorial: suportul pe ecran complet este o necesitate pentru mine. Să adăugăm această funcție acum. Întoarce-te la tine init ()
și, din nou, adăugați un fragment în partea de jos. Trebuie să ascultăm când butonul de comutare pe ecran pe care l-am creat ...
... este făcută clic pe. Când este, ar trebui fie să comutăm videoclipul pe ecran complet, fie opusul.
Nu uitați:
fullScreenToggleButton
se referă la butonul "fullScreen".
// Când este apăsat butonul complet pe ecran ... fullScreenToggleButton.addEventListener ("click", funcția () isVideoFullScreen? That.fullScreenOff (): that.fullScreenOn (); true);
Așteptați un minut: ce este acea
? Nu ar trebui să fie acest
? Raspunsul este nu. În contextul evenimentului clic, acest
se referă acum la butonul "fullScreen", nu la video player
obiect.
Pentru a remedia acest lucru, vom "cache" valoarea inițială a acest
într-o variabilă, numită acea
. Acest lucru poate fi adăugat în partea de sus a noastră init ()
metodă.
init: function () // este egal cu obiectul videoPlayer. var that = this; ...
Ta da! Acum, ne putem referi din nou la video player
obiect. Ca atare, that.fullScreenOff
înseamnă "accesați metoda numită" fullScreenOff "care este un copil al video player
obiect.
Există o problemă. Cum determinăm starea curentă a videoclipului? Este dimensiune normală sau normală? O modalitate ușoară de a face față acestei situații este crearea unei variabile numite "isVideoFullScreen". Puteți adăuga această variabilă chiar în partea de sus a paginii dvs., împreună cu celelalte. În mod implicit, această valoare ar trebui setată, bineînțeles fals
.
fullScreenToggleButton = document.getElementById ("fullScreen"), // Boolean care ne permite să "amintim" dimensiunea curentă a player-ului video. isVideoFullScreen = false,
Acest boolean ne permite acum să apelam corect funcția corespunzătoare atunci când este apăsat butonul "fullScreen".
esteVideoFullScreen? that.fullScreenOff (): that.fullScreenOn ();
Utilizând operatorul ternar, verificăm: "este videoclipul în mod curent în modul ecran complet? Dacă este, sunăm fullScreenOff ()
. În caz contrar, sunăm fullScreenOn ()
.
fullScreenOn: funcția () isVideoFullScreen = true; // Setați o lățime nouă în funcție de lățimea ferestrei video.style.cssText = 'Poziție: fixă; lățime: '+ window.innerWidth +' px; înălțime: '+ window.innerHeight +' px; '; // Aplică un nume de clasă la videoclip și controale, dacă designerul are nevoie ... video.className = 'fullsizeVideo'; videoControls.className = 'fs-control'; fullScreenToggleButton.className = "controlul fs-activ"; // Ascultați pentru cheia de evacuare. Dacă este apăsat, închideți ecranul complet. document.addEventListener ('keydown', this.checkKeyCode, false); , funcția fullScreenOff: () isVideoFullScreen = false; video.style.position = 'static'; video.className = "; fullScreenToggleButton.className =" control "; videoControls.className =";
În cadrul acestor două funcții, modificăm mai întâi valoarea isVideoFullScreen
, în consecinţă. Apoi, ajustăm dimensiunea videoclipului în sine. cssText
ne permite să trecem un șir de stil la un element. În acest caz, nu putem îndeplini această sarcină direct din foaia de stil. Acest lucru se datorează faptului că valorile dorite sunt dinamice și vor depinde de dimensiunea ferestrei browserului.
Utilizare
window.innerWidth
șiwindow.innerHeight
pentru a prelua lățimea și înălțimea ferestrei browserului.
Este, de asemenea, o bună practică de a aplica numele de clasă pe ecran complet elementelor noastre. În acest fel, dacă trebuie să adăugați orice stil adecvat, aveți acum un nume de clasă pe care să-l cârligați.
În plus față de butonul de comutare full-screen, este de asemenea destul de comun să părăsiți modul ecran complet atunci când utilizatorul apasă tasta de evacuare de pe tastatură. Este o comoditate plăcută și este una pe care ar trebui să o implementăm în jucătorul nostru. Din fericire, e ușor!
// Ascultați pentru cheia de evacuare. Dacă este apăsat, închideți ecranul complet. document.addEventListener ('keydown', this.checkKeyCode, false);
Pentru a asculta clicurile cheie, folosim Tasta în jos
eveniment. În timp ce aș putea trece o funcție anonimă ca al doilea parametru, acest bit de cod ar putea fi folosit în mai multe locuri. Iar atunci când acest lucru este adevărat, codul ar trebui să fie relocat la propria funcție, pentru reutilizare. O să-l sunăm, checkKeyCode
.
// Stabilește dacă a fost apăsată tasta de evacuare. checkKeyCode: funcția (e) e = e || window.event; dacă ((e.keyCode || e.which) === 27) videoPlayer.fullScreenOff ();
Această funcție este, din păcate, mai confuză decât ar trebui să fie, din cauza problemelor din Internet Explorer. Desigur, nu sunt sigur cum IE9 se ocupă de obiectul evenimentului, deci, pentru moment, vom compensa discrepanțele dintre modul în care IE și celelalte browsere moderne se ocupă de obiectul evenimentului.
Părăsiți lucrurile deoparte, acest cod verifică dacă cheia care a fost apăsată are un cod de "27." Dacă se întâmplă, atunci tasta "Escape" a fost apăsată, caz în care putem ieși din ecranul complet, prin videoPlayer.fullScreenOff ()
.
Nu în ultimul rând, trebuie să urmărim progresul videoclipului. Deci, pe măsură ce progresează videoclipul, trebuie să oferim un "scruber" de progres care vă va ajuta să urmăriți videoclipul. În plus, permite utilizatorului să scaneze rapid la porțiunea dorită a videoclipului.
E ușor: când se joacă videoclipul! Deci, având în vedere acest lucru, să ne modificăm Joaca
codul evenimentului și apelați o funcție care va urmări progresul videoclipului.
// Când apăsați butonul de redare, // comutați la simbolul "Pauză". video.addEventListener ('play', function () play.title = 'Pause'; play.innerHTML = '& # X2590; & # x2590;„; // Începeți urmărirea progresului videoclipului. videoPlayer.trackPlayProgress (); , fals);
// La fiecare 50 de milisecunde, actualizați progresul redării. trackPlayProgress: funcția () (funcția progressTrack () videoPlayer.updatePlayProgress (); playProgressInterval = setTimeout (progressTrack, 50);) ();
Nu lăsați acest cod să vă sperie. Este doar o funcție recursivă care ne permite să apelăm la o altă metodă, updatePlayProgress ()
, la fiecare cincizeci de milisecunde. De ce nu folosiți setInterval
in schimb? Asta pentru ca setInterval
poate fi uneori urât. Fără a intra în prea multe detalii care depășesc sfera acestui tutorial, setInterval
va rula (în acest caz) o dată la cincizeci de milisecunde, indiferent cât timp durează codul din cadrul funcției.
setInterval
este ca un șofer în traficul de ore de vârf, care refuză să facă pași.
Deci, când este posibil, combinarea setTimeout
cu o funcție recursivă este soluția mai inteligentă. Rețineți că alocăm setTimeout
la o variabilă, playProgressInterval
, pentru că trebuie să clarificăm mai târziu acest timp de expirare. Prin urmare, avem nevoie de un id de cârlig pentru a intra în.
Acum, că am specificat că, la fiecare cincizeci de milisecunde, updatePlayProgress
metoda ar trebui să fie chemată, să o creăm acum.
updatePlayProgress: funcția () playProgressBar.style.width = ((video.currentTime / video.duration) * (progressHolder.offsetWidth)) + "px";
Deși codul de mai sus poate părea foarte confuz la început, nu este prea rău. Am apucat bara de progres și l-am actualizat lățimea (la fiecare 50ms). Putem determina lățimea corectă împărțind locația curentă a videoclipului, pe lungimea videoclipului - cu care putem calcula video.duration
. Această valoare trebuie apoi să fie înmulțită cu lățimea totală a titularului de progres și voila!
Dar ce se întâmplă când videoclipul este întrerupt de utilizator? Cu siguranță nu vrem să continuăm asta setTimeout
. Desigur că nu. Ca atare, ar trebui să creăm o altă metodă, numită stopPlayProgress
, și se referă la aceasta atunci când evenimentul de pauză este declanșat.
// Am adăugat deja acest eveniment. Actualizăm doar cu un nou apel în partea de jos. video.addEventListener ('pauză', funcție () play.title = 'Play'; play.innerHTML = '& # x25BA;' // Video a fost întreruptă, oprește progresul urmăririi videoPlayer.stopTrackingPlayProgress (); );
// Videoclipul a fost oprit, deci opriți actualizarea progresului. stopTrackingPlayProgress: funcția () clearTimeout (playProgressInterval);
Ultimul pas pe care îl vom acoperi în acest tutorial este detalierea modului de a "curăța" videoclipul, adică atunci când utilizatorul face clic pe bara de progres și derulează în sus și în jos videoclipul. Sunt sigur că tu ai îndeplinit această sarcină în mai multe ocazii. Nu Nu NU; aceste lucruri se fac automat. Trebuie să codificăm acea funcționalitate.
Rapid ... ține-ți respirația.
Funcția () progressHolder.addEventListener ("mousedown", funcția () videoPlayer.stopTrackingPlayProgress (); videoPlayer.playPause (); document.onmousemove = funcția (e) videoPlayer.setPlayProgress (e.pageX); progressHolder .onmouseup = funcția (e) document.onmouseup = null; document.onmousemove = null; video.play (); videoPlayer.setPlayProgress (e.pageX); videoPlayer.trackPlayProgress ();, adevărat); , setPlayProgress: funcție (clicX) var newPercent = Math.max (0, Math.min (1, (clickX - this.findPosX (progressHolder)) / progressHolder.offsetWidth)); video.currentTime = newPercent * video.durare; playProgressBar.style.width = newPercent * (progressHolder.offsetWidth) + "px"; , findPosX: funcție (progressHolder) var curleft = progressHolder.offsetLeft; în timp ce (progressHolder = progressHolder.offsetParent) curleft + = progressHolder.offsetLeft; curleft retur;
... și respirație. Să luăm această grămadă de linii de cod în linie.
videoPlayer.stopTrackingPlayProgress
pentru a șterge timpul de expirare pe care l-am creat mai sus. playPause
care se va ocupa, în acest caz, de întreruperea videoclipului. setPlayProgress
metodă. Nu există două modalități în acest sens; chestia asta este confuză, până când auzi brusc "clicul", ca să spun așa. Aceasta este, de obicei, procedată de un "Oooohhhhhh" extins. Dacă nu ați ajuns încă acolo, dacă ochii tăi nu ar putea ajuta decât să glazeze de-a lungul acestui tutorial lung, e în regulă. Citiți-o din nou, și, cel mai important, lucrați împreună. Numai așa vom crește. În al doilea rând, bucăți mari de c