Como mesclar vários (mais de dois) vídeos no Ubuntu?


39

Desejo mesclar vídeos em lotes de vinte (20) cada. Estou executando uma máquina Linux. Os vídeos estão no formato mp4 e qualidade moderada. Alguns até têm o fluxo de áudio ausente. Até agora eu tentei ffmpeg, mencoder, cvlc/vlceMP4Box . Quero escrever um script de linha de comando para conseguir isso, pois estou processando em lote.

O principal problema é que algumas das soluções que tentei funcionam bem para dois vídeos, algumas funcionam bem para vídeos com fluxo de áudio e outras ainda funcionam para outro subconjunto do meu conjunto de vídeos. No entanto, não consegui encontrar uma solução abrangente para esta tarefa.


2
Por favor, não faça a mesma pergunta em vários sites SE: superuser.com/questions/928548/…
Maythux 16/06/2015

Você poderia postar especificamente o que tentou até agora?
ohaal

11
@ohaal Tentei usar vários métodos de concatenação ffmpeg, incluindo filtros e protocolos de arquivo. Eu também tentei usar o concatrecurso de cvlc/vlc. Eu também tentei o concatrecurso de mencoder. Tudo isso funcionou parcialmente. Isso finalmente me ajudou a resolver o problema.
Dhruv Singal

Sim, você já mencionou as ferramentas, o que eu quis dizer foram os comandos reais que você executou. Também seria ótimo se você pudesse incluir o comando que acabou resolvendo para você (na sua resposta), para futuros visitantes.
ohaal

Aah, entendo o seu ponto. Infelizmente, não consigo listar os comandos devido ao grande número. O comando que resolveu meu problema foi estemelt {input-sequence} -consumer avformat:{output-name} acodec=libmp3lame vcodec=libx264
Dhruv Singal

Respostas:


41

Estou usando mkvmergepara juntar vários arquivos MP4 em um único:

mkvmerge -o outfile.mkv infile_01.mp4 \+ infile_02.mp4 \+ infile_03.mp4

3
É melhor usar a extensão .mkvpara o arquivo de saída, pois é um contêiner Matroska, independentemente da extensão que você fornecer.
precisa saber é

Aqui está como instalar mkvmerge: tipsonubuntu.com
Morgoth

Somente este comando mkvmerge funciona. Todos os ffmpeg falham com o áudio deslocado pelo menos.
42n4 22/09

25

Você pode fazer isso usando ffmpeg:

ffmpeg -i concat:"input1.mp4|input2.mp4" output.mp4

referência e mais informações


2
Eu tentei fazer isso. O problema com isso é que ele não fornece uma saída adequada. 1. As faixas de áudio estão confusas. 2. Há algum distúrbio na faixa de vídeo.
Dhruv Singal

Eu usei para mais do que amostra, o resultado é de alta qualidade, talvez a qualidade da sua fonte de vídeo seja o problema?
Maythux

Você provavelmente está certo. Isso resolveu o problema: askubuntu.com/a/637179/420614
Dhruv Singal

2
Não use o protocolo concat para concatenar o MP4. Funciona apenas com determinados formatos que a maioria dos usuários não encontra. Use o concat desmuxer ou o filtro concat .
Llogan

Eu tentei o ffmpeg com 2 arquivos mp4 de 30min cada. Eu tenho um arquivo de saída com duração de 7 horas.
Guus

7

Isso resolveu o problema: https://stackoverflow.com/a/22324018/5014767

melté um ótimo utilitário de linha de comando para isso. Aqui está a página

Editar a partir dos comentários: O comando que resolveu meu problema foi este melt {input-sequence} -consumer avformat:{output-name} acodec=libmp3lame vcodec=libx264


4

Eu escrevi um pequeno script de shell para concaturar MP4s sem transcodificar usando ffmpeg.

for f in $(ls *.MP4); do
    ffmpeg -i $f -c copy -bsf:v h264_mp4toannexb -f mpegts $f.ts
done

CONCAT=$(echo $(ls *.ts) | sed -e "s/ /|/g")

ffmpeg -i "concat:$CONCAT" -c copy -bsf:a aac_adtstoasc output.mp4

rm *.ts

Isso cria arquivos intermediários em um contêiner MPEG e os concatena em um MP4.


É importante observar que esse script falhará se algum dos nomes de arquivos contiver espaços ou, em alguns casos, caracteres especiais. Para o loop, é significativamente melhor usar apenas for f in *.MP4sem usar ls. (Você sempre deve evitar o uso lsde scripts por alguns motivos importantes; existem opções melhores.) Além disso, use aspas para variáveis, a menos que tenha certeza de que não há espaços ou outros caracteres especiais, portanto "${f}"(ou apenas "$f") em vez de sem aspas $f.
22418 Paddy Landau

CONCAT=$(echo $(ls *.ts) | sed -e "s/ /|/g")não funciona bem com nomes de arquivos 1, 2, 3 ... 10 ... 20. Ele acaba analisando-os como 1, 10 ... 2, 20 ... etc. Sugiro que CONCAT=$(echo $(ls -v *.ts) | sed -e "s/ /|/g")isso garanta a ordem .
Tisaconundrum 16/1118

2

Crie um arquivo files.txt com todos os arquivos que você deseja concatenar no seguinte formulário (as linhas que começam com # são ignoradas):

# this is a comment
file 'file1.mp4'
file '/path/to/file2.mp4'
file 'file3.mp4'

Observe que esses podem ser caminhos relativos ou absolutos. Em seguida, você pode transmitir em cópia ou recodificar seus arquivos:

ffmpeg -f concat -safe 0 -i files.txt -c copy output.mp4

0

Meu script, puramente em bashe ffmpeg. Recodifica os arquivos fornecidos em uma linha de comando em um.

Requer que os arquivos tenham a mesma resolução. Aceita diferentes rotações de metadados, o que ffmpeg concat:não.

rm ffmpeg-concat-output.mkv

FILE_COUNT=$#
INPUTS=""
FILTER=""
INDEX=0
for FNAME in $@; do
    echo "Processing ${FNAME}"
    INPUTS="${INPUTS} -i $FNAME"

    if [ -z "${FILTER}" ]; then
        FILTER="[$INDEX:v:0] [$INDEX:a:0]"
    else
        FILTER="${FILTER} [$INDEX:v:0] [$INDEX:a:0]"
    fi
    let INDEX+=1
done

COMMAND="ffmpeg ${INPUTS} \
    -filter_complex '${FILTER} \
        concat=n=${INDEX}:v=1:a=1 [v] [a]' \
    -map '[v]' -map '[a]' \
    ffmpeg-concat-output.mkv"

#   -af 'volume=15dB' # won't work with -filter_complex

bash -c "${COMMAND}"

0

Criei um script Python que, usando moviepy , também pode concatenar subsegmentos (útil se você quiser, por exemplo, remover algumas partes de um vídeo).

Use-o com:

vcat -i inputfile1,inputfile2[start-end],... -o <outputfile>

-1

Além da resposta de Maythux, de :

Alguns contêineres multimídia (MPEG-1, MPEG-2 PS, DV) permitem concatenar vídeos apenas concatenando os arquivos que os contêm.

Ou seja, os vídeos a serem concatenados usam um dos contêineres de vídeo mencionados acima (aos quais adicionarei MPEG-4 Parte 14 para experiência pessoal), você pode simplesmente:

cat video1.ext video2.ext video3.ext > video4.ext

11
Eu tentei isso, mas ele retorna apenas o primeiro vídeo como saída. Li em algum lugar que isso não funciona, embora não me lembre da lógica por trás disso.
Dhruv Singal

@DhruvSingal Sim, eu posso confirmar isso, eu tentei isso em dois vídeos MP4 com exatamente a mesma codificação de vídeo / áudio e como você só podia navegar pelo primeiro vídeo. O que parece razoável, no entanto, tenho certeza de que já fiz isso antes com alguns vídeos MP4. Talvez a memória não esteja funcionando bem aqui ou haja outros requisitos para que isso funcione. Quero pesquisar sobre isso desde que eu estou interessado também, se eu encontrar algo que eu vou atualizar a resposta e deixá-lo um comentário
kos

De alguma forma, precisamos alterar os metadados no início do primeiro vídeo para abranger toda a duração do filme combinado e provavelmente outras coisas. Apenas alguns ficheiros MPEG4 deixe-me ver os metadados ..
Ken Mollerup
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.