Cortar com precisão arquivos de vídeo da linha de comando

22

Estou tendo problemas para encontrar um aplicativo CLI que pode pegar um arquivo de vídeo (avi, mkv e mp4, de preferência) e cortar clipes muito curtos (2-6 segundos) com precisão de tempo. Eu tentei ffmpeg , mencoder , avidemux e mp4box, mas todos eles cortam quadros-chave que criam clipes de mais de 6 segundos. Existe uma ferramenta que recodifique o arquivo de entrada e reduza o tempo exato ou corte imprecisa, recodifique e depois corte com precisão?

curmil
fonte
Você provavelmente terá que recodificar antes de cortar para acertar. Provavelmente, você pode acelerar as coisas cortando primeiro os quadros-chave ao redor e recodificando apenas os trechos.
Nifle 7/08/12
4
Qual comando FFmpeg você tentou, exatamente? Eu acredito que se você decodificar o vídeo antes (ou seja, coloque o -ssparâmetro depois -i ), ele deve ser mais preciso.
Slhck 7/08
1
O truque do FFmpeg funcionou! Não percebi que a ordem importava tanto. É o mesmo para qualquer uma das outras ferramentas?
Cursil 7/08
related- superuser.com/questions/1287650/…
barlop em 27/04

Respostas:

23

Cortando vídeo com ffmpeg

Você pode cortar vídeos com precisão com o FFmpeg. Desde a versão 2.5, é muito fácil. Por exemplo, isso reduziria 10 segundos, iniciando em 0 minutos, 3 segundos e 123 milissegundos.

ffmpeg -ss 00:00:03.123 -i input.mp4 -t 10 -c:v libx264 -c:a copy out.mp4

A posição e o tempo podem ser em segundos ou em hh:mm:ss[.xxx]forma.

Observe que, nesses exemplos, o vídeo será recodificado usando o codificador x264 ; o áudio é copiado.

Você também pode usar em -tovez de -tpara especificar o ponto final em vez da duração. Nesse caso, no entanto, -toé equivalente a -t, uma vez que, ao colocar a -ssfrente -i, o ffmpeg primeiro buscará esse ponto e depois começará a produzir.

Veja também a entrada do wiki Procurando .


Corte preciso para ffmpegversões mais antigas

Se você possui uma versão mais antiga do ffmpeg, para uma busca precisa, é necessário colocar o -ssafter -i, o que torna o processo de codificação um pouco mais lento, porque o vídeo inteiro precisa ser decodificado primeiro:

ffmpeg -i input.mp4 -ss 00:00:03.123 -t 10 -c:v libx264 -c:a copy out.mp4

Aqui, -toe -tse comporte de maneira diferente. -t 10criaria um clipe de dez segundos, enquanto -to 10criaria um clipe de sete segundos.

slhck
fonte
Em vez de -c:v libx264 -c:a libfaaceu acho que podemos usar o -acodec copy -vcodec copyque diz ao ffmpeg apenas para detectar e usar os mesmos codecs que o arquivo original. Alguém pode confirmar?
Baodad
2
@Baodad Você pode, mas isso não vai com precisão cortar. Ao copiar fluxos de bits de vídeo / áudio, o ffmpeg precisa iniciar em um quadro-chave, que pode ser colocado a cada segundo ou ainda mais distante.
slhck
Como superar o erro "codificador desconhecido 'libfaac'"?
Doug
@Doug Escolha um codificador diferente, por exemplo -c:a aac -strict experimental. Essa é a solução mais simples.
slhck
1

A única ferramenta de linha de comando do Linux que eu encontrei até agora, que pode cortar no quadro exato (ou, com precisão), é melt( sudo apt-get install melt).

Digamos que você tenha inputvid.mp4- primeiro verifique suas configurações de codificação com o say ffmpeg(aqui, eu apenas digo que quero codificá-lo novamente para -f mp4, mas como o arquivo /dev/nullpara que a saída seja descartada; eu redireciono o stderr para que eu possa fazer a grep - observe no meio , o comando solicita e você deve responder ycom ENTER, para que o processo prossiga e despeje as informações úteis; isso é com o ffmpeg 3.3.3 no Ubuntu 14):

ffmpeg -i inputvid.mp4 -f mp4 /dev/null 2>&1 | grep 'Stream\|encoder'
    Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p(tv, bt709), 640x360 [SAR 1:1 DAR 16:9], 389 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 95 kb/s (default)
y
File '/dev/null' already exists. Overwrite ? [y/N] Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (aac (native) -> aac (native))
    encoder         : Lavf57.71.100
    Stream #0:0(und): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p(progressive), 640x360 [SAR 1:1 DAR 16:9], q=-1--1, 23.98 fps, 24k tbn, 23.98 tbc (default)
      encoder         : Lavc57.89.100 libx264
    Stream #0:1(und): Audio: aac (LC) ([64][0][0][0] / 0x0040), 44100 Hz, stereo, fltp, 128 kb/s (default)
      encoder         : Lavc57.89.100 aac

Ok, para que possamos ver ffmpegescolhas libx264e aaccodificadores para este vídeo; então podemos inserir isso para melt:

melt inputvid.mp4 in=7235 out=7349 -consumer avformat:cut.mp4 acodec=aac vcodec=libx264

.... e meltcortará com a peça entre os quadros 7235 e 7349 em um novo arquivo cut.mp4. Em seguida, para verificar se os cut.mp4loops estão corretos, use meltnovamente para reproduzi-lo duas vezes - e reproduza-o em uma janela SDL:

melt cut.mp4 cut.mp4 -consumer sdl

... e aqui está o que ffmpegvê para este arquivo:

ffmpeg -i cut.mp4 -f mp4 /dev/null 2>&1 | grep 'Stream\|encoder'    encoder         : Lavf54.20.4
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 640x360 [SAR 1:1 DAR 16:9], 526 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 182 kb/s (default)
y
File '/dev/null' already exists. Overwrite ? [y/N] Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (aac (native) -> aac (native))
    encoder         : Lavf57.71.100
    Stream #0:0(und): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p, 640x360 [SAR 1:1 DAR 16:9], q=-1--1, 23.98 fps, 24k tbn, 23.98 tbc (default)
      encoder         : Lavc57.89.100 libx264
    Stream #0:1(und): Audio: aac (LC) ([64][0][0][0] / 0x0040), 48000 Hz, stereo, fltp, 128 kb/s (default)
      encoder         : Lavc57.89.100 aac

As configurações de codificação de vídeo cut.mp4parecem idênticas, inputvid.mp4exceto a taxa de bits do vídeo alterada de 389 kb / s para 526 kb / s, e também as configurações de codificação de áudio são praticamente as mesmas, exceto a taxa de amostragem alterada de 44100 para 48000 Hz; embora isso possa ser regulado com:

melt inputvid.mp4 in=7235 out=7349 -consumer avformat:cut.mp4 acodec=aac ar=44100 ab=95k vcodec=libx264 vb=389k

... no entanto, mesmo com isso, a taxa de bits final do vídeo para mim acaba com 337 kb / s. Ainda assim, os cortes fazem um loop fino (e isso inclui áudio) quando reproduzidos em um loop, então acho que isso é realmente preciso do quadro ...

sdaau
fonte
1
meltestá recodificando o vídeo e usa as bibliotecas FFmpeg abaixo. Se você permitir a recodificação, o ffmpeg poderá produzir a mesma saída.
Gyan
Obrigado @Gyan - não sabia disso (especialmente que meltusa bibliotecas FFmpeg), bom saber!
sdaau 18/01
O derretimento parece mais fácil de usar do que o ffmpeg, tudo o que precisamos é uma maneira de especificar os tempos, particularmente os horários em h, min, sec ou hr, min, sec, ms, que os converte no quadro correto.
barlop 27/04
0

Como Baodad disse nos comentários (eu posto porque não é fácil encontrar se você lê rapidamente), a melhor abordagem é detectar os codificadores de áudio / vídeo automaticamente pelo ffmpeg, então:

ffmpeg -ss 00:05:17.18 -i in.mp4 -t 00:06:29.10 -acodec copy -vcodec copy out.mp4 
  • start @ 00: 05: 17.18
  • input = in.mp4
  • stop @ 00: 06: 29.10
  • output = out.mp4
Gilles Quenot
fonte
2
Isso não recodifica e não fornece precisão de quadro.
Andrea Lazzarotto 17/02