Tương tác các tập tin video


9

Làm cách nào để ghép (nối) nhiều tệp video MP4 thành một tệp tương tác?

Có rất nhiều chương trình thực hiện điều này cho hai tệp từ dòng lệnh. Ví dụ:

  • ffmpeg
  • avconv
  • MP4Box

Nhưng chúng ta thường cần một giải pháp để làm điều này một cách tương tác.


1
Bạn có thể mô tả những gì bạn có nghĩa là tương tác?
slm

@slm Ý tôi là một chương trình yêu cầu người dùng nhập từng tệp đầu vào, sau đó là tệp đầu ra để tạo. và sau đó thực hiện nối.
Slyx

Tôi chưa bao giờ thấy một chương trình thực hiện điều này trực tiếp, như bạn đã tạo ra, một tập lệnh shell thu thập thông tin và sau đó lắp ráp dòng lệnh. Bạn đang tìm kiếm những cải tiến hơn những gì bạn có?
slm

@slm tôi đã đăng bài này vì đó là nhu cầu thường xuyên đối với người dùng đa phương tiện như tôi. Vì vậy, tôi hy vọng nó sẽ giúp người khác. Tất nhiên bất kỳ cải tiến đều được chào đón nhiều hơn!
Slyx

1
@gold Tôi đặt một chỉnh sửa trong hàng đợi. ffmpegthực sự không có nghĩa là đã chết hoặc lỗi thời: gitCam kết cuối cùng master15 phút trước và tôi sử dụng nó hàng ngày.
Anko

Câu trả lời:


8

Tôi đã không thử phương pháp này gần đây nhưng không hiểu tại sao nó vẫn không hoạt động. Tôi tin rằng bạn chỉ có thể cat .mp4tập tin cùng nhau nếu bạn không muốn làm gì khác hơn là ghép chúng lại.

1. Sử dụng mèo

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

Tôi vẫn sử dụng ffmpegtất cả thời gian, nó cũng có thể nối các tập tin.

2. Sử dụng ffmpeg

  1. Tạo một danh sách các tập tin để nối

    $ cat inputs.txt 
    file sample_mpeg4.mp4
    file sample_mpeg4.mp4
  2. ghép

    $ 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

    Các phương pháp khác được trình bày trong wiki FFmpeg: Cách ghép các tệp phương tiện (nối, hợp nhất) .

    LƯU Ý: Ubuntu không xuất hiện để hỗ trợ concatđịnh dạng. Bạn phải sử dụng giao thức concat. Ngoài ra, nó có tùy chọn codec mỗi luồng. Do đó, sử dụng kết quả giao thức concat như sau:

    $ 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

    Các tùy chọn ffmpeg của Ubuntu được ghi lại ở đây .


Hấp dẫn ! Tôi không biết catlà đủ cho các tệp MP4! giải pháp không tương tác mặc dù!
Slyx

@Slyx - yeah đó là lý do tại sao tôi hỏi ý của bạn khi tương tác. Hãy để tôi xem những gì bạn nói về nó và xem những gì tôi có thể thêm vào này. Kiểm tra rằng cathoạt động mặc dù. Lần cuối cùng tôi sử dụng nó là với .mpgcác tập tin và nó def. đã làm việc với những người đó.
slm

2
Tôi đã xác minh rằng. Sử dụng catkhông phải là một giải pháp hợp lệ. Tệp được tạo bằng cách nhập cathai tệp chỉ hiển thị nội dung của tệp đầu vào!
Slyx

@Slyx - mèo hoạt động nhưng dấu thời gian không chính xác, vì vậy khi bạn cố phát lại, trình phát video sẽ bị lẫn lộn bởi bước nhảy trong dấu thời gian từ 00 đến hết, sau đó quay lại 00. Nếu bạn chuyển mã video này sẽ được cố định như là một phần của quá trình đó. Có nhiều cách để tạo lại dấu thời gian là tốt.
slm

Ý tôi là vậy. Hai nội dung ở đó nhưng trình phát đa phương tiện chỉ phát hiện ra nội dung đầu tiên.
Slyx

4

Tôi sử dụng MP4Box làm cơ sở.
Kịch bản tôi đề nghị đọc từng tệp một, xác minh từng tệp (thời tiết là tệp thông thường), yêu cầu người dùng nhập tên tệp đầu vào để tạo.

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