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:
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.
$ 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
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ă.
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.
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!
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).
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)
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)
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
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.
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
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")
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()
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 '$PWD/$f'"; realizat) -c ieșire copii.mp4
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 în
s-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
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!')
)
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}
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/
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
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
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.
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)