Combine uma imagem + um arquivo de áudio para criar um vídeo usando o FFmpeg

158

Isso deve ser bem trivial, mas não consigo encontrar uma maneira de fazê-lo funcionar.

Eu quero que o FFmpeg pegue uma imagem JPEG e um arquivo de áudio como entrada e gere um arquivo de vídeo com a mesma duração que o arquivo de áudio (esticando a imagem parada por toda a duração).

Eu não me importo muito sobre qual codec de vídeo é usado para a saída, mas é vital que eu possa usar "copiar" como o codec de áudio (ou seja, copiar o fluxo de áudio sem transcodificá-lo).

Qual é a linha de comando certa que faria isso?

Eu tentei:

ffmpeg -i image8.jpg -i sound11.amr -acodec copy test.avi

e tentou várias combinações com e sem -s 640x360 , -loop_input , -shortest , -t xxx , -r 0.1 (taxa de quadros artificialmente baixa na esperança de que o vídeo fosse mais longo) e -f image2

Ou recebo erros ou recebo um arquivo de vídeo com a duração de um quadro.

Eu pesquisei e encontrei uma dúzia de soluções propostas (supostamente para esta mesma pergunta), nenhuma das quais funciona.

Alguém pode sugerir um comando de trabalho e explicar a lógica por trás dele?

    
por matteo 04.05.2011 / 19:19

10 respostas

121

A ordem das opções na linha de comando é importante. Os seguintes trabalhos para o meu caso:

ffmpeg -loop 1 -y -i image8.jpg -i sound11.amr -shortest -acodec copy -vcodec mjpeg result.avi

Em um caso mais geral, onde image.jpg e audio.wav são sua entrada, você pode usar o seguinte comando, adaptado de o wiki do FFmpeg :

ffmpeg -loop 1 -i image.jpg -i audio.wav -c:v libx264 -tune stillimage -c:a aac -b:a 192k -pix_fmt yuv420p -shortest out.mp4

Isso usaria o codificador libx264 e forneceria uma melhor compactação do que o codec MJPEG usado acima. O áudio é AAC, com o codificador ffmpeg AAC integrado.

    
por 01.09.2018 / 10:40
35

Você está tornando caminho mais difícil do que tem que ser. O FFmpeg é muito mais inteligente do que você acredita - sabe que você quer que o vídeo tenha o mesmo tamanho de sua faixa de áudio.

ffmpeg -i still.png -i narrate.wav -acodec libvo_aacenc -vcodec libx264 final.flv

pause

Os únicos atributos que você tem para especificar são input filenames , output codecs e o output filename (que e o ipso inclui o output container ,).

É claro que faz sentido começar com uma imagem estática que compartilhe as mesmas dimensões do seu vídeo final; se você estiver usando um editor de imagem dedicado em vez de especificar as dimensões de saída para o FFmpeg atender, será necessário certificar-se de que suas dimensões de entrada sejam números pares .

O tamanho da saída é um dos hang-ups mais comuns do FFmpeg; alguns codecs são mais restritos nas dimensões de saída do que outros, mas nenhuma saída pode ter atributos de altura ou largura com números ímpares.

O comando pause no final do arquivo em lote mantém a CLI aberta - a melhor maneira de depurar sua linha de comando é lendo as mensagens de erro gera. Eles são extremamente específicos - e a melhor documentação do FFmpeg -, mas o trabalho duro dos desenvolvedores é perdido se você permitir que a janela seja fechada antes de poder lê-los.

O shell de comando tem uma opção cmd /k que mantém uma janela aberta na qual você pode executar as mesmas instruções do seu script em lote no prompt de comando. / p>

FFmpeg e avconv farão com que você use -c:a para -acodec e -c:v para -vcodec eventualmente, mas as instruções antigas funcionam bem nas compilações que eu uso.

Nota: Todo commit tem idiossincrasias. Se a sua linha de comando está falhando sem razão aparente, geralmente é útil tentar outra compilação - ou seguir o garfo para a libav , onde os desenvolvedores mais ativos do FFmpeg estiveram nos últimos dois anos. Sua ferramenta de transcodificação foi renomeada como avconv , mas seus arquivos em lote devem funcionar com qualquer um deles.

    
por 16.12.2012 / 15:21
29

Ainda mais fácil:

ffmpeg -i ep1.png -i ep1.wav ep1.flv

O FFmpeg tentará escolher o melhor codec automaticamente, dependendo da extensão do seu arquivo de saída.

Atualização: notei que o YouTube tem dificuldade em processar o vídeo (fica preso em 95%), acho que há apenas um quadro. A solução que encontrei para deixar o YouTube feliz: adicione mais frames. Além disso, adicionei -acodec copy para preservar a qualidade de áudio. Você precisa de -shortest ou ele faz um loop para sempre. (Ele para no final do fluxo mais curto, que é o áudio, porque o loop da imagem é infinito.) A ordem de suas opções é muito importante para a velocidade, pois os filtros (e outros) são processados na ordem que você especificar. Se você alterar a ordem desses parâmetros, os resultados serão drasticamente diferentes.

ffmpeg -r 1 -loop 1 -i ep1.jpg -i ep1.wav -acodec copy -r 1 -shortest -vf scale=1280:720 ep1.flv

Note também que eu configurei a taxa de quadros duas vezes, isso não é um acidente - a primeira taxa de quadros é para a entrada, a segunda é para a saída. Se você fizer isso corretamente, deve haver apenas um quadro por segundo de vídeo, o que significa que ele codifica de forma relativamente rápida. Também defini a resolução para 720p aqui, o que significa que você deve obter áudio HD no YouTube: -)

    
por 26.05.2014 / 04:09
14

A versão que funcionou para mim:

 ffmpeg -loop 1 -y -i pic.jpg -i sound.amr -shortest video.mp4

Faça check-out da opção -shortest deve estar na frente do arquivo de saída se não receber o erro abaixo:

A opção mais curta (terminar a codificação dentro da entrada mais curta) não pode ser aplicada ao arquivo de entrada pic.jpg - você está tentando aplicar uma opção de entrada a um arquivo de saída ou vice-versa. Mova esta opção antes do arquivo ao qual pertence. Erro ao analisar as opções do arquivo de entrada pic.jpg.

    
por 28.01.2015 / 21:16
8

Na página do ffmpeg:

ffmpeg [[infile options][-i infile]]... {[outfile options] outfile}...

Como você descobriu, as opções de infiles devem vir antes do infil ao qual elas se aplicam.

Este não é um bug, no entanto, apenas um mecanismo pelo qual você pode especificar quais argumentos do infile se aplicam.

    
por 22.05.2011 / 02:40
4

Isso funcionou para mim

ffmpeg -loop 1 -shortest -y -i image.jpg -i audio.mp3 -acodec copy -vcodec libx264 video.avi

Descobri que vcodec libx264 criou arquivos muito menores que mpjeg (10 MB em vez de 100 MB).

    
por 16.04.2014 / 00:15
1

Eu estava tentando fazer o @matteo , mas sem o áudio, e a solução @Colonel Panic funcionou melhor:

ffmpeg -loop 1 -shortest -y -i still.png -vcodec libx264 -t 10 video.avi

Eu só tive que adicionar um argumento de duração em segundos ( -t 10 ).

    
por 18.09.2014 / 13:44
0

ffmpeg -loop 1 -i img.jpg -i audio.wav -c:v libx264 -c:a aac -strict experimental -b:a 192k -shortest out.mp4

    
por 22.07.2014 / 14:15
0

Caso alguém queira convertê-los em lote, tente isso.

Você pode definir a pasta de entrada e saída, e também o formato em que você quer que o vídeo esteja. Neste caso, eu configurei para AVI.

Esta resposta Combine uma imagem + um arquivo de áudio para criar um vídeo usando o FFmpeg me ajudou muito.

 @echo off
 set "sourcedir=C:\Users\CodeHard\Desktop\BOX\Newfolder"  
 set "outputdir=C:\Users\CodeHard\Desktop\BOX\Converted" 

 PUSHD "%sourcedir%"

 for %%F in (*.mp3) DO ffmpeg -r 1 -loop 1 -i abc.jpeg -i "%%F" -acodec copy -r 1 -shortest -vf scale=1280:720 "%outputdir%\%%F.avi"  

 POPD
    
por 12.07.2017 / 18:20
-1

Tente este comando. Isso funciona para mim.

-y -i /storage/emulated/0/images.jpg -i /storage/emulated/0/audio.wav -acodec aac -vcodec mpeg4 -s 480*320 -f mp4 -r 2 /storage/emulated/0/output.mp4"
    
por 24.05.2016 / 09:43