Usando ffmpeg para cortar vídeo


333

Estou usando o ffmpeg para cortar uma seção de um arquivo grande como este:

ffmpeg -i input.wmv -ss 60 -t 60 -acodec copy -vcodec copy output.wmv

A -sspeça funciona bem, mas -té ignorada. Ele remove corretamente os segundos iniciais especificados especificados com, -ssmas continua indo para o final da entrada com a cópia.

Existe uma maneira de usar o ffmpeg para cortar o final de um vídeo sem recodificá-lo?


1
esta sintaxe está correta.
Jggunjer

Respostas:


394

Você pode usar a -ssopção para especificar um registro de data e hora de início e a -topção para especificar a duração da codificação. Os registros de data e hora precisam estar no HH:MM:SS.xxxformato ou em segundos ( s.msec).

O seguinte cortaria os primeiros 30 segundos e, em seguida, cortaria tudo o que fosse 10 segundos depois:

ffmpeg -ss 00:00:30.0 -i input.wmv -c copy -t 00:00:10.0 output.wmv
ffmpeg -ss 30 -i input.wmv -c copy -t 10 output.wmv

Observe que -té uma opção de saída e sempre precisa ser especificada depois -i .

Algumas dicas:

  • Para versões mais antigas do ffmpeg, se você usar -ssdepois -i, obterá uma busca mais precisa às custas de uma execução mais lenta. Veja também: Procurando com o FFmpeg
  • Você pode usar, em -tovez de, -tpara especificar o carimbo de data e hora no qual deseja cortar. Então, em vez de -i <input> -ss 30 -t 10você também poderia fazer -i <input> -ss 30 -to 40para conseguir a mesma coisa.

  • Se o seu ffmpeg não suportar -c, ou -toprovavelmente está desatualizado. Compile você mesmo uma nova versão ou faça o download de uma versão estática da página inicial. Realmente não é complicado.


1
@Mondain Na verdade, você obtém mais precisão colocando o -ss depois. E o slhck menciona isso aqui blog.superuser.com/2012/02/24/… também na documentação do ffmpeg para -ss, menciona uma diferença entre colocá-lo antes ou depois.
Barlop #

5
+1 Eu vim aqui para descobrir como ignorar tudo após os primeiros 35 segundos, obrigado:ffmpeg -i input.wmv -c copy -t 35 output.wmv
karlphillip

2
Isso não funciona para mim (mp4). Ele apenas produz uma tela preta de 5 segundos:frame= 150 fps=0.0 q=-1.0 Lsize= 264kB time=00:00:09.97 bitrate= 216.6kbits/s
serralheiro

2
Isso produziu uma tela preta de 3-4 s no início do meu videoclipe. A modificação de Chris com a omissão -c copyremoveu a tela preta inicial. Veja sua resposta para obter detalhes.
Joelostblom

4
Você escreve "O seguinte seria cortar os primeiros 30 segundos e depois cortar tudo o que for 10 segundos depois disso:" <- O que isso significa? Por clipe você quer dizer incluir? 'clip cos pode significar clip out. Supondo que você queira incluir. Você quer dizer Iniciar a partir de 30 segundos e incluir apenas 10 segundos a partir daí? Nesse caso, sugiro que você escreva que seria muito mais claro.
barlop

94

Como outras pessoas mencionaram, colocar -ssantes (muito mais rápido) ou depois (mais preciso) o -ifaz uma grande diferença. A seção "Busca rápida e precisa" na página de busca do ffmpeg mostra como obter os dois, e eu o usei, e isso faz uma grande diferença. Basicamente, você coloca -ssantes e depois do tempo -i, mas deixe um tempo suficiente antes de começar a cortar para ter outro quadro-chave. Exemplo: se você quiser criar um clipe de 1 minuto, de 9min0seg a 10min 0seg no Video.mp4, poderá fazê-lo com rapidez e precisão usando:

ffmpeg -ss 00:08:00 -i Video.mp4 -ss 00:01:00 -t 00:01:00 -c copy VideoClip.mp4

O primeiro -ssprocura rapidamente (aproximadamente) 8min0seg, e o segundo -ssprocura com precisão 9min0seg, e -t 00:01:00remove um clipe de 1min0seg.

Observe também este ponto importante dessa página: "Se você usar -sscom -c:v copy, o fluxo de bits resultante pode acabar sendo instável, não reproduzível ou fora de sincronia com o fluxo de áudio, pois o ffmpeg é forçado a usar / dividir apenas nos quadros i. "

Isso significa que você precisa recodificar o vídeo, mesmo se você quiser apenas copiá-lo ou arriscar que ele fique instável e fora de sincronia. Você pode tentar -c copyprimeiro, mas se o vídeo for ruim, será necessário refazê-lo.


o mesmo aviso se aplica a -c:a copyesse modo de busca.
Jggunjer

1
A melhor resposta, dessa maneira, funcionou melhor para mim.
Ondra Žižka

3
Parece que "-ss" agora é rápido e preciso no ffmpeg 2.1+ sem especificá-lo duas vezes. trac.ffmpeg.org/wiki/Seeking
Conrad Meyer

25

Descobri que, -sscombinado com, -c copyresultou em um corte de meio segundo no início.

Para evitar isso, você deve remover o -c copy(que reconhecidamente fará uma transcodificação).


4
Há outra resposta que lida com precisão. A recodificação com a opção padrão NÃO é o que você deseja fazer!
Tomasz Gandor

Bom ponto @TomaszGandor
Chris

1
Não entendi a resposta de @ TomaszGandor, mas a remoção foi -c copycorrigida.
Iulian Onofrei

14

MANUALMENTE

Abra o arquivo em um media player que avance quadro a quadro e reproduza um arquivo AVISynth com dados como:

DirectShowSource(("C:\Downloads\Video\Do you want him.flv"), Pixel_Type="yuy2").Crop(0,0,-0,-0)
Subtitle("C:\Downloads\Video\Do you want him.flv", font="Arial", size=24, text_color=$ff0000, align=3)
ShowFrameNumber(scroll=true, x=336, y=27, font="Arial", size=24, text_color=$ff0000)
ShowTime(x=398, y=44, font="Arial", size=24, text_color=$ff0000)

Em seguida, corte com o formato de hora EXATO:

ffmpeg -i "Path\do you want him.flv"        \
       -ss 00:00:05.240 -to 00:00:08.360    \
       -vcodec libx264 -acodec libvo_aacenc \
       "Path\Do you want him1.flv"

e

ffmpeg -i "Path\do you want him.flv"        \
       -ss 00:00:10.240 -to 00:00:14.360    \
       -vcodec libx264 -acodec libvo_aacenc \
       "Path\Do you want him2.flv"

Agora crie um arquivo txt com os arquivos de vídeo com conteúdos como:

file 'C:\Downloads\Video\Do you want him1.flv'
file 'C:\Downloads\Video\Do you want him2.flv'

Execute o ffmpeg:

ffmpeg -f concat -i FileList.txt -c copy "Path\NewName_joined.flv"

9

Para mim, a -topção não funcionou, mas -vframesfuncionou. Eu prefiro usar #frames, já que prefiro cortar em I-Frames e descobri o GOP para vídeo usando ffprobe.

A linha de comando que funcionou para mim é:

ffmpeg -ss 60s -i input.wmv -vframes 1800 -acodec copy -vcodec copy output.wmv

A propósito, colocar -ssna frente -ifaz uma grande diferença no tempo de execução.


1
Na verdade -vframes(ou -frames:v) deve vir depois, -iporque é uma opção de saída.
slhck

5

Assim como no user225366, a opção -t não funciona em vídeos curtos, mas em vídeos mais longos. Para vídeos curtos, parece que -frames: v é melhor. Isto é o que funcionou para mim.

ffmpeg -ss 4 -i input.mp4 -frames:v 200 -vcodec copy output.mp4

É necessário adicionar uma cópia do codec se o vídeo tiver áudio, como mostram as outras respostas.


0

Não vejo muitos mencionarem isso (não sou especialista, talvez haja um problema), mas se o seu arquivo tiver outros fluxos, como legendas e outros metadados, como capítulos e assim por diante, é possível cortar / aparar e manter todos os fluxos com o seguinte comando

ffmpeg -to 60 -i input.mkv -map 0 -c copy output.mkv

Com -map 0você tomar todos os fluxos no arquivo e com -c copyque você copiar todos eles como eles são.
Se você -toomitir o início via -ss, o vídeo de entrada será cortado do início para o segundo 60.

Brincar maptambém é útil se você deseja que apenas os fluxos específicos sejam mantidos no corte (talvez você não precise de todas as fontes de áudio no arquivo ou apenas de algumas legendas).

Eu uso isso quando preciso dividir arquivos MKV grandes que não podem ser armazenados no armazenamento FAT32.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.