Snažil jsem se na to přijít sám, ale nesčetné množství možností mě jen zmátlo.
Chci ideálně použít buď ffmpeg
nebo mencoder
(nebo něco jiného, ale ty dva, o kterých vím, že pracuji) ) převést jakékoli příchozí video na pevnou velikost obrazovky.
Pokud je video širší nebo příliš krátké, vycentrujte jej. Pokud to není správná velikost, změna velikosti nahoru nebo dolů, aby to bylo přesně na pevnou velikost obrazovky.
Přesná poslední věc, kterou potřebuji, je 720×480 v XVid AVI se zvukovou stopou MP3.
Našel jsem spoustu stránek zobrazujících jak změnit velikost na maximální rozlišení, ale potřebuji, aby video bylo přesně v tomto rozlišení (s oříznutými extra částmi, bez černých pruhů).
Může mi někdo říct, aby se spustil příkazový řádek – nebo alespoň dostat mě na většinu / většinu cesty tam? Pokud to musí být více příkazových řádků (spusťte X, abyste získali rozlišení, udělejte th je výpočet a poté spusťte Y s výstupem tohoto výpočtu) mohu to skriptovat.
Komentáře
- Video zařízení podle všeho funguje také s Mpeg4 jako XVid AVI, pokud je to ‚ jednodušší / lepší.
Odpovědět
Nejsem žádný guru ffmpeg, ale to by mělo stačit.
Nejprve můžete získat velikost vstupního videa takto:
ffprobe -v error -of flat=s=_ -select_streams v:0 -show_entries stream=height,width in.mp4
S přiměřeně nedávným ffmpeg můžete změnit velikost videa pomocí těchto možností:
ffmpeg -i in.mp4 -vf scale=720:480 out.mp4
Můžete nastavit šířku nebo výšku do -1
, aby bylo možné ffmpeg
změnit velikost videa při zachování poměru stran. -2
je ve skutečnosti lepší volbou, protože vypočítaná hodnota by měla být sudá. Můžete tedy napsat:
ffmpeg -i in.mp4 -vf scale=720:-2 out.mp4
Jakmile získáte video, může být větší než očekávané 720x480
od necháte ffmpeg
vypočítat výšku, takže ji budete muset oříznout. Lze to provést takto:
ffmpeg -i in.mp4 -filter:v "crop=in_w:480" out.mp4
Nakonec můžete napsat takový skript (lze jej snadno optimalizovat, ale kvůli čitelnosti jsem ho udržel jednoduchý):
#!/bin/bash FILE="/tmp/test.mp4" TMP="/tmp/tmp.mp4" OUT="/tmp/out.mp4" OUT_WIDTH=720 OUT_HEIGHT=480 # Get the size of input video: eval $(ffprobe -v error -of flat=s=_ -select_streams v:0 -show_entries stream=height,width ${FILE}) IN_WIDTH=${streams_stream_0_width} IN_HEIGHT=${streams_stream_0_height} # Get the difference between actual and desired size W_DIFF=$[ ${OUT_WIDTH} - ${IN_WIDTH} ] H_DIFF=$[ ${OUT_HEIGHT} - ${IN_HEIGHT} ] # Let"s take the shorter side, so the video will be at least as big # as the desired size: CROP_SIDE="n" if [ ${W_DIFF} -lt ${H_DIFF} ] ; then SCALE="-2:${OUT_HEIGHT}" CROP_SIDE="w" else SCALE="${OUT_WIDTH}:-2" CROP_SIDE="h" fi # Then perform a first resizing ffmpeg -i ${FILE} -vf scale=${SCALE} ${TMP} # Now get the temporary video size eval $(ffprobe -v error -of flat=s=_ -select_streams v:0 -show_entries stream=height,width ${TMP}) IN_WIDTH=${streams_stream_0_width} IN_HEIGHT=${streams_stream_0_height} # Calculate how much we should crop if [ "z${CROP_SIDE}" = "zh" ] ; then DIFF=$[ ${IN_HEIGHT} - ${OUT_HEIGHT} ] CROP="in_w:in_h-${DIFF}" elif [ "z${CROP_SIDE}" = "zw" ] ; then DIFF=$[ ${IN_WIDTH} - ${OUT_WIDTH} ] CROP="in_w-${DIFF}:in_h" fi # Then crop... ffmpeg -i ${TMP} -filter:v "crop=${CROP}" ${OUT}
Komentáře
- Měl jsem takový legrační pocit, že ‚ mi chybí scénář, ale ‚ Zkusil jsem to se spoustou video souborů a zdá se, že videa správně ořezáváte a měníte jejich velikost na absolutně správnou velikost – výborně!
- Vypadá to, že s rozhodnutím CROP_SIDE není něco v pořádku.
- `# Získejte rychlost mezi skutečnou a požadovanou velikostí w_rate =
echo "scale=3; ${in_width}/${out_width}*1000"| bc | awk '{printf "%d", $0}'
h_rate =echo "scale=3; ${in_height}/${out_height}*1000"| bc | awk '{printf "%d", $0}'
# Let ‚ s vezme kratší stranu, takže video bude alespoň stejně velký jako požadovaná velikost a ořízněte delší stranu: crop_side = ‚ n ‚ pokud [$ {w_rate} -gt $ {h_rate}]; pak scale = “ -2: $ {out_height} “ crop_side = ‚ w ‚ else scale = “ $ {out_width}: – 2 “ crop_side = ‚ h ‚ fi `
odpověď
ffmpeg -i input.file -vf "scale=(iw*sar)*max(720/(iw*sar)\,480/ih):ih*max(720/(iw*sar)\,480/ih), crop=720:480" -c:v mpeg4 -vtag XVID -q:v 4 -c:a libmp3lame -q:a 4 output.avi
Nahraďte soubor„ input.file „názvem svého vstupního souboru.
Komentáře
- Toto by měla být nejlepší odpověď, protože ‚ nevyžaduje volání ffprobe. Poznamenejte si sekvence čárky zpětného lomítka v příkazu. Pokud ‚ umístíte příkaz do řetězce C / JavaScript / PHP, musíte ‚ uniknout zpětným lomítkům.
- Pěkně, Briane. Část video filtru je přesně to, co jsem také potřeboval. (tj. převést stará videa 4: 3 na 16: 9)!
- geniální! vše v jednom.
- Mnohem čistší než výše uvedený skript. Všimněte si, že pokud ‚ nechcete XVID / MP3, můžete tagy po druhé uvozovce jednoduše změnit na něco jako
-c:a copy scaled_result.mp4
- můžete mi vysvětlit, co ‚ s
sar
uvnitřiw*sar
Odpověď
Chcete-li oříznout a změnit měřítko najednou, můžete vytvořit řetěz filtrů oříznutí a zmenšení líbí se mi to:
ffmpeg -i SomeInput.mp4 -vf "crop=in_h*9/16:in_h,scale=-2:400" -t 4 SomeOutput.mp4
Výše uvedené nejprve ořízne video na portrét 16: 9, poté se zmenší na výšku 400px x příslušnou šířku (sudé číslo).
Odpověď
Jsem ve ffmpeg nový, ale nyní mám ve VB.NET pěkný malý převaděč, který vytváří syrové filmy různé výstupní formáty pro použití v malých zařízeních, která mají přístup na kartu SD, ale nemají dostatek energie na dekódování složitého videa.
Kvůli způsobu, jakým to funguje při změně velikosti a oříznutí, jsem to musel ručně kódovat a vytvořit parametry. V podstatě potřebuji znát výslednou šířku a výšku.
Mám 2 zaškrtávací políčka pro tyto možnosti: –
Zachovat poměr stran (X) Vyplnit všechny pixely (X)
Jako vstup jsou potřeba pouze 4 proměnné (1) Původní šířka videa, (2) Původní výška videa, (3) Šířka zařízení, (4) Výška zařízení.
Ačkoli pro VB.NET by se dalo docela snadno přizpůsobit pro jakýkoli jazyk.
Dim crop As String = "" " will build this in ffmpeg format for -s or scale and crop If cbAspectRatio.Checked = False Then m_dest_output_w = sz._w m_dest_output_h = sz._h " scale to w * h - simple crop = " -s " & m_dest_output_w & ":" & m_dest_output_h Else Dim ratio As Double = CDbl(m_video_width) / CDbl(m_video_height) " this is aspect ratio of original unsized video If cbFillPixels.Checked = False Then " shrink to fit If sz._w * ratio <= m_video_height Then m_dest_output_w = sz._w m_dest_output_h = sz._w / ratio Else m_dest_output_h = sz._h m_dest_output_w = sz._h / ratio End If " no cropping just resizing to a non-filled area that fits crop = " -s " & m_dest_output_w & ":" & m_dest_output_h " no cropping needed as letterboxed Else " expand / fill --- cropping needed If sz._w * ratio >= m_video_height Then m_dest_output_w = sz._w m_dest_output_h = sz._w * ratio crop = ",crop=" & sz._w & ":" & sz._h & ":0:" & Math.Abs((m_dest_output_h - sz._h)) \ 2 Else m_dest_output_h = sz._h m_dest_output_w = sz._h * ratio crop = ",crop=" & sz._w & ":" & sz._h & ":" & Math.Abs((m_dest_output_w - sz._w)) \ 2 & ":0" End If crop = " -vf scale=" & m_dest_output_w & ":" & m_dest_output_h & crop m_dest_output_w = sz._w m_dest_output_h = sz._h End If End If