Streaming plików video

0

Posiadam zewnętrzny link do pliku video:

$url = 'http://strona.pl/plik.flv';

Chcę na swojej stronie umożliwić oglądanie tego pliku, czyli nie pobieranie, a oglądanie filmu przez player typu jwplayer, flowplayer itp.
Kolejną sprawą jest fakt, że plik zapisany w zmiennej $url nie może być bezpośrednio odtwarzany z tego url tylko plik musi zostać jakby zapisany na moim serwerze FTP i dopiero wtedy odtworzony. W tym celu chciałem to zrobić mniej więcej tak: http://php.net/manual/en/function.fread.php#51720
Czyli pobieranie pliku do stringu i wyświetlanie go część po części - jeśli od razu chciałbym wyświetlić całość, nie dzieląc na party, dostałbym błąd typu: Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 2798048 bytes) in XXX.

Nie wiem zbytnio jednak jak się za to zabrać. Jakie nagłówki powinny być udostępnione, aby z tego finalnie wyszedł odtwarzacz, a nie plik możliwy do pobrania?
Kolejna sprawa - przy kilku próbach wygenerowania czegoś takiego musiałem czekać ok. 4 minuty na finał - to trochę długo :/

Jakieś porady jak to zrobić?
Dzięki.

0

Możesz jednocześnie zapisywać plik u siebie i jednocześnie go podawać użytkownikowi. Możesz spowodować takie działanie, że jeżeli użytkownik przerwie odtwarzanie, gdy cały plik się nie pobrał - u Ciebie ten plik dociągnie się do końca.
Żeby uniknąć tego fatal error - po prostu nie zapisuj całego pliku do zmiennej - w pętli pobieraj po 16KB np. i te 16KB zapisuj do pliku, wypluwaj przez echo, a potem rób flush() i ob_flush(), żeby pozbyć się treści, którą chcesz podać użytkownikowi z pamięci.

Największym problemem jest tu ogarnięcie nagłówków Range. Czyli - co, gdy użytkownik przewinie film gdzieś na środek. Ty chcesz zapisywać plik na swój serwer (zapewne po to, żeby potem nie ściągać go z zewnątrz jeszcze raz?), więc wtedy: albo ignorujesz takie żądanie, jeżeli plik z zewnątrz nie został jeszcze pobrany - albo decydujesz się nie zapisywać tego pliku u siebie wtedy - albo opcja trzecia - każdesz użytkownikowi czekać aż dociągniesz przynajmniej ten fragment u siebie (i tu ważne: jeżeli nie będziesz przerywał pobierania, gdy użytkownik kliknie w środek filmu [czyli wygeneruje nowe żądanie] - to plik z danego URL będzie dalej ściągany - tu masz przykład skryptu, który pozwala odczytywać plik, do którego aktualnie zapisujesz z innego źródła: http://stackoverflow.com/questions/3218895/php-how-to-read-a-file-live-that-is-constantly-being-written-to )

Generalnie nie rozpatrzyłeś wszystkich możliwych przypadków i co chcesz z nimi robić, więc porady są mocno ogólne.

Jeszcze jedna istotna rzecz - firmy hostingowe mają dosyć niskie limity na jednoczesne wykonywanie X skryptów php. U Ciebie jeżeli odtwarzanie filmów będzie szło poprzez skrypt w tym języku - to na stronie będziesz miał max ok. 8 oglądających (takie limity często widywałem). Zależy gdzie się hostujesz.

0

Dzięki za odpowiedź dobry człowieku bo już myślałem, że mnie wszyscy olali - nawet na stackoverflow.com nikt mi nie odpisał na ten temat.
Więc tak - mój hosting - linuxpl.com.

Co do pobierania pliku - chcę to właśnie tak zrobić, aby pobierać plik partiami i echować go na ekran (tworząc z tych kawałków klip video), ale nie zapisywać tego filmu u siebie na dysku.
Próbowałem to zrobić tak:

Plik filmy.php:

$url = 'http://strona.pl/film.flv';

header('Accept-Ranges: bytes');
header('Content-Type: video/flv');
header('Connection: keep-alive');
header ("Content-Length: " . filesize($url));
header('Content-Transfer-Encoding: binary');
header ("Content-Disposition: attachment; filename=file.flv");

$fd = fopen($url, "r");
while(!feof($fd))
{
	echo fread($fd, 4096);
	ob_flush();
}

index.html:

 <video width="320" height="240" controls>
  <source src="filmy.php" type="video/x-flv">
  Your browser does not support the video tag.
</video> 

Niestety, za cholerę nie mogę w tym HTMLu podać pliku z rozszerzeniem .php bo wypluwa błąd, że URL jest niepoprawny bądź też nie potrafi odczytać tego pliku. Nie wiem jak to ugryźć żeby to wszystko współgrało. Cały problem polega na tym, że mam dostęp do głównego pliku z filmem - plik znajduje się na zewnętrznym serwisie, jednak ten link do pliku jest generowany na podstawie IP, tak więc mój serwis jak pobierze przez CURLa ten URL to jest to link działający tylko dla mojego serwera. User, który wchodzi na moją stronę i dostanie wyechowany ten link na ekran - u niego to nie pójdzie ze względu na inne adresy IP. Wykombinowałem więc, że muszę pobrać partiami ten plik i stworzyć z niego jakby "live streaming". Trochę to ogólnie skomplikowane, najelpiej by było w tle pobrać ten link z tej strony z poziomu np. JS/Ajax, jednak ta strona chroni się ORIGIN POLICY (czy jakoś tak) i tutaj też jest problem, więc chyba to rozwiązanie jest najlepsze, jednak nie do końca chce to działac. Jakieś porady?

EDIT:

Kurde, udało mi się to odpalić za pomocą tego: http://stackoverflow.com/questions/2248800/play-flv-in-html :P Mimo wszystko, masz jakieś sugestie co do tego rozwiązania? Serio tylko kilka osób jednocześnie będzie mogło ogladać różne filmy na mojej stronie ?

EDIT 2:

Jednak trochę się pospieszyłem. Zauważyłem, że jeśli film zacznie lecieć i ssuwakiem przewinę film na końcówkę to ssuwak się tam rzeczywiście zatrzyma (na końcu), czas normalnie leci jakby film był powiedzmy na 143, jednak w rzeczywistości to jest ok. 2-3 minuta filmu. Po chwili ten czas się zatrzymuje w miejscu, mimo że film dalej normalnie leci. Wynika z tego, że ten player nie kontroluje tego czy film został pobrany w takiej ilości, aby można go było przewinąć do danej minuty. Da się jakoś nałożyć ograniczenie, że jeśli film nie pobrał się powiedzmy do tego czasu 143 to po prostu skrypt uniemożliwia ręczne przesunięcie do tego momentu?

EDIT 3:

Dostałem odpowiedź na stackoverflow.com, jednak szczerze mówiąc - nie wiem jak ten kod wykorzystać: http://stackoverflow.com/questions/29189551/videojs-play-without-fully-load-video/29192617#29192617
Gdzie powinny być zdefiniowane te nagłówki w przypadku wykrycia tego nagłówka RANGE ? W pętli? Przed nią? Po drugie, nagłówek RANGE trzeba jakoś zdefiniować czy on sam się wysyła w przypadku zmiany pozycji filmu?

0

Sorry że odkopuje takie archeo ale temat mi pasuje

kawałek kodu z index.html z flowplayera

[HTML] pobierz, plaintext

<body>
   <!-- the player -->
   <div class="flowplayer" data-swf="flowplayer.swf" data-ratio="0.4167">
      <video>
         <source type="video/webm" src="bauhaus.webm">
         <source type="video/mp4" src="bauhaus.mp4">
      </video>
   </div>
</body>

Pliki video trzymam w bazie danych (id,nazwa,typ,video). Nazwa to nazwa pliku, typ zapisuje mi video/mp4 a w kolumnę video (longblob) wrzucam mi film.

Jak zrobić by pobrać plik z bazy danych i odpalić go w flowplayer. Jak wstawiam w miejsce "bauhaus.webm" $video (plik mp4 z bazy danych) nie odpala filmu.
Jak to przebudować, ktoś dał rade ?

1 użytkowników online, w tym zalogowanych: 0, gości: 1