Automatizando a geração de vídeo adicionando uma introdução e um vídeo final ao vídeo principal

1

Eu tenho um projeto de vídeo que estou tentando compilar. Aqui está a visão geral:

  1. Eu tenho muitos vídeos que são sessões de treinamento de 5 minutos - Principal vídeo.
  2. O Vídeo Intro será um vídeo padrão de 5 segundos que será tem o título e o autor do vídeo. Isso será concatenado ao vídeo principal.
  3. The Trailing Video será basicamente um vídeo em estoque será concatenado ao vídeo principal e terá todo o legaleze etc.
  4. O Intro Vid irá suavemente desaparecer no vídeo principal, bem como quando você chegar ao final do vídeo principal, ele irá se transformar no vídeo do Trailing.
  5. O produto é um novo vídeo com Intro, Main & Vídeo de trailer, tudo em um!

O conceito é realmente simples assim. Na verdade, encontrei um exemplo de uma pessoa que resolveu isso e está fazendo exatamente o que eu quero .

Esta solução é um script Bash que pega um arquivo de configuração que possui o título, autor, etc. e gera o Intro, o Ending e cria o vídeo resultante com eles concatenados.

Estou usando o Ubuntu 12.04 Server. Eu tenho tentado tomar isso como uma amostra e apenas executá-lo sem sorte por causa de erros de incompatibilidade. Eu até tentei convertê-lo usando .MP4 containers ou .MKV . Estou com erro após erro ou problemas de incompatibilidade. Eu fui tão longe quanto mudar o binário ffmpeg usando a versão de 25 de outubro de 2013 do link que eu gosto como eu não precisa se preocupar com a reconstrução do binário. Quase bem-sucedido, mas novamente tenho algum erro que não consigo resolver.

Sei que parte do problema é o fato de que a produção de vídeo, codecs, formatos é um campo completamente novo para mim, por isso estou tentando trabalhar nesse novo território.

Talvez um especialista aqui tenha algo semelhante que eu possa usar como uma diretriz que usa o formato MP4 ou h.264. Ou pegue a solução acima da URL e faça com que ela funcione com uma versão mais atualizada do ffmpeg.

Eu incluirei o script e seu arquivo de parâmetros e a saída (abreviada por causa da limitação) abaixo. Basicamente, como o script está agora, quando executado, recebo o erro [matroska,webm @ 0x27bbee0] Read error . Este erro é retornado da rotina 'reasembleVideo' do primeiro comando ffmpeg.

O seguinte é o arquivo de parâmetros:

#!/bin/bash
INPUTFILE="ssh_main.mp4"
LOGO="logo.png"
LOGOLENGTH="1"
SPEAKER="Jason"
TITLE="Basic SSH Video"
DATE="October 28, 2013"
SCENESTART="00:00:01"
SCENEDURATION="00:00:09"
OUTPUTFILE="ssh_basic_1"
}

O seguinte é o script que estou executando. O ${OUTPUTFILE} que está sendo usado é um pequeno vídeo de 2 minutos que eu crio em screen-o-matic no formato MP4.

Script no PasteBin (muito longo para o post do Super User)

    
por DevDewboy 02.11.2013 / 00:15

2 respostas

1

Em um ambiente de produção, quando há muitos vídeos para participar, para automatizar o processo, você pode dividi-lo em praticamente quatro componentes. Digamos que você tenha 100 vídeos de treinamento principais para começar. Estes são nomeados main001.mov, main002.mov e assim por diante até main100.mov.

  • Crie seus 100 cartões de título como png ou outro formato - por meio de imagemagick / graphicsmagick / gimp / photoshop / whatever.
  • Converta-os em mov files no ffmpeg. Eu mostro usando um arquivo de som estéreo preparado que é silencioso, em vez de trazer de um dispositivo nulo, mas isso seria ótimo também. Isso cria um título de 5 segundos com o aparecimento e o desaparecimento gradual:
#!/bin/bash  

for i in *.png;  
do  
ffmpeg -y -loop 1 -f image2 -i $i -i silence.wav -t 00:00:05 -s 1920x1080 -aspect 16:9 -acodec pcm_s24le -b:a 128k -vcodec qtrle -b:v 1024k -filter_complex 'fade=in:0:10, fade=out:110:10' -f mov ${i%%.png}.mov

done

Isso cria (100) títulos mov a partir dos arquivos png fornecidos.

  • Crie seu cartão final como um png e converta para mov como antes, mas agora você pode dizer:
ffmpeg -y -loop 1 -f image2 -i endcard.png -i silence.wav -t 00:00:05 -s 1920x1080 -aspect 16:9 -acodec pcm_s24le -b:a 128k -vcodec qtrle -b:v 1024k -filter_complex 'fade=in:0:10, fade=out:110:10' -f mov endcard.mov
  • Concatene três conjuntos de arquivos, os dois primeiros conjuntos têm 100 arquivos cada, título e principal, e o terceiro contendo apenas um arquivo final comum. Para isso, você coloca os nomes de arquivos dos conjuntos em três matrizes e faz um loop pelos índices do array para se juntar a eles da seguinte forma:
#!/bin/bash  

# define the movie array  

movie=("main001.mov" "main002.mov" .....and so on till ... "main100.mov")  

#define titles array  

title=("title001.mov" "title002.mov" .....and so on till ... "title100.mov")  

#define end card array  

endcard=("endcard.mov")  

# Use for loop  
# get total subscripts in an array  

total=${#movie[*]}  

for (( i=0; i<=$(( $total -1 )); i++ ))  
do  
ffmpeg -i ${title[i]} -i ${movie[i]} -i ${endcard[0]} -y -filter_complex '[0:0] setsar=1/1[sarfix];[sarfix] [1:0]  [2:0] concat=n=3:v=1:a=0 [v]' -map '[v]' -pass 1 -strict -2 -an -vcodec libx264 -pix_fmt yuv420p -aspect 16:9 -threads 4 -b:v 1024k -flags +loop -cmp chroma -partitions +parti4x4+partp8x8+partb8x8 -subq 1 -trellis 0 -refs 1 -bf 3 -b_strategy 2 -coder 1 -me_range 16 -g 250 -keyint_min 75 -sc_threshold 40 -i_qfactor 0.71 -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 ${movie[i]%%.mov}.mp4

ffmpeg -i ${title[i]} -i ${movie[i]} -i ${endcard[0]} -y -filter_complex '[0:0] setsar=1/1[sarfix];[sarfix] [0:1] [1:0] [1:1] [2:0] [2:1] concat=n=3:v=1:a=1[v] [a]' -map '[v]' -map '[a]' -strict -2 -acodec aac -b:a 128k -pass 2 -vcodec libx264 -pix_fmt yuv420p -aspect 16:9 -threads 4 -b:v 1024k -flags +loop -cmp chroma -partitions +parti4x4+partp8x8+partb8x8 -mixed-refs 1 -subq 6 -trellis 1 -refs 5 -bf 3 -b_strategy 2 -coder 1 -me_range 16 -g 250 -keyint_min 75 -sc_threshold 40 -i_qfactor 0.71 -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 ${movie[i]%%.mov}.mp4

done

O passo 1 não leva em consideração o áudio. O índice da matriz de cartão final é estático em 0, já que existe apenas um. Claro, você pode passar diretamente o nome do arquivo aqui em vez de usar array. Sarfix pode ser necessário se o filme do título ou mesmo o filme de placa final causar problemas. Eu não mostrei a opção sarfix para o filme da placa final - que exigiria setsar = 1/1 [sarfix]; [sarfix] após o mapeamento [2: 0]. Observe também que os tamanhos e taxas de bits podem não se aplicar a você.

Desta forma, você pode automatizar a concatenação de grande número de arquivos principais com títulos e cartões finais.

    
por 05.11.2013 / 12:33
0

Você tem 2 $ {OUTPUTFILE} .mkv? Um para a entrada principal e outro para a saída final? Altere o final explicitamente para algo como $ {FINALOUTPUT} .mkv. Você está usando o protocolo concat no formato mkv. Você deve usar o demuxer de concat, ou alterar seus arquivos intermediários inteiros para os formatos mpeg ou .ts. Além disso:

Ponha a taxa - r 29.97 depois de -i "$ {OUTPUTFILE} -frames" /frame%d.png.
Então, em vez de: ./ffmpeg -threads 4 -r 29.97 -f image2 -i "${OUTPUTFILE}-frames"/frame%d.png \ -i "${OUTPUTFILE}.mkv" -c:a copy \ -map 0:0 -map 1:0 -f MP4 -y "${OUTPUTFILE}.mkv"

Uso:
./ffmpeg -threads 4 -f image2 -i "${OUTPUTFILE}-frames"/frame%d.png -r 29.97 \ -i "${OUTPUTFILE}.mkv" -c:a copy \ -map 0:0 -map 1:0 -f MP4 -y "${OUTPUTFILE}.mkv"

Na fase de concatenação, tente sem taxa:
./ffmpeg -threads 4 \ -i concat:"${OUTPUTFILE}-intro.mkv"\|"${OUTPUTFILE}.mkv"\|"${OUTPUTFILE}-exit.mkv" \ -y "${FINALOUTPUT}.mkv"

Se isso não funcionar, você deve usar as outras opções de concat, como o demuxer de concatenação:
ffmpeg -f concat -i mylist.txt -c copy output
Onde mylist.txt contém uma lista dos três arquivos gerados.
Veja este .

Há também outros problemas com um fluxo padronizado para yuv444p e o outro sendo explicitamente yuv420p. Isso deve ter -pix_fmt yuv420p declarado explicitamente:
ffmpeg -loop 1 -i "${OUTPUTFILE}-intro.png" -q:v 1 -r 29.97 -t ${LOGOLENGTH} -y -f MP4 "${OUTPUTFILE}-logo1.mkv"
como também o próximo estágio:
ffmpeg -i "${OUTPUTFILE}-logo1.mkv" -i "silence.mkv" \ -c:v copy -c:a copy -map 0:0 -map 1:0 -threads 4 \ -y -f MP4 "${OUTPUTFILE}-intro.mkv"

    
por 05.11.2013 / 08:48