Quero que meu site permita que os usuários criem com precisão seus próprios clipes a partir de um vídeo de origem que forneço.
Eu tenho um arquivo de vídeo de origem que primeiro desejo converter para algo adequado para um site:
Input #0, matroska,webm, from 'source.mkv':
Duration: 00:28:18.57, start: 0.000000, bitrate: 10183 kb/s
Stream #0:0: Video: h264 (Constrained Baseline), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 1k tbn, 48 tbc (default)
Stream #0:1: Audio: mp3, 44100 Hz, stereo, s16, 128 kb/s (default)
Eu uso o ffmpeg para convertê-lo assim:
ffmpeg -i source.mkv -c:v libx264 -c:a aac -strict experimental -vf scale="960:-1" source.mp4
Assistir a este vídeo de volta é de boa qualidade e tamanho de arquivo pequeno o suficiente para minhas necessidades, e carrega / reproduz no meu site.
Eu tenho uma página da web que permite que os usuários selecionem um ponto de partida e um ponto final neste vídeo - e criem um clipe. Aqui está um exemplo do comando ffmpeg que eu uso para isso:
-ss 577.920 -i source.mp4 -t 011.980 -codec:v copy -codec:a copy -vf scale="960:-1" clip1.mp4
O problema é que o clipe nem sempre é preciso com tempo suficiente. Normalmente, o áudio é preciso o suficiente, mas o vídeo para meio segundo mais cedo ou algo assim.
Existe alguma maneira de tornar isso preciso e em sincronia, digamos, 0,2 segundos?
Edição: Adicionar -force_key_frames 00:00:00.2
não ajudou.
Edição: Eu mudei o recorte para usar em -c:v libx264 -c:a aac -strict experimental
vez de -codec:v copy -codec:a copy
com bons (ish) resultados.
O arquivo pode ser reproduzido externamente sem problemas - mas quando eu o carrego no meu elemento de vídeo html5 e o reproduzo - a última parte do vídeo (o áudio é bom) congela. A última parte que congela é menor que um segundo.
Devo tentar com outro codificador de vídeo? Qual é a melhor alternativa para libx264? Tendo em mente, provavelmente vou querer que isso seja publicado em um site público.
Mas espere, o fato de ele ser reproduzido com precisão sem problemas com um player como MPC ou Windows Media Player sugere que é um problema com o Google Chrome ou o elemento de vídeo HTML? Ou estou usando uma codificação não suportada ou algo assim?
Respostas:
O comportamento das
-ss
alterações depende se usado como uma opção de entrada ou saída e geralmente é mais lento, mas pode ser mais preciso quando usado como uma opção de saída. Veja a resposta para ffmpeg converte o vídeo do período especificado lentamente para obter mais detalhes e exemplos.Para alterar a qualidade da saída,
source.mp4
use a-crf
opção com um valor entre 18 e 28 (23 é o padrão). Consulte a seção CRF do Guia de codificação FFmpeg e x264 para obter exemplos.Seu comando de corte pode ser simplificado:
Eu substituí
-codec:v copy -codec:a copy
por-c copy -map 0
. Isso copiará todos os fluxos em vez dos apenas os primeiros fluxos de vídeo e áudio - embora a entrada tenha apenas dois fluxos devido ao seu comando anterior. Como você não pode escalar sem recodificar, portanto, é mutuamente exclusivo-codec:v copy
, e como sua entrada já está dimensionada para o tamanho definido, removi as opções de filtro.Se ainda não for preciso o suficiente, tente:
Será mais lento, mas provavelmente mais preciso. Veja os links na resposta no primeiro link que forneci para uma descrição das diferenças desses dois exemplos.
Por último, você deve executar
source.mp4
através deqt-faststart
(localizado no diretório ferramentas fonte ffmpeg), ou usar a-movflags faststart
opção. Isso realocará alguns dados para o início do arquivo, para que ele possa iniciar a reprodução antes de ser baixado completamente.fonte
-ss
como opção de saída em vez de opção de entrada corrigiu meu problema: o primeiro quadro de vídeo estava em torno de 1s no vídeo de saída, com apenas áudio antes disso (também confirmado porffprobe -show_frames
). Movendo-se-ss
depois-i
fez com que produza quadros de áudio e vídeo a partir de quadro 0.