Làm cách nào để hợp nhất nhiều (hơn hai) video trên Ubuntu?


39

Tôi muốn hợp nhất các video theo kích cỡ lô hai mươi (20) mỗi video. Tôi đang chạy một máy Linux. Các video có định dạng mp4 và chất lượng vừa phải. Một số thậm chí còn thiếu luồng âm thanh. Cho đến nay tôi đã cố gắng ffmpeg, mencoder, cvlc/vlcMP4Box. Tôi muốn viết một kịch bản dòng lệnh để đạt được điều này, vì tôi đang xử lý hàng loạt.

Vấn đề chính là một số giải pháp tôi đã thử hoạt động tốt cho hai video, một số giải pháp hoạt động tốt cho video có luồng âm thanh và một số giải pháp khác hoạt động tốt đối với một số tập hợp con khác của bộ video của tôi. Tuy nhiên, tôi chưa thể tìm ra giải pháp toàn diện cho nhiệm vụ này.


2
Xin đừng hỏi cùng một câu hỏi trong nhiều trang SE: superuser.com/questions/928548/,
Maythux

Bạn có thể gửi cụ thể những gì bạn đã cố gắng cho đến nay?
ohaal

1
@ohaal Tôi đã thử sử dụng các phương pháp nối khác nhau được đưa ra ffmpeg, bao gồm các bộ lọc và giao thức tệp. Tôi cũng đã thử sử dụng concattính năng của cvlc/vlc. Tôi cũng đã thử concattính năng của mencoder. Tất cả những thứ này đã làm việc một phần. Điều này cuối cùng đã giúp tôi giải quyết vấn đề.
Dhruv Singal

Vâng, bạn đã đề cập đến các công cụ, ý tôi là các lệnh thực tế bạn đã chạy. Ngoài ra, sẽ thật tuyệt nếu bạn có thể bao gồm lệnh kết thúc giải quyết nó cho bạn (trong câu trả lời của bạn), cho khách truy cập trong tương lai.
ohaal

Aah, tôi thấy quan điểm của bạn. Thật không may, tôi không thể liệt kê các lệnh do số tuyệt đối. Lệnh giải quyết vấn đề của tôi là đâymelt {input-sequence} -consumer avformat:{output-name} acodec=libmp3lame vcodec=libx264
Dhruv Singal

Câu trả lời:


41

Tôi đang sử dụng mkvmergeđể nối nhiều tệp MP4 thành một tệp duy nhất:

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

3
Tốt hơn là sử dụng phần mở rộng .mkvcho tệp đầu ra, vì nó là một thùng chứa Matroska bất kể bạn mở rộng phần mở rộng nào.
haridsv

Dưới đây là cách cài đặt mkvmerge: tipsonubfox.com
Morgoth

Chỉ lệnh này mkvmerge hoạt động. Tất cả những người ffmpeg đều thất bại với âm thanh thay đổi ít nhất.
42n4

25

Bạn có thể làm điều đó bằng cách sử dụng ffmpeg:

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

tham khảo và biết thêm thông tin


2
Tôi đã cố gắng làm điều đó. Vấn đề với điều này là nó không đưa ra một cách đúng đắn. 1. Các bản nhạc âm thanh bị rối. 2. Có một số nhiễu loạn trong video theo dõi.
Dhruv Singal

Tôi đã sử dụng nó cho nhiều hơn mẫu, kết quả là chất lượng cao, có thể chất lượng video nguồn của bạn là vấn đề?
Maythux

Bạn có thể đúng. Điều này đã giải quyết được vấn đề: Askubfox.com/a/637179/420614
Dhruv Singal

2
Không sử dụng giao thức concat để nối MP4. Nó chỉ hoạt động với các định dạng nhất định mà hầu hết người dùng phổ thông không gặp phải. Thay vào đó, sử dụng bộ lọc concux hoặc bộ lọc concat .
llogan

Tôi đã thử ffmpeg với 2 tệp mp4 mỗi tệp 30 phút. Tôi nhận được một tập tin đầu ra với độ dài 7 giờ.
Guus

7

Điều này đã giải quyết được vấn đề: https://stackoverflow.com/a/22324018/5014767

meltlà một tiện ích dòng lệnh tuyệt vời cho việc này. Đây là trang

Chỉnh sửa từ các bình luận: Lệnh giải quyết vấn đề của tôi là melt {input-sequence} -consumer avformat:{output-name} acodec=libmp3lame vcodec=libx264


4

Tôi đã viết một kịch bản shell nhỏ để concat MP4 mà không cần chuyển mã bằng 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

Điều này tạo ra các tệp trung gian trong một thùng chứa MPEG và sau đó ghép chúng thành một MP4.


Điều quan trọng cần lưu ý là tập lệnh này sẽ thất bại nếu bất kỳ tên tệp nào chứa khoảng trắng hoặc, trong một số trường hợp, các ký tự đặc biệt. Đối với vòng lặp, tốt hơn đáng kể là chỉ sử dụng for f in *.MP4mà không cần sử dụng ls. (Bạn nên luôn luôn tránh sử dụng lstrong các kịch bản cho một vài lý do quan trọng; có những lựa chọn tốt hơn.) Ngoài ra, dấu ngoặc kép sử dụng cho các biến trừ khi bạn là chắc chắn rằng không có khoảng trắng hoặc ký tự đặc biệt khác, vì vậy "${f}"(hoặc chỉ "$f") thay vì không thể viện chứng $f.
Paddy Landau

CONCAT=$(echo $(ls *.ts) | sed -e "s/ /|/g")không hoạt động tốt với các tên tệp là 1, 2, 3 ... 10 ... 20. Cuối cùng, phân tích chúng thành 1, 10 ... 2, 20 ... vv Tôi đề nghị CONCAT=$(echo $(ls -v *.ts) | sed -e "s/ /|/g")điều này sẽ đảm bảo trật tự .
tisaconundrum

2

Tạo một tệp file.txt với tất cả các tệp bạn muốn ghép nối theo mẫu sau (các dòng bắt đầu bằng # bị bỏ qua):

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

Lưu ý rằng đây có thể là đường dẫn tương đối hoặc tuyệt đối. Sau đó, bạn có thể truyền phát bản sao hoặc mã hóa lại các tệp của mình:

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

0

Kịch bản của tôi, hoàn toàn trong bashffmpeg. Mã hóa lại các tập tin được đưa ra trên một dòng lệnh thành một.

Yêu cầu các tệp phải có cùng độ phân giải. Chấp nhận xoay vòng siêu dữ liệu khác nhau, điều ffmpeg concat:này không.

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

Tôi đã tạo một tập lệnh Python , bằng cách sử dụng filmpy , có thể ghép các phần con (cũng hữu ích nếu bạn muốn xóa một số phần khỏi video).

Sử dụng nó với:

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

-1

Ngoài câu trả lời của Maythux, từ :

Một vài thùng chứa đa phương tiện (MPEG-1, MPEG-2 PS, DV) cho phép một người ghép video bằng cách chỉ ghép các tệp chứa chúng.

Tức là các video được ghép nối sử dụng một trong các bộ chứa video đã nói ở trên (tôi sẽ thêm MPEG-4 Phần 14 cho trải nghiệm cá nhân), bạn có thể chỉ cần:

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

1
Tôi đã thử điều này nhưng nó chỉ trả về video đầu tiên là đầu ra. Tôi đọc ở đâu đó rằng nó không hoạt động, mặc dù tôi không nhớ lý do căn bản đằng sau này.
Dhruv Singal

@DhruvSingal Vâng, tôi có thể xác nhận điều này, tôi đã thử điều này trên hai video MP4 với cùng mã hóa video / âm thanh chính xác và vì bạn chỉ có thể duyệt qua video đầu tiên. Điều này có vẻ hợp lý, tuy nhiên tôi khá chắc chắn rằng tôi đã từng làm điều này trước đây với một vài video MP4. Có lẽ bộ nhớ không phục vụ tốt ở đây hoặc có những yêu cầu khác để làm việc này. Tôi muốn nghiên cứu về vấn đề này vì tôi cũng quan tâm, nếu tôi tìm thấy điều gì đó tôi sẽ cập nhật câu trả lời và gửi cho bạn một nhận xét
kos

Bằng cách nào đó, chúng tôi cần thay đổi siêu dữ liệu khi bắt đầu video đầu tiên để bao gồm toàn bộ thời lượng của bộ phim kết hợp và các nội dung khác có thể. Chỉ một vài tệp mpeg4 cho tôi xem siêu dữ liệu ..
Ken Mollerup
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.