it-swarm-pt.tech

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

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

Eu quero FFmpeg para tomar uma imagem JPEG e um arquivo de áudio como entrada e gerar um arquivo de vídeo com a mesma duração que o arquivo de áudio (alongando a imagem estática para toda a duração).

Eu não me importo muito sobre o codec de vídeo que é 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 disso?

172
matteo

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 AAC ffmpeg integrado.

134
matteo

Você está fazendo isso wayharder do que tem que ser. FFmpeg é muito mais inteligente do que você acredita - sabe que você quer que o vídeo tenha o mesmo tamanho que o seu áudio faixa.

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

pause

Os únicos atributos você havepara especificar são o input filenames, o output codecs, e o output filenameque _ (eo ipsoinclui o output container,).

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

Output size is um dos hang-ups mais comuns do FFmpeg; alguns codecs são mais restritos em dimensões de saída do que outros, mas nenhuma saída pode ter atributos de altura ou largura de número ímpar.

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

O comando Shell tem um switch cmd /k que mantém uma janela aberta onde você pode executar as mesmas instruções do seu script em lote no prompt de comando.

FFmpeg e avconv farão você usar -c:a para -acodec e -c:v para -vcodec Eventualmente, mas as instruções antigas funcionam bem nas construções que uso.

Nota Bene:Todo commit possui idiossincrasias. Se sua linha de comando está falhando sem razão aparente, geralmente é útil tentar outra compilação - ou seguir o fork até libav, onde os desenvolvedores mais ativos do FFmpeg têm estado nos últimos anos.A sua ferramenta de transcodificação foi renomeada como avconv mas seus arquivos em lote devem funcionar com qualquer um deles.

39
patronanejo

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%), porque só há 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 do áudio. Você precisa de -shortest ou ele faz um loop para sempre. (Ele pára 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 dramaticamente 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 :-)

33
PJ Brunet

A versão que funcionou para mim:

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

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.

14
fguillen

A partir do ffmpeg manpage:

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

Como você descobriu, as opções do arquivo devem vir antes do arquivo a que se aplicam.

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

8
ComputerDruid

Isso funcionou para mim

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

Eu encontrei vcodec libx264 criado arquivos muito menores do que mpjeg (10 MB em vez de 100 MB).

4
Colonel Panic

Eu estava tentando fazer como @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).

1
user284130

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

0
user3535334

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

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

Esta resposta Combine uma imagem + um arquivo de áudio para fazer 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
0
Suraj Jain