Video dosyalarını etkileşimli olarak birleştirin


9

Birden fazla MP4 video dosyasını etkileşimli olarak tek bir dosyaya nasıl birleştirebiliriz (birleştirebilirsiniz)?

Komut satırından iki dosya için bunu yapan birçok program var. Örneğin:

  • ffmpeg
  • avconv
  • MP4Box

Ancak bunu etkileşimli olarak yapmak için sık sık bir çözüme ihtiyacımız var.


1
Ne demek istediğinizi interaktif olarak anlatabilir misiniz?
slm

@slm Kullanıcıdan girdi dosyalarını teker teker girmesini, ardından oluşturulacak çıktı dosyasını girmesini isteyen bir program kastediyorum. ve sonra birleştirme yapın.
Slyx

Bunu doğrudan yapan bir program görmedim, bu sizin hazırladığınız gibi, bilgileri toplayan ve daha sonra komut satırını birleştiren bir kabuk komut dosyası. Sahip olduklarınızla ilgili iyileştirmeler mi arıyorsunuz?
slm

@slm bunu benim gibi multimedya kullanıcılarına sıkça ihtiyaç duyduğu için yayınladım. Umarım başka birine yardımcı olur. Tabii ki herhangi bir gelişme daha bekliyoruz!
Slyx

1
@gold Kuyruğa bir düzenleme koydum. ffmpegtarafından gerçekten de hiçbir şekilde ölü veya eskimiş: Geçen gittaahhüt masteroldu 15 dakika önce ve ben her gün kullanıyorum.
Anko

Yanıtlar:


8

Bu yöntemi son zamanlarda denemedim ama neden hala işe yaramadığını anlamıyorum. Bunları cat .mp4birleştirmekten başka bir şey yapmak istemiyorsanız dosyaları bir araya getirebileceğinizi düşünüyorum .

1. kedi kullanma

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

Hala ffmpegher zaman kullanıyorum, dosyaları da birleştirebilir.

2. ffmpeg kullanma

  1. Birleştirilecek dosyaların bir listesini yapın

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

    $ 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
    

    Diğer yöntemler FFmpeg wiki'sinde ele alınmıştır: Medya dosyaları nasıl birleştirilir (birleştirilir, birleştirilir) .

    NOT: Ubuntu concatformatı desteklemiyor gibi görünüyor . Concat protokolünü kullanmalısınız. Ayrıca, akış başına kodek seçenekleri vardır. Böylece, concat protokolü kullanılarak aşağıdaki gibi sonuçlar elde edilir:

    $ 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
    

    Ubuntu ffmpeg seçenekleri burada belgelenmiştir .


İlginç ! catMP4 dosyaları için yeterli olduğunu bilmiyordum ! çözüm interaktif değil!
Slyx

@Slyx - evet bu yüzden interaktif olarak ne demek istediğini sordum. Bu konuda söylediklerini göreyim ve buna neler ekleyebileceğimi göreyim. catGerçi çalıştığını kontrol edin . En son kullandığım .mpgdosya ve def ile oldu. onlarla çalıştı.
slm

2
Bunu doğruladım. Kullanmak catgeçerli bir çözüm değildir. catİki dosya girerek oluşturulan dosya sadece ilk girdi dosyasının içeriğini gösterir!
Slyx

@Slyx - kedi çalışıyor ancak zaman damgaları doğru değil, bu yüzden oynatmaya çalıştığınızda video oynatıcı 00'dan sonuna, sonra 00'a kadar zaman damgasındaki atlama ile karışıyor. bu sürecin bir parçası olarak düzeltilecekti. Zaman damgalarını da yeniden oluşturmanın yolları vardır.
slm

Ben de bunu kastediyorum. İki içerik var ama medya oynatıcı ilkini algılıyor.
Slyx

4

MP4Box'ı çalışma tabanı olarak kullanıyorum.
Önerdiğim komut dosyası tüm dosyaları tek tek okur, her birini doğrular (hava durumu normal bir dosyadır), kullanıcıdan giriş dosya adının oluşturulmasını ister.

#!/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 !"
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.