W jednym ze swoich poprzednich tematów pytałem o możliwość pobrania pliku mp4 z serwisu, który nie udostępnia bezpośredniego linka do niego. Otrzymałem wówczas poradę, jak zrobić to przy użyciu curl’a, która działa znakomicie. Chciałbym teraz zapytać, czy przy użyciu tej samej metody da się ściągnąć plik mp4 i zapisać go w rozdzielczości mniejszej niż oryginalna. Np. plik 1080p zapisać jako 720p.
Puść go przez ffmpeg
@hindus, weźmy taki przykład:
curl 'https://stream.vider.info/video/263523/v.mp4?uid=0' \
-H 'authority: stream.vider.info' \
-H 'accept: */*' \
-H 'accept-language: pl-PL,pl;q=0.9,en-US;q=0.8,en;q=0.7' \
-H 'cookie: _ga=GA1.1.1754579214.1666461710; euconsent-v2=CPhP_kAPhP_kAAKAsAPLCmCsAP_AAH_AAB5YJFNd_H__bW9r-f5_aft0eY1P9_r37uQzDhfNk-8F3L_W_LwX52E7NF36tq4KmR4ku1LBIUNlHMHUDUmwaokVryHsak2cpzNKJ7BEknMZOydYGF9vmxtj-QKY7_5_d3bx2D-t_9v239z3z81Xn3d53-_03LCdV5_9Dfn9fR_bc9KPt_58v8v8_____3_e__3_7997BIgAkw1biALsyxwZtAwigRAjCsJCqBQAQUAwtEBgA4OCnZWAT6wgQAIBQBGBECHAFGBAIAABIAkIgAkCLBAAACIBAACABEIhAAwMAgsALAwCAAEA0DFEKAAQJCDIgIilMCAqBIIDWyoQSgukNMIA6ywAoJEbFQAIgkBFYAAgLBwDBEgJWLBAkxRvkAIwQoBRKhWogAAA.YAAAAAAAAAAA; addtl_consent=1~39.4.3.9.6.9.13.6.4.15.9.5.2.7.4.1.7.1.3.2.10.3.5.4.21.4.6.9.7.10.2.9.2.18.7.6.14.5.20.6.5.1.3.1.11.29.4.14.4.5.3.10.6.2.9.6.6.9.4.4.29.4.5.3.1.6.2.2.17.1.17.10.9.1.8.6.2.8.3.4.146.8.42.15.1.14.3.1.8.10.25.3.7.25.5.18.9.7.41.2.4.18.21.3.4.2.7.6.5.2.14.18.7.3.2.2.8.20.8.8.6.3.10.4.20.2.13.4.6.4.11.1.3.22.16.2.6.8.2.4.11.6.5.33.11.8.1.10.28.12.1.3.21.2.7.6.1.9.30.17.4.9.15.8.7.3.6.6.7.2.4.1.7.12.13.22.13.2.12.2.10.1.4.15.2.4.9.4.5.4.7.13.5.15.4.13.4.14.8.2.15.2.5.6.2.2.1.2.14.7.4.8.2.9.10.18.12.13.2.18.1.1.3.1.1.9.25.4.1.19.8.4.5.3.5.4.8.4.2.2.2.14.2.13.4.2.6.9.6.3.4.3.5.2.3.6.10.11.6.3.16.3.11.3.1.2.3.9.19.11.15.3.10.7.6.4.3.4.6.3.3.3.3.1.1.1.6.11.3.1.1.11.6.1.10.5.2.6.3.2.2.4.3.2.2.7.15.7.12.2.1.3.3.4.5.4.3.2.2.5.3.1.1.1.2.9.1.6.9.1.5.2.1.7.10.11.1.3.1.1.2.1.3.2.6.1.12.5.3.1.3.1.1.2.2.7.7.1.4.1.2.6.1.2.1.1.3.1.1.4.1.1.2.1.8.1.7.4.3.2.1.3.5.3.9.6.1.15.10.28.1.2.2.12.3.4.1.6.3.4.7.1.3.1.1.3.1.5.3.1.3.4.1.1.4.2.1.2.1.2.2.2.4.2.1.2.2.2.4.1.1.1.2.2.1.1.1.1.2.1.1.1.2.2.1.1.2.1.2.1.7.1.2.1.1.1.2.1.1.1.1.2.1.1.3.2.1.1.8.1.1.6.2.1.6.5.1.1.1.1.1.2.2.3.1.1.4.1.1.2.2.1.1.4.3.1.2.2.1.2.1.2.3.1.1.2.4.1.1.1.5.1.3.6.3.1.5.2.3.4.1.2.3.1.4.2.1.2.2.2.1.1.1.1.1.1.11.1.3.1.1.2.2.5.2.3.3.5.1.1.1.4.2.1.1.2.5.1.9.4.1.1.3.1.7.1.4.5.1.7.2.1.1.1.2.1.1.1.4.2.1.12.1.1.3.1.2.2.3.1.2.1.1.1.2.1.1.2.1.1.1.1.2.4.1.5.1.2.4.3.8.2.2.9.7.2.2.1.2.1.4.6.1.1.6.1.1.2.6.3.1.2; cookie_v12stream_hostname=freedisc-n5; cookie_v12viderinfoo12_sessions=a%3A7%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%227e3b579ac642eca6fce8ec745dde3ee4%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A10%3A%2283.4.15.40%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A110%3A%22Mozilla%2F5.0+%28Windows+NT+6.1%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F106.0.0.0+Safari%2F537.36%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1666615692%3Bs%3A9%3A%22user_data%22%3Bs%3A0%3A%22%22%3Bs%3A8%3A%22language%22%3Bs%3A2%3A%22pl%22%3Bs%3A14%3A%22file_last_view%22%3Bs%3A6%3A%22263521%22%3B%7D3d1ef64a986acc87e6c910a9fc7a462a; cookie_v12last_item_id=263523; cookie_v12sess_ebdd=YToxOntzOjQ6InRpbWUiO2k6MTY2NjYxNTkzMzt9; _ga_VP1P70Q01K=GS1.1.1666611426.2.1.1666615933.0.0.0; _ga_3YMP2VEBVF=GS1.1.1666611426.2.1.1666615933.0.0.0' \
-H 'range: bytes=0-' \
-H 'referer: https://vider.info/' \
-H 'sec-ch-ua: "Chromium";v="106", "Google Chrome";v="106", "Not;A=Brand";v="99"' \
-H 'sec-ch-ua-mobile: ?0' \
-H 'sec-ch-ua-platform: "Windows"' \
-H 'sec-fetch-dest: video' \
-H 'sec-fetch-mode: no-cors' \
-H 'sec-fetch-site: same-site' \
-H 'user-agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36' \
--compressed -o /home/rostov/domains/rostov.smallhost.pl/public_html/seriale/S01E04.mp4 &>/dev/null &
Jak powinienem to zrobić?
Tak naprawdę musisz przekodować cały materiał. Dokładnie najlepiej ffmpeg
ale nie poprzez potok z curl
tylko wykorzystując wewnętrzną obsługę http w ffmpeg, czyli musisz przerobić nagłówki na postać zrozumiałą dla ffmpeg (zwróć uwagę na zapis, w ffmpeg podajesz nagłówki w jednym parametrze, ffmpeg jest bardzo wrażliwy np na dodatkowe puste linie podane w -headers, wtedy odmawia współpracy) :
ffmpeg -headers $'authority: stream.vider.info
accept: */*
accept-language: pl-PL,pl;q=0.9,en-US;q=0.8,en;q=0.7
cookie: _ga=GA1.1.1754579214.1666461710; euconsent-v2=CPhP_kAPhP_kAAKAsAPLCmCsAP_AAH_AAB5YJFNd_H__bW9r-f5_aft0eY1P9_r37uQzDhfNk-8F3L_W_LwX52E7NF36tq4KmR4ku1LBIUNlHMHUDUmwaokVryHsak2cpzNKJ7BEknMZOydYGF9vmxtj-QKY7_5_d3bx2D-t_9v239z3z81Xn3d53-_03LCdV5_9Dfn9fR_bc9KPt_58v8v8_____3_e__3_7997BIgAkw1biALsyxwZtAwigRAjCsJCqBQAQUAwtEBgA4OCnZWAT6wgQAIBQBGBECHAFGBAIAABIAkIgAkCLBAAACIBAACABEIhAAwMAgsALAwCAAEA0DFEKAAQJCDIgIilMCAqBIIDWyoQSgukNMIA6ywAoJEbFQAIgkBFYAAgLBwDBEgJWLBAkxRvkAIwQoBRKhWogAAA.YAAAAAAAAAAA; addtl_consent=1~39.4.3.9.6.9.13.6.4.15.9.5.2.7.4.1.7.1.3.2.10.3.5.4.21.4.6.9.7.10.2.9.2.18.7.6.14.5.20.6.5.1.3.1.11.29.4.14.4.5.3.10.6.2.9.6.6.9.4.4.29.4.5.3.1.6.2.2.17.1.17.10.9.1.8.6.2.8.3.4.146.8.42.15.1.14.3.1.8.10.25.3.7.25.5.18.9.7.41.2.4.18.21.3.4.2.7.6.5.2.14.18.7.3.2.2.8.20.8.8.6.3.10.4.20.2.13.4.6.4.11.1.3.22.16.2.6.8.2.4.11.6.5.33.11.8.1.10.28.12.1.3.21.2.7.6.1.9.30.17.4.9.15.8.7.3.6.6.7.2.4.1.7.12.13.22.13.2.12.2.10.1.4.15.2.4.9.4.5.4.7.13.5.15.4.13.4.14.8.2.15.2.5.6.2.2.1.2.14.7.4.8.2.9.10.18.12.13.2.18.1.1.3.1.1.9.25.4.1.19.8.4.5.3.5.4.8.4.2.2.2.14.2.13.4.2.6.9.6.3.4.3.5.2.3.6.10.11.6.3.16.3.11.3.1.2.3.9.19.11.15.3.10.7.6.4.3.4.6.3.3.3.3.1.1.1.6.11.3.1.1.11.6.1.10.5.2.6.3.2.2.4.3.2.2.7.15.7.12.2.1.3.3.4.5.4.3.2.2.5.3.1.1.1.2.9.1.6.9.1.5.2.1.7.10.11.1.3.1.1.2.1.3.2.6.1.12.5.3.1.3.1.1.2.2.7.7.1.4.1.2.6.1.2.1.1.3.1.1.4.1.1.2.1.8.1.7.4.3.2.1.3.5.3.9.6.1.15.10.28.1.2.2.12.3.4.1.6.3.4.7.1.3.1.1.3.1.5.3.1.3.4.1.1.4.2.1.2.1.2.2.2.4.2.1.2.2.2.4.1.1.1.2.2.1.1.1.1.2.1.1.1.2.2.1.1.2.1.2.1.7.1.2.1.1.1.2.1.1.1.1.2.1.1.3.2.1.1.8.1.1.6.2.1.6.5.1.1.1.1.1.2.2.3.1.1.4.1.1.2.2.1.1.4.3.1.2.2.1.2.1.2.3.1.1.2.4.1.1.1.5.1.3.6.3.1.5.2.3.4.1.2.3.1.4.2.1.2.2.2.1.1.1.1.1.1.11.1.3.1.1.2.2.5.2.3.3.5.1.1.1.4.2.1.1.2.5.1.9.4.1.1.3.1.7.1.4.5.1.7.2.1.1.1.2.1.1.1.4.2.1.12.1.1.3.1.2.2.3.1.2.1.1.1.2.1.1.2.1.1.1.1.2.4.1.5.1.2.4.3.8.2.2.9.7.2.2.1.2.1.4.6.1.1.6.1.1.2.6.3.1.2; cookie_v12stream_hostname=freedisc-n5; cookie_v12viderinfoo12_sessions=a%3A7%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%227e3b579ac642eca6fce8ec745dde3ee4%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A10%3A%2283.4.15.40%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A110%3A%22Mozilla%2F5.0+%28Windows+NT+6.1%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F106.0.0.0+Safari%2F537.36%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1666615692%3Bs%3A9%3A%22user_data%22%3Bs%3A0%3A%22%22%3Bs%3A8%3A%22language%22%3Bs%3A2%3A%22pl%22%3Bs%3A14%3A%22file_last_view%22%3Bs%3A6%3A%22263521%22%3B%7D3d1ef64a986acc87e6c910a9fc7a462a; cookie_v12last_item_id=263523; cookie_v12sess_ebdd=YToxOntzOjQ6InRpbWUiO2k6MTY2NjYxNTkzMzt9; _ga_VP1P70Q01K=GS1.1.1666611426.2.1.1666615933.0.0.0; _ga_3YMP2VEBVF=GS1.1.1666611426.2.1.1666615933.0.0.0
range: bytes=0-
referer: https://vider.info/
sec-ch-ua: "Chromium";v="106", "Google Chrome";v="106", "Not;A=Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
sec-fetch-dest: video
sec-fetch-mode: no-cors
sec-fetch-site: same-site
user-agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36
' -i https://stream.vider.info/video/263523/v.mp4?uid=0 -vf scale=1280:720 -preset slow -crf 18 output.mp4
Dobierz sobie preset
oraz crf
zgodnie z Encode/H.264 – FFmpeg, możesz ich nie podawać, wtedy zostaną użyte wartości domyślne.
Jeżeli na końcu podasz
-i https://stream.vider.info/video/263523/v.mp4?uid=0 -v trace
to uzyskasz informacje o wideo, zamiast konwersji. Przydatne, bo od razu widać np w jakiej rozdzielczości jest materiał źródłowy (pod linkiem, który podałeś jest film o rozdzielczości 480x272 ).
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'https://stream.vider.info/video/263523/v.mp4?uid=0':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf55.0.100
Duration: 00:43:41.33, start: 0.000000, bitrate: 342 kb/s
Stream #0:0(und), 3, 1/15360: Video: h264 (High), 1 reference frame (avc1 / 0x31637661), yuv420p(left), **480x272** [SAR 34:45 DAR 4:3], 0/1, 225 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(pol), 1, 1/48000: Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 108 kb/s (default)
Metadata:
handler_name : SoundHandler
Czyli w tym przypadku wykona się skalowanie w górę z 420p do 720p co nie da żadnego zysku, a plik wynikowy będzie większy.
To nawet nie jest 420p a 272p:
video - what exactly mean 2160p, 1440p, 1080p, ... 144p? - Stack Overflow
To oczywiste, że określając rozdzielczość video, podaje się ilość linii w pionie.
Używając akurat tego filmu, chciałem tylko pokazać, w jaki sposób go ściągam przy użyciu curl’a. Rozdzielczość źródła nie miała w tym przypadku znaczenia, bo wiadomo, że konwersja z mniejszej do większej przynosi pogorszenie jakości.
A to nie lepiej użyć programu HandBrake?
Możesz przekonwertować plik na format H.254 lub H.265 z kompresją i jakość pliku będzie niezauważalna a odczuwalnie mniejsza.
Program jest darmowy i ma masę możliwości,
polecam pobawić się https://handbrake.fr/
Gorzej jak antyczne CPU/GPU i będzie tylko męczyć komputer.
Nie bardzo. Potrzebuję czegoś, co mogę uruchomić na shellu, ponieważ nie dysponuję zbyt dobrym łączem, a do tego niektóre serwisy streamingowe mają nienajlepsze serwery, które przy wielu userach działają jeszcze gorzej, co w łącznym rezultacie powoduje, że ściągnięcie filmu w lepszej jakości czasem zajmuje kilka/kilkanaście godzin. Na shellu odpalam i później przynajmniej ściągam z szybkiego serwera. Ale pojemność mam ograniczoną do 5 GB, więc potrzebuję czegoś, co ściągnie i przekonwertuje video do 720p (tyle do oglądania mi wystarczy).
Wklejone przeze mnie polecenie ffmpeg
dokładnie to robi, tj konwersja w locie. Pobiera, konwertuje i zapisuje do pliku. Wszystko na shellu, no chyba że nie masz tam ffmpeg
to musisz doinstalować, powinno się dać bez roota.
No fakt
Troszkę źle sformułowałem pytanie. Chodzi o to, że chcę takie ściąganie z konwersją odpalić na koncie shell, które ma pojemność 5 GB. Często natomiast potrzebuję ściągnąć kilkugodzinne video, które ma kilkanaście GB. Dlatego zastanawia mnie, czy to polecenie, żeby dokonać konwersji, musi najpierw dokonać ściągnięcia całego pliku video.
Polecenie ffmpeg
które podałem zapisuje na dysk tylko plik po konwersji. Jednym słowem dane kompresowane są w locie bez żadnego pośredniego pliku. Jeżeli materiał ma 12GB ale dobierzesz parametry kompresji/rozdzielczość tak aby plik wynikowy dał około 3GB, to zapisany zostanie tylko ten plik 3GB.
@Bradlee, pozwolę sobie zadać jeszcze 2 pytania:
-
W podanym przez Ciebie przykładzie użyłeś parametru:
scale=1280:720
. Czy można podać tylko wysokość, aby szerokość była proporcjonalna względem źródła? -
Czy da się jakoś obliczyć, jaką wartość parametrów
preset
orazcrf
dobrać, przy rozdzielczości720p
, aby otrzymać plik wynikowy o określonej wielkości?
Skalowanie proporcjonalne uzyskasz z podając -1
jako jeden z wymiarów. Zobacz Scaling – FFmpeg → Keeping the Aspect Ratio. Niestety to nie zawsze zadziała, np gdy szerokość względem wysokości da w przeliczeniu jakiś ułamek, to ffmpeg zwróci błąd i wtedy musisz podać oba wymiary.
Dobre pytanie, chyba trzeba metodą prób i błędów, podobna dyskusja toczy się tutaj filesize - How to calculate ffmpeg output file size? - Stack Overflow