Cum pentru a concatena două fișiere MP4 folosind FFmpeg?

Am'm încercarea de a concatena două fișiere mp4 folosind ffmpeg. Am nevoie de acest lucru să fie un proces automat prin urmare, de ce am ales ffmpeg. Am'm conversie a două fișiere în .ts fișiere și apoi concatenarea lor și apoi încercarea de a codifica care concated .ts fișier. Fișierele sunt h264 aac și codificate și am'm în speranța de a păstra calitatea același sau cât mai aproape de original posibil.

ffmpeg -i part1.mp4 -vcodec copy -vbsf h264_mp4toannexb -acodec copy part1.ts
ffmpeg -i part2.mp4 -vcodec copy -vbsf h264_mp4toannexb -acodec copy part2.ts
cat part1.ts part2.ts > parts.ts
ffmpeg -y -i parts.ts -acodec copy -ar 44100 -ab 96k -coder ac -vbsf h264_mp4toannexb parts.mp4

Din păcate, am'm primesc următorul mesaj de eroare întoarce de ffmpeg timpul de codare:

[h264 @ 0x1012600]sps_id out of range
[h264 @ 0x1012600]non-existing SPS 0 referenced in buffering period
[h264 @ 0x1012600]sps_id out of range
[h264 @ 0x1012600]non-existing SPS 0 referenced in buffering period
[NULL @ 0x101d600]error, non monotone timestamps 13779431 >= 13779431kbits/s    
av_interleaved_write_frame(): Error while opening file

Acest lucru se întâmplă aproximativ o jumătate de drum prin codare care mă face să cred că poți't concat două .ts fișiere împreună și să-l lucreze.

FFmpeg are trei concatenare metode:

1. concat filtru video

ffmpeg -i opening.mkv -i episode.mkv -i ending.mkv \
  -filter_complex "[0:v] [0:a] [1:v] [1:a] [2:v] [2:a] concat=n=3:v=1:a=1 [v] [a]" \
  -map "[v]" -map "[a]" output.mkv

Rețineți că această metodă efectuează o re-encode.

2. concat demuxer

$ cat mylist.txt
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'

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

Pentru Windows:

(echo file 'first file.mp4' & echo file 'second file.mp4' )>list.txt
ffmpeg -safe 0 -f concat -i list.txt -c copy output.mp4

3. concat protocol

ffmpeg -i "concat:input1|input2" -codec copy output.mkv

Această metodă nu funcționează pentru mai multe formate, inclusiv MP4, datorită naturii acestor formate și simplist concatenare efectuate prin această metodă.

Pe care să o folosiți

  • concat filtru: Utilizați dacă intrările dvs. nu au aceeași parametri (lățime, înălțime, etc), sau nu sunt aceleași formate/codecuri, sau dacă doriți să efectuați orice filtrare. (Ai putea re-codifica doar intrările care nu't se potrivesc așa că împart același codec și alți parametri, apoi utilizați concat demuxer pentru a evita re-codare alte intrări).

  • concat demuxer: Utilizați atunci când doriți, pentru a evita o re-encode și format nu are suport pentru fișiere nivel de concatenare (cele mai multe fișiere folosite de către utilizatorii generale nu suport fișier nivel de concatenare).

  • concat protocol: a se Utiliza cu formate de fișiere de sprijin la nivel de concatenare (MPEG-1, MPEG-2 PS, DV). A nu se folosi cu MP4.

Dacă aveți dubii, încercați concat demuxer.

# # , De asemenea, a se vedea

Comentarii (26)

PENTRU FIȘIERE MP4

Pentru .mp4 fișiere (pe care le-am obținut de la DailyMotion.com: 50 minute tv episod, descarca numai în trei părți, trei .fișiere video mp4) următoarele fost o soluție eficientă pentru Windows 7, și nu NU implică re-codare a fișierelor.

Am redenumit fișiere (ca file1.mp4, file2.mp4, file3.mp4) astfel încât părțile au fost în ordinea corectă pentru vizualizarea completă tv episod.

Apoi am creat un simplu fișier batch (concat.bat), cu următorul cuprins:

:: Create File List
echo file file1.mp4 >  mylist.txt 
echo file file2.mp4 >> mylist.txt
echo file file3.mp4 >> mylist.txt

:: Concatenate Files
ffmpeg -f concat -i mylist.txt -c copy output.mp4

La fișier batch și ffmpeg.exe trebuie să fie pus în același folder ca .fișiere mp4 s-a alaturat. Apoi rulați fișierul batch. De obicei va dura mai puțin de zece secunde pentru a rula. .

Addendum (2018/10/21) -

Dacă ceea ce căutați este o metodă pentru a preciza toate mp4 fișiere în folderul curent, fără o mulțime de dactilografiate, încercați acest lucru în Windows fișier batch în loc de (TREBUIE include opțiunea -în condiții de siguranță 0):

:: Create File List
for %%i in (*.mp4) do echo file '%%i'>> mylist.txt

:: Concatenate Files
ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp4

Aceasta funcționează pe Windows 7, într-un fișier batch. Don't încercați să utilizați-l în linia de comandă, pentru că ea funcționează doar într-un fișier batch!

Comentarii (8)

Aici's rapid (durează mai puțin de 1 minut) și fără pierderi mod de a face acest lucru fără a avea nevoie de fișierele intermediare:

ls Movie_Part_1.mp4 Movie_Part_2.mp4 | perl -ne 'print "file $_"' | ffmpeg -f concat -i - -c copy Movie_Joined.mp4

"e" conține fișierele să se alăture "perl" creează concatenare fișier de pe-the-fly într-o țeavă "-eu -" partea spune ffmpeg pentru a citi din pipe

(notă - fișierele mele a avut nici spații sau chestii ciudate le - ai'll nevoie caz shell-evadarea dacă vrei să faci această idee cu "tare" fișiere).

Comentarii (9)

pentru fișiere MP4:

Dacă acestea nu sunt exact la fel (100% acelasi codec, aceeași rezoluție, același tip) fișiere MP4, atunci va trebui să trans-cod-le în fluxuri intermediare de la inceput:

ffmpeg -i myfile1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts temp1.ts
ffmpeg -i myfile2.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts temp2.ts
// now join
ffmpeg -i "concat:temp1.ts|temp2.ts" -c copy -bsf:a aac_adtstoasc output.mp4

NOTA!: Producția va fi ca primul fișier ( și nu un al doilea)

Comentarii (9)

Am fost încercarea de a înlănțui trei .mp3 audio fișiere într-un singur.m4a fișier și acest ffmpeg lucrari de comandă.

Comanda de intrare:

ffmpeg -i input1.mp3 -i input2.mp3 -i input3.mp3 -filter_complex concat=n=3:v=0:a=1 -f MOV -vn -y input.m4a

Semnificațiile : " -filter_complex concat=n=3:v=0:o=1" :

concat înseamnă utilizarea mass-media de concatenare (unire) funcția de.
n înseamnă a confirma numărul total de fișiere de intrare.
v înseamnă has video? utilizați 0 = nici un video, 1 = conține video.
o înseamnă has audio? utilizați 0 = nici audio, 1 = conține audio.
-f mijloace vigoare a seta formatul de fișier (pentru a vedea toate formatele suportate, folosesc ffmpeg -ce`)
-vn înseamnă dezactiva video (și, de asemenea, "- o " - ar dezactiva audio dacă nu a vrut)
-y înseamnă suprascrie fișierele de ieșire (dacă fișierul de ieșire există deja).

Pentru mai multe informatii: folosesc ffmpeg -h plin` imprimare toate opțiunile (inclusiv toate format și codec opțiuni specifice, foarte mult)

Comentarii (2)
Soluția

Am ajuns să folosesc mpg ca intermediar format și a funcționat (REȚINEȚI acest lucru este un exemplu periculos, -qscale 0 va re-encode video...)

ffmpeg -i 1.mp4 -qscale 0 1.mpg
ffmpeg -i 2.mp4 -qscale 0 2.mpg
cat 1.mpg 2.mpg | ffmpeg -f mpeg -i - -qscale 0 -vcodec mpeg4 output.mp4
Comentarii (13)

Documentație detaliată cu privire la diferite moduri de înlănțuire în ffmpeg poate fi a găsit aici.

Puteți utiliza 'Concat filtru' pentru rapid concatenare.

Se efectuează o re-encode. Această opțiune este cel mai bine atunci când intrările au diferite formate video/audio.

Pentru Concatenarea 2 fișiere:

ffmpeg -i input1.mp4 -i input2.webm \
-filter_complex "[0:v:0] [0:a:0] [1:v:0] [1:a:0] concat=n=2:v=1:a=1 [v] [a]" \
-map "[v]" -map "[a]" output.mp4

Pentru Concatenarea 3 fișiere:

ffmpeg -i input1.mp4 -i input2.webm -i input3.mp4 \
-filter_complex "[0:v:0] [0:a:0] [1:v:0] [1:a:0] [2:v:0] [2:a:0] concat=n=3:v=1:a=1 [v] [a]" \
-map "[v]" -map "[a]" output.mp4

Aceasta funcționează și pentru aceeași, precum și mai multe tipuri de fișiere de intrare.

Comentarii (12)

aceasta a lucrat pentru mine (pe windows)

ffmpeg -i "concat:input1|input2" -codec copy output

un exemplu...

ffmpeg -i "concat:01.mp4|02.mp4" -codec copy output.mp4

Python

Folosind un cod python să o facă cu cât mai multe mp4 există într-un folder (instala python de la python.org, copiați și inserați codul și de a salva acest cod într-un fișier numit mp4.py și rulați-l din cmd deschis în dosarul cu python mp4.py și toate mp4 în dosarul va fi concatenate)

import glob
import os

stringa = ""
for f in glob.glob("*.mp4"):
    stringa += f + "|"
os.system("ffmpeg -i \"concat:" + stringa + "\" -codec copy output.mp4")

Versiunea 2 cu Python

Luate din post pe blog-ul meu, acest lucru este cum am face-o în python:

import os
import glob

def concatenate():
    stringa = "ffmpeg -i \"concat:"
    elenco_video = glob.glob("*.mp4")
    elenco_file_temp = []
    for f in elenco_video:
        file = "temp" + str(elenco_video.index(f) + 1) + ".ts"
        os.system("ffmpeg -i " + f + " -c copy -bsf:v h264_mp4toannexb -f mpegts " + file)
        elenco_file_temp.append(file)
    print(elenco_file_temp)
    for f in elenco_file_temp:
        stringa += f
        if elenco_file_temp.index(f) != len(elenco_file_temp)-1:
            stringa += "|"
        else:
            stringa += "\" -c copy  -bsf:a aac_adtstoasc output.mp4"
    print(stringa)
    os.system(stringa)

concatenate()
Comentarii (4)

Am găsit o țeavă de operatorul nu au de lucru pentru mine atunci când se utilizează opțiunea 3 pentru a concat mai multe MP4s pe un Mac în răspunsul acceptat.

Următoarele o-liner funcționează pe un Mac (High Sierra) pentru a concatena mp4s, cu nici un intermediar crearea de fișiere necesare.

ffmpeg -f concat -în condiții de siguranță 0 -i <(pentru f în ./*.mp4; do echo "dosar &#39;$PWD/$f&#39;"; realizat) -c ieșire copii.mp4

Comentarii (1)

bazat pe rogerdpack's și Ed999's de răspunsuri, am'am creat mea .sh versiune

#!/bin/bash

[ -e list.txt ] && rm list.txt
for f in *.mp4
do
   echo "file $f" >> list.txt
done

ffmpeg -f concat -i list.txt -c copy joined-out.mp4 && rm list.txt

se alătură toate *.mp4 fișierele în folderul curent îns-au alăturat-out.mp4`

testat pe mac.

rezultate filesize este exact suma de 60 de testat fișiere. Nu ar trebui să fie nici o pierdere. Doar ceea ce am nevoie

Comentarii (0)

Din documentația aici: https://trac.ffmpeg.org/wiki/Concatenate

Dacă aveți fișiere MP4, acestea ar putea fi fi concatenate de prima transcodare le MPEG-2 fluxuri de transport. Cu video H. 264 și AAC audio, următoarele pot fi folosite:

ffmpeg -i input1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate1.ts
ffmpeg -i input2.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate2.ts
ffmpeg -i "concat:intermediate1.ts|intermediate2.ts" -c copy -bsf:a aac_adtstoasc output.mp4

Această abordare funcționează pe toate platformele.

Am nevoie de capacitatea de a îngloba acest lucru într-un cross-platform script, asa ca am folosit `fluent-ffmpeg și a venit cu următoarea soluție:

const unlink = path =>
  new Promise((resolve, reject) =>
    fs.unlink(path, err => (err ? reject(err) : resolve()))
  )

const createIntermediate = file =>
  new Promise((resolve, reject) => {
    const out = `${Math.random()
      .toString(13)
      .slice(2)}.ts`

    ffmpeg(file)
      .outputOptions('-c', 'copy', '-bsf:v', 'h264_mp4toannexb', '-f', 'mpegts')
      .output(out)
      .on('end', () => resolve(out))
      .on('error', reject)
      .run()
  })

const concat = async (files, output) => {
  const names = await Promise.all(files.map(createIntermediate))
  const namesString = names.join('|')

  await new Promise((resolve, reject) =>
    ffmpeg(`concat:${namesString}`)
      .outputOptions('-c', 'copy', '-bsf:a', 'aac_adtstoasc')
      .output(output)
      .on('end', resolve)
      .on('error', reject)
      .run()
  )

  names.map(unlink)
}

concat(['file1.mp4', 'file2.mp4', 'file3.mp4'], 'output.mp4').then(() =>
  console.log('done!')
)
Comentarii (0)

Aici este un script am făcut pentru a concatena mai multe GoPro mp4's într-un 720p mp4. Sper's de ajutor.

#!/bin/sh
cmd="( "
for i; do
    cmd="${cmd}ffmpeg -i $i -ab 256000 -vb 10000000 -mbd rd -trellis 2 -cmp 2 -subcmp 2 -g 100 -f mpeg -; "
done
cmd="${cmd} ) | ffmpeg -i - -vb 10000000 -ab 256000 -s 1280x720 -y out-`date +%F-%H%M.%S`.mp4"
echo "${cmd}"
eval ${cmd}
Comentarii (2)

Pentru .mp4 dosar, am constatat că funcționează mai bine și mai rapid de a utiliza open source de linie de comandă instrument:mp4box`. Apoi puteți folosi în felul acesta:

mp4box.exe -add video1.mp4 -cat video2.mp4 destvideo.mp4

Descărcați de aici pentru cele mai multe platforme: https://gpac.wp.imt.fr/mp4box/

Comentarii (2)
ffmpeg \
  -i input_1.mp4 \
  -i input_2.mp4 \
  -filter_complex '[0:v]pad=iw*2:ih[int];[int][1:v]overlay=W/2:0[vid]' \
  -map [vid] \
  -c:v libx264 \
  -crf 23 \
  -preset veryfast \
  output.mp4
Comentarii (3)

Fuzionarea tuturor mp4 fișierele din directorul curent

Eu personal ca nu crearea de fișier extern care trebuie să ștergeți după aceea, așa că soluția mea a fost următorul care include fișiere de numerotare listare (ca file_1_name, file_2_name, file_10_name, file_20_name, file_100_name, ...)

#!/bin/bash
filesList=""
for file in $(ls -1v *.mp4);do #lists even numbered file
    filesList="${filesList}${file}|"
done
filesList=${filesList%?} # removes trailing pipe
ffmpeg -i "concat:$filesList" -c copy $(date +%Y%m%d_%H%M%S)_merged.mp4
Comentarii (2)

După diverse încercări de mai jos script-ul a lucrat pentru mine pe windows 10 powershell.

    $files=Get-ChildItem -path e:\ -Filter *.mp4

    $files| ForEach-Object  {"file '$($_.FullName)'"}| Out-File -FilePath e:\temp.txt -Encoding ASCII

    if (-not (test-path "e:\ffmpeg\bin\ffmpeg.exe")) {throw "e:\ffmpeg\bin\ffmpeg.exe needed"}

    E:\ffmpeg\bin\ffmpeg.exe -safe 0 -f concat -i "e:\temp.txt" -c copy -bsf:v hevc_mp4toannexb -an e:\joined.mp4

    # Conversion Cleanup
    Remove-Item e:\temp.txt

Aici primele două linii crea un fișier text temp.txt care are următorul conținut

file 'e:\first.mp4'
file 'e:\second.mp4'

3, 4 linii verifică dacă ffmpeg este disponibil la cale și de a crea "s-a alăturat.mp4"

Diferențele cheie de la alte răspunsuri sunt mai jos

usage  of -bsf:v hevc_mp4toannexb -an

pentru mp4 fișier de mai sus nu funcționează, poate fi necesar să utilizați alte alternative, cum ar fi de mai jos în funcție de codare video.

h264_mp4toannexb

Toate aceste posibile Bitstream filtre pot fi găsite la https://ffmpeg.org/ffmpeg-bitstream-filters.html

Comentarii (1)

Aici's metoda mea pentru aderarea la un director plin de fișiere MP4 folosind comanda de substituție și concat filtru video (acest lucru va re-encode) - a gândit că cineva va folosi la ceva de acest one-liner, mai ales dacă aveți multe fișiere (m-am alăturat 17 fișiere într-o singură lovitură):

ffmpeg $(for f in *.mp4 ; do echo -n "-i $f "; realizat) -filter_complex \ "$(i=0 ; for f in *.mp4 ; do echo -n "[$i:v] [$i:o] " ; i=$((i+1)) ; face \ && echo "concat=n=$i:v=1:a=1 [v] [a]")" harta "[v]" harta "[o]" de ieșire.mp4

N. B. această comandă se alătură fișierele în ordinea în care au're nume (adică aceeași ordine în care au're prezentat, dacă tu a alerga e *.mp4) - in cazul meu, fiecare din ei a avut un număr de pistă, așa că a lucrat mare.

Comentarii (0)

La concat protocolul descris aici; https://trac.ffmpeg.org/wiki/Concatenate#protocol

Atunci când sunt implementate folosind numele conducte pentru a evita fișierele intermediare

Este foarte rapid (a se citi: instant), nu are cadre a scăzut, și funcționează bine.

Amintiți-vă pentru a șterge numit țeavă de fișiere și amintiți-vă să verificați dacă video este H264 AAC și pe care le puteți face cu doar ffmpeg -am filename.mp4` (verifica pentru h264 aac și mențiuni)

Comentarii (0)