2013-10-08 14 views
47

Oglądałem wideo z youtube i postanowiłem zbadać niektóre części jego odtwarzacza wideo. Zauważyłem, że w przeciwieństwie do większości filmów HTML5, które widziałem, odtwarzacz wideo Youtube nie robi normalnego źródła wideo i zamiast tego wykorzystuje adres URL typu blob jako źródło.Jak działa buforowanie odtwarzacza wideo HTML5 w odtwarzaczu Youtube?

Poprzednio testowałem wideo HTML5 i stwierdziłem, że serwer rozpoczyna przesyłanie strumieniowe całego wideo od początku i buforuje w tle całą resztę wideo. Oznacza to, że jeśli twoje wideo ma 300 megabajtów, zostaną pobrane wszystkie 300 megabajtów. Jeśli szukasz środka, rozpocznie się pobieranie od pozycji szukania aż do końca.

Youtube nie działa w ten sposób (przynajmniej w wersji chromowanej). Zamiast tego może kontrolować buforowanie, więc buforuje tylko pewną ilość podczas pauzy. Wydaje się również, że buforuje tylko odpowiednie fragmenty, więc jeśli pominiesz to, upewnij się, że nie chcesz buforować fragmentów, które raczej nie będą oglądane.

Podczas moich prób zbadania, w jaki sposób zadziałało, zauważyłem, że tag src wideo ma wartość blob:http%3A//www.youtube.com/ee625eee-2802-49b2-a13f-eb374d551d54, która wskazywała mi na blobs, która następnie doprowadziła mnie do typed arrays. Korzystając z tych dwóch zasobów, mogę załadować wideo MP4 do obiektu typu blob i wyświetlić go w tagu wideo HTML5.

Jednak ja utknąłem na tym, jak Youtube radzi sobie z kawałkami. Patrząc na ruch sieciowy, wydaje się, że wysyła żądania do http://r6---sn-p5q7ynee.c.youtube.com/videoplayback, które zwracają binarne dane wideo z powrotem w porcjach o wielkości 1,1 MB. Warto również zauważyć, że większość normalnych żądań związanych z żądaniami wideo HTML5 wydaje się otrzymywać kod odpowiedzi 206 podczas przesyłania strumieniowego, ale połączenia play-video youtube otrzymują 200 kopii.

Próbowałem usiłować załadować tylko zakres bajtów (poprzez ustawienie nagłówka http Range), co niestety nie powiodło się (zakładam, ponieważ nie było meta-danych dla wideo przychodzącego z wideo).

W tym momencie utknąłem na zastanawianiu się, w jaki sposób Youtube to osiąga. Wpadłem na kilka pomysłów, ale żadna z nich nie została całkowicie sprzedana:

1) Youtube wysyła osobne fragmenty wideo i audio do każdego połączenia /videoplayback. Wydaje się, że jest to dość duże obciążenie po stronie przesyłania i wydaje się, że trudno byłoby połączyć je tak, aby wyglądało na to, że jest to jedno nieczytelne wideo. Ponadto tag wideo wydaje się myśleć, że jest to jeden pełny film, sądząc po wywołaniu $('video').duration i $('video').currentTime, co prowadzi mnie do przekonania, że ​​tag wideo myśli, że jest to pojedynczy plik wideo. Na koniec tag vrc-a src nigdy się nie zmienia, co sprawia, że ​​wierzę, że działa z pojedynczym blobem, a nie z przełączaniem obiektów typu blob.

2) Youtube konstruuje pusty obszar typu blob, który jest wstępnie dopasowany do pełnej tablicy wideo i aktualizuje obiekt typu blob z fragmentami podczas jego pobierania. Wtedy upewniłby się, że użytkownik nie zbliżył się zbytnio do ostatnio pobranego elementu (aby uniemożliwić użytkownikowi wejście do niedoładowanej sekcji obiektu typu blob). Problem, który widzę z tym, że nie widzę żadnego sposobu, aby dynamicznie aktualizować blob za pośrednictwem javascript (chociaż może mam problem z googlowaniem)

3) Youtube pobiera metadane, a następnie zaczyna budować kolejność blobów poprzez dołączanie elementów wideo podczas ich pobierania. Problem, który widzę za pomocą tej metody, nie rozumiem, w jaki sposób poradzi sobie z wyszukiwaniem w obszarze po buforowaniu. .

Może ja "jestem po prostu brakuje oczywistą odpowiedź, która znajduje się tuż przede mną Ktoś ma jakieś pomysły


edit: Pomyślałem czwartego wariantu.Innym pomysłem jest to, że mogą użyć interfejsu API pliku, aby zapisać fragmenty binarne do pliku i użyć tego pliku do streamowania. Wygląda na to, że API pliku ma możliwość wyszukiwania określonych pozycji, co pozwala na wypełnienie filmu pustymi bajtami i wypełnienie ich w momencie ich otrzymania. Z pewnością będzie to również dotyczyło poszukiwania wideo.

+0

Myślałem, że użyli [MediaStream API] (https://developer.mozilla.org/en-US/docs/Web/API/MediaStream_API), ale do tej pory byłem zbyt leniwy, aby w pełni zbadać. Proszę, daj mi znać! =) – Rudie

+0

Różni się od [MediaSource API] (http://updates.html5rocks.com/2011/11/Stream-video-using-the-MediaSource-API) .... – Rudie

+0

Interesujące API, chociaż brakuje mu całkiem kilka rzeczy, które będą potrzebne (na przykład sposób na rozpoczęcie), chyba że czytam rzeczy niepoprawnie. Tak czy inaczej nie pracuję w firmie, w której pracowałem, gdzie prowadziłem te badania i nie wiem, kiedy wrócę do tego typu rzeczy :) – KallDrexx

Odpowiedz

6

Gdy spojrzysz na AppData GoogleChrome, podczas odtwarzania filmu z YouTube zobaczysz, że buforuje w segmencie plików. Filmy przesłane do youtube są podzielone na segmenty, dlatego nie można dokładnie wskazać ram czasowych w pierwszym kliknięciu na pasku, jeśli ten okres jest poza bieżącym segmentem.

Liczba segmentów zależy od długości filmu oraz od czasu rozpoczęcia i zakończenia odtwarzania wideo.

Po połączeniu z ramką czasową filmu po prostu pominie buforowanie segmentów, które pojawią się przed tym okresem.

Niestety nie wiem zbyt wiele na temat kodowania odtwarzania wideo, ale mam nadzieję, że wskaże to właściwy kierunek.

+2

Interesujące, widzę wiele plików dodawanych do mojego katalogu AppData \ Local \ Google \ Chrome \ Dane użytkownika \ Default \ Cache, a sądząc po ruchu w sieci pliki o wielkości 1,1 MB to porcje wideo.Pozostaje pytanie, w jaki sposób połączyć je razem. Dzięki :) – KallDrexx

4

Youtube używa tej funkcji tylko w przeglądarkach obsługujących rozszerzenia Media Source Extensions, więc to zależy od przeglądarki, która decyduje o całej reszcie z powodu tej funkcji.

4

znajduje się element płótno na stronie, Może to pomoże http://html5doctor.com/video-canvas-magic/

wiedzieliśmy film jest już na segmenty, pytanie brzmi jak zszyć je together.i myśleć element prawdziwy film nie robi praca odtwórz, wspierać źródło danych i narysować seagments każdą klatkę do elementu canvas.

var v = document.getElementById('v'); 
var canvas = document.getElementById('c'); 
v.addEventListener('play', function(){ 
    if(v.paused || v.ended) return false; 
    c.drawImage(v,0,0,w,h); 
    setTimeout(draw,20,v,c,w,h); 
},false); 

+0

Proszę wyjaśnić swoją odpowiedź nieco więcej (być może poprzez dodanie niektórych informacji z podanego linku). Odpowiedzi dotyczące wyłącznie linków są odradzane. – soktinpk

+0

Przepraszam, mój angielski jest kiepski. Wiedzieliśmy, że film został podzielony na segmenty. Pytanie brzmi: jak połączyć je ze sobą.i uważamy, że prawdziwy element wideo nie działa w trybie odtwarzania, obsługuje źródła danych i rysuje seagmenty w każdej klatce do elementu płótna ... – vetch

+0

Jeśli umieścisz to w swojej odpowiedzi, powrócę do głosu. – soktinpk

3

Ok, więc kilka rzeczy, które trzeba wiedzieć, że YouTube opiera się na tym wielkim open source Project. Zachowuje się inaczej w przypadku każdej przeglądarki i jeśli twoja przeglądarka obsługuje bardziej intensywne dekodowanie, takie jak WEBM, będzie to wykorzystywać do oszczędzania przepustowości sieci Google. Także jeśli spojrzysz na to Demo Następnie znajdziesz sekcję, która pobiera cały film wideo do rzeczy zwanej "offline storage". Wiem, że Chrome ma to i kilka innych przeglądarek nie każdy, w niektórych przypadkach muszą korzystać z całego źródła wideo zamiast kropli. Tak więc strumień blobowy jest przesyłany strumieniowo w zależności od interakcji użytkownika z wideo. Tak, film jest tylko 1 plikiem i ma metadane tego filmu, takie jak mała baza danych, która informuje o czasie filmu i punktach, w których można podzielić porcje.

Możesz dowiedzieć się więcej czytając dokumentację Projektu . Naprawdę polecam obejrzeć demo.

Powiązane problemy