2010-05-06 14:12:17 +0000 2010-05-06 14:12:17 +0000
357
357

Usando ffmpeg para cortar vídeo

Estou usando 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 parte -ss funciona bem, mas o -t é ignorado. Remove correctamente os segundos iniciais especificados com -ss mas depois continua até ao fim da entrada com a cópia.

Existe alguma forma de usar ffmpeg para cortar o fim de um vídeo sem o recodificar?

Respostas (7)

105
105
105
2014-01-20 04:07:24 +0000

Como outras pessoas mencionaram, colocar o -ss antes (muito mais rápido) ou depois (mais preciso) do -i faz uma grande diferença. A secção “Procura Rápida e Precisa” na página ffmpeg seek diz-lhe como obter ambos, e eu já o usei, e faz uma grande diferença. Basicamente você coloca o -ss antes E depois do -i, certifique-se apenas de deixar tempo suficiente antes de onde você quer começar a cortar para ter outro quadro chave. Exemplo: Se quiser fazer um clipe de 1 minuto, de 9min0sec a 10min0sec no Video.mp4, pode fazê-lo de forma rápida e precisa usando:

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

O primeiro -ss procura rápido até (aproximadamente) 8min0sec, e depois o segundo -ss procura preciso até 9min0sec, e o -t 00:01:00 tira um clipe de 1min0sec.

Note também este ponto importante a partir dessa página: “Se utilizar o -ss com o -c:v copy, o bitstream resultante pode acabar por ser picotado, não reproduzível, ou ficar fora de sincronia com o fluxo de áudio, uma vez que o ffmpeg é forçado a utilizar/dividir apenas em i-frames”

Isto significa que precisa de recodificar o vídeo, mesmo que queira apenas copiá-lo, ou arrisca-se a que fique picotado e fora de sincronia. Pode tentar apenas -c copy primeiro, mas se o vídeo for uma porcaria vai precisar de o refazer.

27
27
27
2014-05-09 02:24:58 +0000

Descobri que o -ss combinado com o -c copy resultou numa costeleta de meio segundo no início.

Para evitar isso, é necessário retirar o -c copy (que reconhecidamente fará uma transcodificação).

13
13
13
2014-09-04 05:48:57 +0000

MANUALMENTE

Abra o ficheiro num leitor de media que irá avançar frame a frame e reproduzir um ficheiro AVISynth com dados tais 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)

Depois corte com o formato EXACTO do tempo:

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"
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 faça um ficheiro txt com os ficheiros 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'

Executar ffmpeg:

ffmpeg -f concat -i FileList.txt -c copy "Path\NewName_joined.flv"
8
8
8
2013-05-19 03:14:56 +0000

Para mim a opção -t não funcionou, mas a -vframes funcionou. Prefiro usar o #frames, uma vez que preferia cortar na I-Frames e descobri o GOP para vídeo usando o 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 o -ss na frente do -i faz uma grande diferença no tempo de execução.

5
5
5
2016-12-08 11:24:57 +0000

Tal como no user225366, a opção -t não funciona para vídeos curtos, mas funciona para vídeos mais longos. Para vídeos curtos, parece que -frames:v é melhor. Foi isto que funcionou comigo.

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

-acodec copy precisa de ser adicionado se o vídeo tiver áudio, como as outras respostas mostram.

0
0
0
2020-02-12 02:20:00 +0000

utilize este formato:

ffmpeg <start time> <input file> <cut duration> <out file>

por exemplo, corte um clip de 60 segundos após 1 minuto de vídeo

ffmpeg.exe -ss 00:01:00 -i "in file.mp4" -to 00:01:00 -c copy out.mp4

0
0
0
2019-09-01 05:29:02 +0000

Não vejo muitos a mencionar isto (não sou especialista, talvez haja um senão), mas se o seu ficheiro tiver outros fluxos como legendas e outros metadados como capítulos e assim por diante, é possível cortar/tripar e manter todos os fluxos com o seguinte comando

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

Com o -map 0 você pega em todos os fluxos do ficheiro, e com o -c copy copia-os todos tal como estão.
Usando -to omitindo o início via -ss irá cortar o vídeo de entrada do início para o segundo 60.

A manipulação com map é útil também se quiser que apenas sejam mantidos streams específicos no corte (talvez não precise de todas as fontes de áudio no ficheiro, ou apenas algumas legendas).

Eu uso isto quando preciso de dividir grandes ficheiros MKV que não podem ser armazenados no armazenamento FAT32.