Linux'ta mp4 dosyalarına katılın


31

Tek bir tane oluşturmak için iki mp4 dosyasına katılmak istiyorum. Video akışları h264'te ve sesler aac olarak kodlanmıştır. Hesaplamalı sebeplerden dolayı videoları tekrar başka bir formatta kodlayamıyorum. Ayrıca, herhangi bir GUI programı kullanamıyorum, tüm işlemler Linux komut satırı yardımcı programları ile yapılmalıdır. FFmpeg bunu mpeg4 dosyaları için yapamaz, bu yüzden MP4Box kullandım:

MP4Box -add video1.mp4 -cat video2.mp4 newvideo.mp4

Maalesef ses tamamen karışıyor. Sorunun sesin aac olduğunu sanıyordum, bu yüzden mp3 olarak kodladım ve tekrar MP4Box kullandım. Bu durumda ses newvideo.mp4( yarısına karşılık gelen video1.mp4) ilk yarısı için gayet iyi ancak sonra ses yok ve videoda da gezinemiyorum.

Bir sonraki düşüncem, ses ve video akışlarının, uzunluklarında düzeltmem gereken bazı küçük tutarsızlıklar olduğu idi. Böylece her giriş videosu için video ve ses akışlarını böldüm ve sonra FFmpeg'deki -shortest seçeneğiyle birleştirdim.

Böylece koştuğum ilk video için:

 avconv -y -i video1.mp4 -c copy -map 0:0 videostream1.mp4
 avconv -y -i video1.mp4 -c copy -map 0:1 audiostream1.m4a
 avconv -y -i videostream1.mp4 -i audiostream1.m4a  -c copy -shortest  video1_aligned.mp4

Benzer şekilde ikinci video için ve daha önce olduğu gibi MP4Box kullanılmış. Ne yazık ki bu da işe yaramadı. Elimdeki tek başarı, video akışlarına ayrı ayrı (yani videostream1.mp4 ve videostream2.mp4) ve ses akışlarına (yani audiostream1.m4a ve audiostream2.m4a) katıldığımda ve ardından video ve sese son bir dosyada katıldı. Ancak, videonun ikinci yarısında senkronizasyon kaybedilir. Somut olarak, 1 saniyelik bir ses ve video gecikmesi var. Herhangi bir öneriniz gerçekten bekliyoruz.


"FFmpeg bunu mpeg4 dosyaları için yapamaz bu yüzden MP4Box kullandım" demek istiyorsun MP4 dosyası? ? her ikisini de ses-video kullanımları aynı kodlama parametreleri (genişlik, yükseklik, SPS, PPS, kanalların görüntüyü, Samplingrate, sayı akışları

ffprobe kullanarak ses akışlarının aynı özelliklere sahip olduğunu görüyorum. Video akışları aynı boyutlarda ancak farklı oranlarda. İlk video için Video: h264, 720x592, 277 kb / s, PAR 18944: 12915 DAR 512: 287, 24.97 fps, 45k tbr, 90k tbn, 90k tbc, ikinci Video için: h264, 720x592, 226 kb / s, PAR 481: 330 DAR 39:22, 24.91 fps, 45k tbr, 90k tbn, 90k tbc. Bunun problemlerimin kaynağı olduğuna inanıyor musunuz?

MP4, farklı video için farklı parçalar kullanarak farklı özelliklere sahip video / sese katılmayı destekler, ancak oynatıcı o kadar akıllı değildir.
rajneesh


Sorunuz zaten ffmpeg SSS’de yanıtlandı: ffmpeg.org/faq.html#How-can-I-join-video-files_003f
Palec

Yanıtlar:


31

Bunu yapmanın en iyi yolu şu anda concat demuxer ile . İlk önce, şöyle inputs.txtbiçimlendirilmiş bir dosya oluşturun :

file '/path/to/input1.mp4'
file '/path/to/input2.mp4'
file '/path/to/input3.mp4'

Ardından, sadece bu ffmpeg komutunu çalıştırın:

ffmpeg -f concat -i inputs.txt -c copy output.mp4

SSS bölümündeki birleştirmeffmpeg bölümüne de bakın .


Ffmpeg'ün eski sürümlerini kullanan herkesin yararına aşağıdakileri burada tutuyorum.

Ffmpeg'in en son sürümleri bunu yapabilir: dosyaları önce mpeg aktarım akışlarına dönüştürmeniz gerekir (yalnızca kap formatını değiştirdiği için oldukça işlemci ışığı):

ffmpeg -i input.mp4 -map 0 -c copy -f mpegts -bsf h264_mp4toannexb middle.ts

Bu h264 hakkında bir hata atarsa, kullanmanız gerekebilir:

ffmpeg -i input.mp4 -map 0 -c copy -f mpegts -bsf h264_mp4toannexb middle.ts

Her giriş dosyasında bunu ayrı ayrı yapmanız gerekecektir. Dosyaları bir araya getirmek için şunu kullanın:

ffmpeg -i "concat:middle1.ts|middle2.ts|middle3.ts" -c copy output.mp4

Bu aac hakkında bir hata atarsa, kullanmanız gerekebilir

ffmpeg -i "concat:middle1.ts|middle2.ts|middle3.ts" -c copy -absf aac_adtstoasc output.mp4

Sisteminiz adlandırılmış yöneltmeleri destekliyorsa, bunu ara dosyalar oluşturmadan da yapabilirsiniz.

mkfifo temp0 temp1

Aşağıdakileri üç ayrı sanal terminalde yapmanız gerekecektir:

ffmpeg -i input0.mp4 -map 0 -c copy -f mpegts -bsf h264_mp4toannexb -y temp0
ffmpeg -i input1.mp4 -map 0 -c copy -f mpegts -bsf h264_mp4toannexb -y temp1
ffmpeg -f mpegts -i "concat:temp0|temp1" -c copy -absf aac_adtstoasc output.mp4

Eğer output.mp4 zaten mevcutsa, üçüncü ffmpeg size üzerine yazmak isteyip istemediğinizi soracaktır, ancak bunu FIFO'lara eriştikten sonra yapacak ve bu ilk önce ffmpeg'leri kapatacak. Bu yüzden çıktı dosyanız için kullanılmayan bir isim seçtiğinizden emin olun.

Girdi dosyalarınız farklıysa bu işe yaramayabilir - Bit hızındaki farklılıkların iyi olduğuna inanıyorum, ancak kare boyutu, kare hızı vb. Eşleşmesi gerekiyor.


çok iyi thx arkadaşı, bir cazibe gibi çalıştı
Jose Armando

2
@DaveJarvis Öyle değil; bu, avconv'u geliştirmek için ffmpeg projesinden ayrılan bir avuç geliştirici olan libav ekibi tarafından kasıtlı ve kötü amaçlı bir şekilde yayılan bir mesajdı (ve ffmpeg adına telif hakkı güvenceye alınmadığından adını değiştirdi). Bkz Kim bana ffmpeg, libav ve avconv arasındaki farkı ve ilişkiyi söyleyebilir? biraz daha fazla bilgi için.
kötülük

2
*** THIS PROGRAM IS DEPRECATED *** This program is only provided for compatibility and will be removed in a future release. Please use avconv instead.şimdi koşarken gördüğüm bir mesajffmpeg
Lord Loh.

@LordLoh. Önceki yorumumdaki bağlantıya bakın.
evilsoup

1
Bu cevap cevap vermiyor - mp4 ile nasıl bir araya getirileceğiavconv
Lord Loh.

7

Mp4 için bulduğum tek çalışma çözümü gpac paketindeki MP4Box ile oldu.

#!/bin/bash
filesList=""
for file in $(ls *.mp4|sort -n);do
    filesList="$filesList -cat $file"
done
MP4Box $filesList -new merged_files_$(date +%Y%m%d_%H%M%S).mp4

veya komut

MP4Box -cat file1.mp4 -cat file2.mp4 -new mergedFile.mp4

mencoder ve avconv ile çalışamam.: ((


2

Senaryo dvo için teşekkürler. Benim için harika bir başlangıç ​​noktasıydı. Adlandırılmış yöneltmeler kullanmakta bir sorunum olmadığından, senaryoyu kullanmak için uyarladım. Artı, içinde boşluk bulunan dosya isimleriyle çalışmasını da düzelttim. Adlandırılmış yöneltmelere çıkış, siz onlardan okumaya başlayana kadar "gitmez", bu nedenle ilk remux görevlerini avconv son çağrısından önce & sonra arka planlamanız gerekir. Artı, -c kopyasını kullanmayı unutma, ya da tüm partiyi tekrar kodlarsın.

#!/bin/bash
for FILE in "$@"; do
   TAG=$(echo "$FILE" | sed -e s/[^A-Za-z0-9.]/_/g)
   mkfifo $TAG.mp4concatpipe
   avconv -loglevel "quiet" -i "$FILE"  -f mpegts -c copy -bsf h264_mp4toannexb -y $TAG.mp4concatpipe &
   IN=$IN\|$TAG.fifo
done

IN=${IN#\|}
avconv -i concat:$IN -c copy out.mp4
rm *.mp4concatpipe

Nedense bu bana bir "concat: first.m4v.fifo | second.m4v.fifo:" böyle bir dosya ya da dizin yok "hatası veriyor. Alıntılar bile olsa (-i concat:" $ IN "ya da -i" concat: $ IN "). MP4Box aşağıdaki diğer cevabında önerilen ancak harika çalışıyor!
vorburger

2

Mac'te (macOS 10.13 High Sierra) Aşağıdakileri başarı ile kullandım:

for f in *.m4a; do echo "file '$f'" >> mylist.txt; done

Gerekirse yukarıdaki gibi tekrar sıralayın (./ kaldırıldığını unutmayın - yol ffmpeg dosyasının güvenli olmayan dosya adı hatasını atmasına neden oluyordu).

Sonra varsayılan MacPorts ffmpeg için belirtilen codec ve bitrate kaldırmak zorunda kaldı:

ffmpeg -f concat -i mylist.txt  output.m4a

Super User'a Hoşgeldiniz! Lütfen soruyu tekrar dikkatlice okuyunuz. Cevabınız linux ile ilgili orijinal soruya cevap vermiyor. Linux üzerinde çalışacağına inanıyorsanız, lütfen gelecekteki okuyucuların yine süper kullanıcılara hoş geldiniz demenizin ve girişiniz için teşekkür etmenizin net bir anlayışının olduğunu da ekleyin. Lütfen birkaç dakikanızı ayırın ve okuyun: - superuser.com/help .Alı cevap: superuser.com/help/how-to-answer .
mic84

2

İşte hepsini bu kadar kolaylaştıran tek bir astar. Size sonuçta ortaya çıkan bir video dosyasını sağlamak için yapılması gereken her şeyi yapar. Şerefe!

find *.mp4 | sed 's:\ :\\\ :g'| sed 's/^/file /' > list.txt; ffmpeg -f concat -i list.txt -c copy output.mp4; rm list.txts

1

Teşekkürler kötülük; Burada en yeni olanı kullanarak işlemi otomatikleştirmek için küçük bir senaryo var avconv.
BTW, adlandırılmış yöneltmeler benim için işe yaramadı (çıkışları sıkışmış).

   #!/bin/bash

    for FILE in $@; do
      avconv -i $FILE -map 0 -f mpegts -bsf h264_mp4toannexb -c:v copy -y $FILE.tmp
      IN=$IN\|$FILE.tmp
    done

    IN=${IN#\|}
    avconv -i concat:"$IN" out.mp4

    for FILE in $@; do
      rm $FILE.tmp
    done

0

İle büyük başarılar elde ettik

for f in ./*.m4a; do echo "file '$f'" >> mylist.txt; done

mylist.txt dosyasını biraz sıralamanız gerekebilir

ffmpeg -f concat -i mylist.txt -c:a libfdk_aac -b:a 128k output.m4a

ffmpeg sürüm 2.2.3

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.