Menggabungkan file video secara interaktif

9

Bagaimana cara menggabungkan (bergabung) beberapa file video MP4 menjadi satu file secara interaktif?

Ada banyak program yang melakukan ini untuk dua file dari baris perintah. Contohnya:

  • ffmpeg
  • avconv
  • MP4Box

Tetapi kita sering membutuhkan solusi untuk melakukan ini secara interaktif.

Slyx
sumber
1
Bisakah Anda menggambarkan apa yang Anda maksud dengan interaktif?
slm
@slm Maksud saya program yang meminta pengguna untuk memasukkan file input satu per satu, kemudian file output untuk dibuat. dan kemudian membuat rangkaian.
Slyx
Saya belum pernah melihat program yang melakukan ini secara langsung, seperti yang Anda buat, skrip shell yang mengumpulkan info dan kemudian merakit baris perintah. Apakah Anda mencari peningkatan atas apa yang Anda miliki?
slm
@slm saya memposting ini karena ini adalah kebutuhan yang sering untuk pengguna multimedia seperti saya. Jadi saya harap ini membantu orang lain. Tentu saja setiap perbaikan lebih dari diterima!
Slyx
1
@gold aku meletakkan edit di antrian. ffmpegmemang tidak mati atau usang: gitKomit terakhir masteradalah 15 menit yang lalu dan saya menggunakannya setiap hari.
Anko

Jawaban:

8

Saya belum mencoba metode ini baru-baru ini tetapi tidak melihat mengapa itu tidak akan berhasil. Saya percaya Anda hanya dapat cat .mp4file bersama jika Anda tidak ingin melakukan apa pun selain menggabungkannya.

1. Menggunakan kucing

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

Saya masih menggunakan ffmpegsepanjang waktu, itu juga dapat menyatukan file.

2. Menggunakan ffmpeg

  1. Buat daftar file untuk digabungkan

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

    $ 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

    Metode lain dicakup dalam wiki FFmpeg: Cara menggabungkan (bergabung, menggabungkan) file media .

    CATATAN: Ubuntu tampaknya tidak mendukung concatformat. Anda harus menggunakan protokol khusus. Selain itu, ia memiliki opsi codec per aliran. Dengan demikian, menggunakan hasil protokol concat sebagai berikut:

    $ 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

    Opsi ffmpeg Ubuntu didokumentasikan di sini .

slm
sumber
Menarik! Saya tidak tahu itu catcukup untuk file MP4! solusinya tidak interaktif!
Slyx
@ Slly - ya itu sebabnya saya bertanya apa yang Anda maksud dengan interaktif. Biarkan saya melihat apa yang Anda katakan tentang itu dan lihat apa yang bisa saya tambahkan ke ini. Periksa apakah itu catberfungsi. Terakhir kali saya menggunakannya adalah dengan .mpgfile dan def. bekerja dengan mereka.
slm
2
Saya memverifikasi itu. Menggunakan catbukanlah solusi yang valid. File yang dihasilkan dengan catdua file hanya menampilkan konten dari file input pertama!
Slyx
@Slyx - cat berfungsi tetapi stempel waktu tidak benar, jadi ketika Anda mencoba memutarnya, pemutar video menjadi bingung dengan lompatan stempel waktu dari 00 hingga akhir, lalu kembali ke 00. Jika Anda melakukan transkode video ini akan diperbaiki sebagai bagian dari proses itu. Ada beberapa cara untuk membuat ulang cap waktu juga.
slm
Itu yang saya maksud juga. Dua konten ada tetapi media player hanya mendeteksi yang pertama.
Slyx
4

Saya menggunakan MP4Box sebagai basis kerja.
Skrip yang saya sarankan membaca semua file satu per satu, memverifikasi masing-masing (apakah ini file biasa), meminta pengguna untuk memasukkan nama file input yang akan dibuat.

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