Eu tenho um grande conjunto de jpgs que desejo converter em um vídeo sem perdas (ou, pelo menos, muito próximo a sem perdas, desde que o tempo de codificação não seja muito maior do que o contrário).
Ingenuamente, eu pensaria que deveria haver algum codec que possa armazenar cada quadro jpg como está (sem recompressão) e talvez obter uma boa compactação substituindo alguns quadros apenas pelas informações sobre o delta do quadro anterior. No meu caso, existem muitas sequências de quadros idênticas entre si, ou que têm uma pequena diferença entre elas.
Existe algum codec e configurações adequadas para o ffmpeg que podem conseguir isso?
Respostas:
Apenas mux as imagens
Você pode simplesmente compactar as imagens JPG para criar um vídeo:
Observe que, se você omitir
-framerate
, um padrão de-framerate 25
será aplicado à entrada.Otimização sem perdas
Você pode usar
jpegtran
para executar a otimização sem perdas em cada quadro, o que pode proporcionar uma economia significativa no tamanho do arquivo:Agora mux com
ffmpeg
como mostrado acima.Verificando se está realmente sem perdas
O framehash muxer pode ser usado para comparar o hash exclusivo de cada quadro para garantir que o resultado seja realmente sem perdas:
Nos exemplos acima, cada quadro associado à entrada e saída compartilha o mesmo hash, garantindo que os quadros sejam idênticos e que a saída seja sem perdas.
Veja também
fonte
framemd5
comandos devem alcançar além de apenas listar os hashes? como obter compressão adicional quando quadros idênticos são identificados?Isso produzirá um vídeo H.264 sem perdas, onde os quadros usarão informações de outros quadros
ffmpeg -f image2 -r 30 -i %09d.jpg -vcodec libx264 -profile:v high444 -refs 16 -crf 0 -preset ultrafast a.mp4
Explicação das opções:
-f image2
- diz ao ffmpeg para selecionar um grupo de imagens-r 30
- diz ao ffmpeg para codificar a 30 quadros (ou imagens) por segundo (altere para a taxa de quadros desejada)-i %09d.jpg
- diz ao ffmpeg para usar as imagens 000000000.jpg a 999999999.jpg como entrada. Altere9
in%09d.jpg
para quantos zeros têm os nomes da sequência de imagens. Se os nomes dos seus arquivos forem, por exemplo, img0001.jpg, isso será expresso como img% 04d.jpg-vcodec libx264
- instrui o ffmpeg a enviar para um arquivo compatível com H.264-profile:v high444
- diz à libx264 para usar o perfil sem perdas preditivas 4: 4: 4 alto, permitindo codificação sem perdas-refs 16
- diz à libx264 para ter 16 imagens armazenadas em um buffer, para que possam ser referenciadas por outras imagens no vídeo-crf 0
- diz à libx264 para executar uma codificação sem perdas-preset ultrafast
- diz à libx264 para priorizar a velocidade de codificação sobre o tamanho do arquivo de saídaa.mp4
- diz ao ffmpeg para salvar a saída em um arquivo MP4 chamado a.mp4. Mude para o nome e formato do arquivo que você deseja usarfonte
-f image2
é supérfluo aqui. O desmuxador do arquivo de imagem deve usar em-framerate
vez de-r
. A libx264 escolherá automaticamente o apropriado-profile
para sem perdas e o que-preset
será tratado-refs
.-refs 5
no máximo, a menos que você saiba que seu conteúdo tem imagens idênticas separadas por várias outras, isso pode fazer com que x264 perca a referência antes de chegar à duplicata. Maior que oultrafast
que pouco diferencia no modo sem perdas, exceto o ganho de ~ 10% do CABAC sobre o CAVLC (para um alto custo de CPU nas taxas de bits exigidas para as perdas). Sério, em alguns 720x480p60 de ação ao vivo (saída de desentrelaçamento),superfast
era de 28 GB,slower
era de 27 GB . Se o tempo de codificação não importa, mas o tempo de decodificação, não se esqueça de evitar o CABAC. Talvez até-tune fastdecode
. A contagem moderada de árbitros não deve doer.-preset placebo
algumas frações extras de porcentagem.-vcodec libx265 -x265-params lossless=1
é a opção equivalente. (Mas, na minha experiência (= gravação de apresentações de slides do Powerpoint), não é necessariamente melhor, e é muito mais lento que o h264. ... do modo sem perdasVocê pode criar uma
avi
animação como uma série depng
imagens (png
é lossless assim que ajpeg => png
conversão não deve degradar suas fotos):se suas imagens tiverem um nome
img_0001.jpg
onde "25" é a taxa de quadros que você deseja no vídeo resultante.
-start_number
não é necessário se for 1, mas é útil se o seu primeiro número de vídeo não for 1.Se você deseja codificar
mjpeg
com a linha de comando da mais alta qualidade, é:E o mais importante é que você pode converter o vídeo em uma série de imagens:
etc ...
fonte
Para expandir a resposta de LordNeckbeard, sim, basta compactar os dados JPEG em um fluxo de vídeo MJPEG. Essa será a menor representação da sequência exata de imagens de saída, mesmo que o MJPEG seja um codec terrivelmente ineficiente para os padrões atuais. (sem redundância temporal e nem mesmo previsão interna.
Você pode criar um vídeo MJPEG com taxa de quadros variável para aproveitar as imagens duplicadas em sua entrada.
Hm, isso não vai funcionar, pois o mpdecimate não funciona com dados compactados, e não podemos permitir que o ffmpeg decodifique e depois repita o jpeg nos dados da imagem sem perda e custo da CPU.
Talvez se você substituísse arquivos de origem jpg duplicados por arquivos vazios com esse número de sequência, ou algo assim?
Como essa pergunta nem é recente, não vou demorar para descobrir como fazê-lo, a menos que alguém responda para perguntar como. Mas como o MJPEG pode entrar em um contêiner mkv, tenho certeza de que é possível ter um arquivo que não duplique os dados jpeg para quadros repetidos, mas apenas não tenha um quadro de saída para decodificar até que a sequência de duplicatas seja sobre.
Oh, aqui está uma ideia:
Em seguida, remova (ou mova para o lado) todos os jpegs dos quadros que o mpdecimate deseja soltar (provavelmente possui algumas opções de registro? Ou -vf showinfo, analise-o e mova ou vincule somente os quadros que aparecem em sua saída, deixando para trás os JPEGs descartados?). mux isso para um MJPEG.mkv e, em seguida, faça algo com mkvmerge para substituir os carimbos de data / hora do quadro naqueles pelos carimbos de data e hora de
mpdecimate.timestamps
.Se você estivesse usando o xcoding, em vez de apenas misturar dados jpeg no MJPEG, isso seria MUITO mais fácil, já que você usaria meu primeiro comando com mpdecimate e qualquer outro codec que
copy
não fosse, e funcionaria apenas (tm).Eu não tentei nada disso, pois essa era uma pergunta antiga. Além disso, o motivo pelo qual não preenchi as lacunas de como realmente filtrar seu diretório de jpegs com base na saída mpdecimate, ou como realmente usar o fluxo de carimbo de data / hora.
fonte