Як об'єднати кілька (більше двох) відео на Ubuntu?


39

Я хочу об'єднати відео у розмірі серії двадцять (20). Я працюю на версії Linux. Відео у форматі mp4 та середньої якості. У деяких навіть відсутній аудіопотік. До сих пір я намагався ffmpeg, mencoder, cvlc/vlcі MP4Box. Я хочу написати сценарій командного рядка, щоб досягти цього, оскільки я роблю пакетну обробку.

Основне питання полягає в тому, що деякі рішення я намагався добре працювати для двох відео, деякі добре працюють для відео з аудіо потоком, а інші добре працюють для деяких інших підмножин мого набору відео. Однак мені не вдалося знайти комплексного рішення цього завдання.


2
Будь ласка, не задайте те саме питання на веб-сайтах SE: superuser.com/questions/928548/…
— Maythux

Чи можете ви опублікувати конкретно те, що ви намагалися до цього часу?
— ohaal

1
@ohaal Я намагався використовувати різні методи конкатенації, наведені в ffmpeg, включаючи фільтри та файлові протоколи. Я також спробував використовувати concatфункцію cvlc/vlc. Я також спробував concatфункцію mencoder. Все це працювало частково. Це нарешті допомогло мені вирішити питання.
— Dhruv Singal

Так, ви вже згадали про інструменти, я мав на увазі фактичні команди, якими ви керували. Також було б чудово, якби ви могли включити команду, яка закінчилася вирішенням її для вас (у своїй відповіді), для майбутніх відвідувачів.
— ohaal

Ааа, я бачу вашу думку. На жаль, я не можу перерахувати команди через чистий номер. Команда, яка вирішила мою проблему, була такаmelt {input-sequence} -consumer avformat:{output-name} acodec=libmp3lame vcodec=libx264
— Друв Сінгал

Відповіді:


41

Я використовую mkvmergeдля об'єднання декількох файлів MP4 в один:

mkvmerge -o outfile.mkv infile_01.mp4 \+ infile_02.mp4 \+ infile_03.mp4

3
Розширення краще використовувати .mkvдля вихідного файлу, оскільки це контейнер Matroska незалежно від того, яке розширення ви надаєте.
— haridsv

Ось як встановити mkvmerge: tipsonubuntu.com
— Моргота

Тільки ця команда mkvmerge працює. Усі ffmpeg не вдається зі зміщеним звуком принаймні.
— 42n4

25

Ви можете зробити це за допомогою ffmpeg:

ffmpeg -i concat:"input1.mp4|input2.mp4" output.mp4

довідка та додаткова інформація


2
Я спробував це зробити. Проблема з цим полягає в тому, що це не дає належних результатів. 1. Аудіозаписи заплутані. 2. У відеодоріжці є деякі порушення.
— Dhruv Singal

Я використовував його для більш ніж зразка, результат - висока якість, можливо, проблема з вашим джерелом відео?
— Maythux

Ви, мабуть, праві. Це вирішило питання: askubuntu.com/a/637179/420614
— Dhruv Singal

2
Не використовуйте протокол concat для об'єднання MP4. Він працює лише з певними форматами, з якими не стикається більшість користувачів. Замість цього використовуйте concat demuxer або concat filter .
— llogan

Я спробував ffmpeg з 2 mp4 файлами по 30 хв кожен. У мене вийшов вихідний файл довжиною 7 годин.
— Гусь

7

Це вирішило питання: https://stackoverflow.com/a/22324018/5014767

meltє чудовою утилітою для цього командного рядка. Ось сторінка

Редагувати з коментарів: Команда, яка вирішила мою проблему, була така melt {input-sequence} -consumer avformat:{output-name} acodec=libmp3lame vcodec=libx264


4

Я написав невеликий скрипт оболонки, щоб сформулювати MP4 без перекодування за допомогою ffmpeg.

for f in $(ls *.MP4); do
    ffmpeg -i $f -c copy -bsf:v h264_mp4toannexb -f mpegts $f.ts
done

CONCAT=$(echo $(ls *.ts) | sed -e "s/ /|/g")

ffmpeg -i "concat:$CONCAT" -c copy -bsf:a aac_adtstoasc output.mp4

rm *.ts

Це створює проміжні файли в контейнері MPEG, а потім з'єднує їх у MP4.


Важливо зазначити, що цей скрипт не вдасться, якщо будь-яка з імен файлів містить пробіли або, в деяких випадках, спеціальні символи. Для циклу значно краще використовувати просто for f in *.MP4без використання ls. (Ви завжди повинні уникати використання lsв скриптах з декількох важливих причин; є кращі варіанти.) Також використовуйте цитати для змінних, якщо ви не впевнені, що немає пробілів чи інших спеціальних символів, так що "${f}"(або просто "$f") замість цитованих $f.
— Падді Ландау

CONCAT=$(echo $(ls *.ts) | sed -e "s/ /|/g")не працює добре з іменами файлів, які є 1, 2, 3 ... 10 ... 20. Це в кінцевому підсумку аналізує їх як 1, 10 ... 2, 20 ... і т.д. Я пропоную CONCAT=$(echo $(ls -v *.ts) | sed -e "s/ /|/g")це забезпечити порядок .
— tisaconundrum

2

Створіть файл file.txt з усіма файлами, які ви хочете об'єднати у такій формі (рядки, що починаються з #, ігноруються):

# this is a comment
file 'file1.mp4'
file '/path/to/file2.mp4'
file 'file3.mp4'

Зауважте, що це можуть бути як відносні, так і абсолютні шляхи. Потім ви можете потоково скопіювати або перекодувати свої файли:

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

0

Мій сценарій, суто в bashі ffmpeg. Перекодуйте файли, подані в командному рядку, в один.

Потрібно, щоб файли були однакової роздільної здатності. Приймає різні обертання метаданих, що ffmpeg concat:не робить.

rm ffmpeg-concat-output.mkv

FILE_COUNT=$#
INPUTS=""
FILTER=""
INDEX=0
for FNAME in $@; do
    echo "Processing ${FNAME}"
    INPUTS="${INPUTS} -i $FNAME"

    if [ -z "${FILTER}" ]; then
        FILTER="[$INDEX:v:0] [$INDEX:a:0]"
    else
        FILTER="${FILTER} [$INDEX:v:0] [$INDEX:a:0]"
    fi
    let INDEX+=1
done

COMMAND="ffmpeg ${INPUTS} \
    -filter_complex '${FILTER} \
        concat=n=${INDEX}:v=1:a=1 [v] [a]' \
    -map '[v]' -map '[a]' \
    ffmpeg-concat-output.mkv"

#   -af 'volume=15dB' # won't work with -filter_complex

bash -c "${COMMAND}"

0

Я створив сценарій Python, який, використовуючи фільм , може об'єднати також підсегменти (корисно, якщо ви хочете, наприклад, видалити деякі частини з відео).

Використовуйте його з:

vcat -i inputfile1,inputfile2[start-end],... -o <outputfile>

-1

Окрім відповіді Мейту, від :

Кілька мультимедійних контейнерів (MPEG-1, MPEG-2 PS, DV) дозволяють об'єднати відео, просто об'єднавши файли, що містять їх.

Тобто відео для об'єднання відео використовує один із вищезазначених контейнерів для відео (до якого я додам MPEG-4, частина 14 для особистого досвіду), ви можете просто:

cat video1.ext video2.ext video3.ext > video4.ext

1
Я спробував це, але він повертає лише перше відео як вихід. Я десь читав, що це не працює, хоча я не пам’ятаю обґрунтування цього.
— Dhruv Singal

@DhruvSingal Так, я можу це підтвердити, я спробував це на двох відео MP4 з точно такою ж кодуванням відео / аудіо, і, як ви, я міг переглядати лише перше відео. Що здається розумним, проте я майже впевнений, що робив це раніше, ніж кілька відео MP4. Можливо, пам’ять тут не служить добре, або для цього є інші вимоги. Я хочу вивчити це, оскільки мені цікаво, якщо я знайду щось, я оновлю відповідь і віддам вам коментар
— kos

Нам потрібно якось змінити метадані на початку першого відео, щоб охопити всю довжину комбінованого фільму та ймовірно інші речі. Лише кілька файлів mpeg4 дозволили мені побачити метадані ..
— Кен Моллеруп
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.