Interativamente concatenar arquivos de vídeo

8

Como concatenar (juntar) vários arquivos de vídeo MP4 em um arquivo interativamente?

Existem muitos programas que fazem isso para dois arquivos a partir da linha de comando. Por exemplo:

  • ffmpeg
  • avconv
  • MP4Box

Mas frequentemente precisamos de uma solução para fazer isso de forma interativa.

    
por Slyx 20.02.2014 / 05:14

2 respostas

4

Eu uso o MP4Box como base de trabalho.
O script que eu sugiro lê todos os arquivos, um por um, verificando cada um (o tempo é um arquivo comum), pede ao usuário o nome do arquivo de entrada para criar.

#!/bin/bash
printf "###  Concatenate Media files ###\n"
fInputCount=0
# Reading input files
IFS=''
while (true)
do
    let currentNumber=$fInputCount+1 
    printf "File n°%s (\"ok\" to finish): " $currentNumber
    read inputFile
    [ "$inputFile" == "ok" ] && break
    [ ! -e "$inputFile" ] || [ ! -f "$inputFile" ] && printf "\"%s\" : Invalid filename. Skipped !\n" "$inputFile" && continue
    ((fInputCount++))
    inputFileList[$fInputCount]=$inputFile
    printf "\"%s\" : Added to queue !\n" "$inputFile"
done
[ "$fInputCount" == "0" ] || [ "$fInputCount" == "1" ] && echo "No enough input data. BYE ! " && exit
# Listing the input file list 
for ((i=1;i<=$fInputCount;i++))
do
    printf "%2d : %s\n" $i ${inputFileList[$i]}
done
# Reading the output filename
while (true)
do
    printf "Output file without extention (\"none\" to dismiss) : "
    read outputRead
    [ "$outputRead" == "none" ] && echo "Dismissed. BYE ! " && exit
    [ "$outputRead" == "" ] && echo "Try again ! " && continue
    [ -e "$outputRead" ] && echo "\"$outputRead\" exists. Try again !" && continue
    outputFile=$outputRead.mp4
    echo "Output to \"$outputFile\". Go !" && break
done
# Creating a random temporary filename
tmpOutFile="/tmp/concatMedia"'date +"%s%N"| sha1sum | awk '{print $1}''".mp4"
# Joining the two first input files
MP4Box -cat "${inputFileList[1]}" -cat "${inputFileList[2]}" $tmpOutFile
# Adding all other files
for ((i=3;i<=$fInputCount;i++))
do
    tmpIntermediateFile=$tmpOutFile
    tmpOutFile="/tmp/concatMedia"'date +"%s%N"| sha1sum | awk '{print $1}''".mp4"
    MP4Box -cat $tmpIntermediateFile -cat "${inputFileList[$i]}" $tmpOutFile
    rm $tmpIntermediateFile
done
mv $tmpOutFile "$outputFile"
# Finished
echo "\"$outputFile\" Saved !"
    
por 20.02.2014 / 05:51
8

Eu não tentei esse método recentemente, mas não vejo por que ele ainda não funcionaria. Eu acredito que você pode apenas cat .mp4 arquivos juntos se você não quiser fazer nada além de concatená-los.

1. Usando cat

$ cat file1.mp4 file2.mp4 > file3.mp4
$ ffmpeg -i file3.mp4 -qscale:v 2 output.avi

Eu ainda uso ffmpeg o tempo todo, ele também pode concatenar arquivos.

2. Usando o ffmpeg

  1. Faça uma lista de arquivos para concatenar

    $ cat inputs.txt 
    file sample_mpeg4.mp4
    file sample_mpeg4.mp4
    
  2. concatenar

    $ ffmpeg -f concat -i inputs.txt -c copy out.mp4
    
    $ ll |grep -E "sample|out"
    -rw-rw-r--. 1 saml saml 491860 Feb 19 23:36 out.mp4
    -rw-r--r--. 1 saml saml 245779 Feb 19 23:32 sample_mpeg4.mp4
    

    Outros métodos são abordados no wiki do FFmpeg: Como concatenar (juntar, mesclar) arquivos de mídia .

    NOTA: O Ubuntu não parece suportar o formato concat . Você tem que usar o protocolo concat. Além disso, possui opções de codec por stream. Assim, usando os resultados do protocolo concat da seguinte forma:

    $ ffmpeg -i input1.mp4 -vcodec copy -acodec copy \
         -vbsf h264_mp4toannexb -f mpegts intermediate1.ts
    
    $ ffmpeg -i input2.mp4 -vcodec copy -acodec copy \
         -vbsf h264_mp4toannexb -f mpegts intermediate2.ts
    
    $ ffmpeg -i "concat:intermediate1.ts|intermediate2.ts" \
         -vcodec copy -acodec copy -absf aac_adtstoasc output.mp4
    

    As opções do Ubuntu ffmpeg estão documentadas aqui .

por 20.02.2014 / 05:39