การแก้ไขวิดีโอบรรทัดคำสั่งใน Linux (ตัดเข้าร่วมและดูตัวอย่าง)


32

ฉันมีความต้องการในการแก้ไขที่ง่าย - ฉันต้องตัดวิดีโอบางส่วนอาจแทรก PNG บางส่วนระหว่างกันและเข้าร่วมวิดีโอเหล่านี้ (ไม่จำเป็นต้องมีการเปลี่ยนเอฟเฟ็กต์ ฯลฯ ) โดยพื้นฐานแล้วpitiviจะทำในสิ่งที่ฉันต้องการยกเว้นว่าฉันใช้ 640x480 30 fps AVI's จากกล้องและทันทีที่ฉันใส่เนื้อหาประเภทนั้นสองสามนาทีpitiviเริ่มแช่แข็งตัวอย่างและไม่สามารถใช้งานได้

ดังนั้นฉันเริ่มมองหาเครื่องมือบรรทัดคำสั่งสำหรับ Linux; ฉันเดาเท่านั้นffmpeg( บรรทัดคำสั่ง - การใช้ ffmpeg เพื่อตัดวิดีโอ - Super User ) และmplayer( Sam - แก้ไขไฟล์วิดีโอด้วย mencoder ภายใต้ linux ) เป็นผู้สมัครจนถึงขณะนี้ แต่ฉันไม่พบตัวอย่างของการใช้ที่ฉันมีอยู่ในใจ

 

โดยทั่วไปฉันนึกภาพว่ามีเครื่องมือเข้ารหัสและเครื่องมือเล่น (เช่นffmpegvs ffplay; หรือmencodervs mplayer) - เช่นนั้นเพื่อเริ่มต้นลำดับการแก้ไขสามารถระบุได้โดยตรงบนบรรทัดคำสั่งโดยควรมีความละเอียดของเฟรม - รหัสเทียมจะมีลักษณะดังนี้:

videnctool -compose --file=vid1.avi --start=00:00:30:12 --end=00:01:45:00 --file=vid2.avi --start=00:05:00:00 --end=00:07:12:25 --file=mypicture.png --duration=00:00:02:00 --file=vid3.avi --start=00:02:00:00 --end=00:02:45:10 --output=editedvid.avi

... หรืออาจมีไฟล์ข้อความ "เพลย์ลิสต์" เช่น:

vid1.avi      00:00:30:12 00:01:45:00 
vid2.avi      00:05:00:00 00:07:12:25 
mypicture.png -           00:00:02:00
vid3.avi      00:02:00:00 00:02:45:10 

... ดังนั้นจึงอาจถูกเรียกด้วย

videnctool -compose --playlist=playlist.txt --output=editedvid.avi

ความคิดที่นี่จะเป็นที่วิดีโอทั้งหมดที่อยู่ในรูปแบบเดียวกัน - ช่วยให้เครื่องมือในการหลีกเลี่ยงการแปลงรหัสและเพียงแค่ทำ "สำเนาดิบ" แทน (ในขณะที่mencoder's คัดลอกตัวแปลงสัญญาณ: " -oac copy -ovc copy") - หรือขาดว่า เสียง / วิดีโอที่ไม่บีบอัดจะโอเค (แม้ว่าจะกินพื้นที่สักหน่อย) ในกรณีของภาพนิ่งเครื่องมือจะใช้การเข้ารหัสที่กำหนดโดยไฟล์วิดีโอ

 

สิ่งที่ฉันเห็นจนถึงตอนนี้mencoderและffmpegสามารถทำงานกับไฟล์แต่ละไฟล์; เช่นตัดส่วนเดียวจากไฟล์เดียวหรือเข้าร่วมไฟล์ ( mencoderยังมีEdit Decision Lists (EDL)ซึ่งสามารถใช้ในการทำการตัดเฟรมที่แน่นอน - เพื่อให้คุณสามารถกำหนดขอบเขตการตัดหลายส่วน แต่มันมาประกอบกับไฟล์เดียว ) ซึ่งหมายความว่าฉันต้องทำงานกับการตัดชิ้นแรกจากไฟล์แต่ละไฟล์ก่อน (ซึ่งแต่ละไฟล์ต้องการไฟล์ชั่วคราวบนดิสก์) จากนั้นเข้าร่วมในไฟล์วิดีโอขั้นสุดท้าย

ฉันจะจินตนาการว่ามีเครื่องมือของเครื่องเล่นที่สอดคล้องกันซึ่งสามารถอ่านรูปแบบตัวเลือกบรรทัดคำสั่งเดียวกัน / ไฟล์เพลย์ลิสเป็นเครื่องมือเข้ารหัส - ยกเว้นว่ามันจะไม่สร้างไฟล์เอาต์พุต แต่แทนที่จะเล่นวิดีโอแทน เช่นใน pseudocode:

vidplaytool --playlist=playlist.txt --start=00:01:14 --end=00:03:13

... และให้มีหน่วยความจำเพียงพอก็จะสร้างตัวอย่างความละเอียดต่ำวิดีโอในแรมและเล่นกลับในหน้าต่างในขณะที่นำเสนอบางส่วนปฏิสัมพันธ์ จำกัด (ชอบmplayer's แป้นพิมพ์ลัดสำหรับการเล่น, หยุด, ย้อนกลับ, กรอบขั้นตอน ) แน่นอนฉันจินตนาการถึงเวลาเริ่มต้นและสิ้นสุดเพื่ออ้างถึงเพลย์ลิสต์ทั้งหมดและรวมไฟล์ใด ๆ ที่อาจสิ้นสุดในภูมิภาคนั้นในเพลย์ลิสต์

ดังนั้นผลลัพธ์สุดท้ายของทั้งหมดนี้คือ: การทำงานของบรรทัดคำสั่ง ไม่มีไฟล์ชั่วคราวในขณะที่ทำการแก้ไข - และยังไม่มีไฟล์ชั่วคราว (หรือการแปลงรหัส) เมื่อแสดงผลสุดท้าย ... ซึ่งฉันคิดว่าตัวเองน่าจะดี

ดังนั้นในขณะที่ฉันคิดว่าทุกอย่างที่กล่าวมาอาจจะยืดออกไปบ้าง - มีอะไรบ้างไหมที่จะประมาณขั้นตอนการทำงานที่อธิบายไว้ข้างต้น?


1
ฉันมักจะใช้ mkvmerge เมื่อฉันต้องการแยก / เข้าร่วมวิดีโอ
วิ

ขอบคุณสำหรับสิ่งนั้น @Vi - ไม่เคยได้ยินมาmkvmergeก่อนจะทำให้แน่ใจว่าฉันตรวจสอบ .. ไชโย!
sdaau

คำตอบ:



23

ตกลงตั้งแต่ฉันไม่สามารถหามากเกี่ยวกับmeltการใช้บรรทัดคำสั่งต่อไปนี้เป็นบันทึกบาง .. (และหลังจากนี้ให้ดูคำตอบนี้ใช้ทดแทนกระบวนการโปรแกรมเคล็ดลับคาดหวังว่าไฟล์ที่มีนามสกุลที่เฉพาะเจาะจงเป็นอาร์กิวเมนต์? - Unix และ Linux Stack แลกเปลี่ยนสำหรับสคริปต์ ตัวอย่างผ่านbash)

เริ่มต้นด้วย - มีแพ็คเกจ Ubuntu / Debian สำหรับmelt(ฉันมี Ubuntu 11.04 กับ MLT ละลาย 0.6.2); ลิงก์ที่ได้รับจาก@Ieltonสำหรับ "Media Lovin 'Toolkit" (MLT) Wiki ซึ่งmeltเป็นส่วนหนึ่งของ (แต่ยังopenshotและkdenlive) นี่คือลิงค์ไปยังไฟล์ข้อความเอกสารจาก git ของพวกเขา: mltframework.org/mlt.git/tree - docs / ; ทราบวิกิพีเดียมีหน้าเกี่ยวกับBuildScripts

สำหรับตอนนี้ปัญหาที่ใหญ่ที่สุด (เฉพาะ) ที่ฉันมีคือฉันไม่สามารถหาวิธีส่งออกองค์ประกอบวิดีโอที่ไม่บีบอัดได้ (ไม่ว่าจะเป็นpngเฟรมหรือรูปแบบวิดีโอที่ไม่มีการบีบอัด)

 

ก่อนอื่นในบรรทัดคำสั่งmeltคุณสามารถควบคุมการเล่นผ่านเฟรมได้ ตัวอย่างเช่นหากต้องการ "สร้าง" ช่องว่างสีขาวยาว 15 เฟรมและดูด้วยmeltเครื่องเล่นในตัวให้ใช้

melt -blank 15

เมื่อคุณดูด้วยmeltคุณจะได้รับข้อมูลบรรทัดคำสั่งstderrสำหรับเครื่องเล่นในตัวด้วย:

$ melt -blank 15 
+-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
|1=-10| |2= -5| |3= -2| |4= -1| |5=  0| |6=  1| |7=  2| |8=  5| |9= 10|
+-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
+---------------------------------------------------------------------+
|               H = back 1 minute,  L = forward 1 minute              |
|                 h = previous frame,  l = next frame                 |
|           g = start of clip, j = next clip, k = previous clip       |
|                0 = restart, q = quit, space = play                  |
+---------------------------------------------------------------------+
Current Position:         15

เมื่อmeltเล่นเสร็จแล้วจะไม่ออก - ดังนั้นคุณควรพิมพ์qเพื่อออก

เราควรทราบมีที่เรียกว่า "ผู้ผลิต" และ "ผู้บริโภค" meltใน หากไม่มีการระบุอะไรเลยค่าเริ่มต้น "consumer" คือหน้าต่างSDL (Simple DirectMedia Layer) ที่เล่นวิดีโอ ดังนั้นคำสั่งดังกล่าวเป็นเช่นเดียวกับ:

melt -blank 15 -consumer sdl

ดังนั้นหากเราต้องการบันทึกสิ่งที่meltแสดงเราควรเปลี่ยนคอนซูเมอร์เป็นสิ่งที่รองรับรูปแบบไฟล์ วิธีรับรายชื่อผู้บริโภค:

$ melt -query "consumers"
---
consumers:
  - sdl
  - sdl_audio
  - sdl_preview
  - sdl_still
  - gtk2_preview
  - avformat
  - libdv
  - xml
  - decklink
  - null
...

libdvDV การส่งออกของผู้บริโภคจะจัดรูปแบบข้อมูลโดยตรงกับstdoutเพื่อที่จะบันทึกวิดีโอที่.dvไฟล์ที่คุณต้องการทำ:

melt -blank 15 -consumer libdv > test.dv

โปรดทราบว่าจากผู้บริโภคที่ระบุไว้รูปแบบเดียวที่ฉันได้ลองซึ่งสามารถเปิดได้ในแอปพลิเคชันอื่นคือlibdv(ฉันใช้vlcเป็นแอปพลิเคชันอื่น); อย่างไรก็ตามสิ่งนี้อาจล้มเหลวสำหรับการแปลงรหัสประเภทอื่น ( เช่นถ้าว่างเปล่าฉันพยายามแปลงตัวอย่างจาก.flvไฟล์ไฟล์. dv ที่เป็นผลลัพธ์จะเปิดและเล่นvlcแต่เสียหาย )

 

ตอนนี้สำหรับส่วนการแก้ไข โดยพื้นฐานแล้วคุณสามารถระบุชุดของชื่อไฟล์ / เข้า / ออกโดยตรงในบรรทัดคำสั่ง; บอกว่าคุณมีไฟล์video.aviแล้วคุณสามารถทำได้:

melt video.avi in=30 out=79 -blank 15 video.avi in=30 out=79

หรือรูปแบบที่ดีขึ้นเล็กน้อย:

melt \ 
video.avi in=30 out=79 \ 
-blank 15 \
video.avi in=30 out=79

นี่หมายความว่าvideo.aviจากเฟรม 30 ถึงเฟรม 79 จะถูกเล่น; จากนั้นว่าง 15 เฟรม; จากนั้นvideo.aviลำดับจากเฟรม 30 ถึงเฟรม 79 อีกครั้ง

วิธีใช้รูปภาพ (พูด.png) ในองค์ประกอบการตัดต่อวิดีโอ:

melt \
video.avi in=30 out=79 \
test.png in=0 out=15 \
video.avi in=30 out=79 \
-blank 15

โปรดทราบว่าสำหรับtest.png, in=พารามิเตอร์ไม่จำเป็นต้องเป็น 0 - แต่ภาพจะปรากฏสำหรับout- inเวลา ในกรณีนี้มันจะง่ายที่สุดที่จะเพียงแค่ปล่อยin=0พารามิเตอร์ทั้งหมด

 

สิ่งที่ดีคือลำดับการแก้ไขนี้สามารถบันทึก - หรือmeltเรียกมันว่าเป็นอนุกรม - เป็นไฟล์ โปรดทราบว่ามีสองวิธีในการทำให้เป็นอันดับดังกล่าว: "ง่าย" หรือ XML ตัวอย่างเช่นในการบันทึกคำสั่งดังกล่าวเป็นไฟล์ "ง่าย" ต่อเนื่องเราสามารถเพิ่ม-serialise [filename]สวิตช์ไปยังคำสั่ง:

$ melt video.avi in=30 out=79 -blank 15 video.avi in=30 out=79 -serialise file.melt 
Project saved as file.melt.

ตอนนี้file.meltประกอบด้วย:

video.avi
in=30
out=79
-blank
15
video.avi
in=30
out=79

ดูเหมือนว่ารูปแบบไฟล์ "ง่าย" ต่อเนื่องนี้ไม่มีตัวอักษร "คอมเม้นท์" - ถ้าฉันพยายามเพิ่ม# commentบรรทัด "" meltบ่นกับ: ' ล้มเหลวในการโหลด "# comment" ' (แต่นอกเหนือจากนั้นดูเหมือนว่า บรรทัดจะถูกละเว้นและเล่นต่อไปเรื่อย ๆ ) " .melt" ดูเหมือนว่าเป็นส่วนขยายที่meltรู้จักว่าเป็นไฟล์แบบอนุกรมที่เรียบง่าย

ตอนนี้เพื่อเล่นซ้ำไฟล์ที่ต่อเนื่องกันนี้เราสามารถเรียกมันได้โดยหลักการแล้วmelt file.meltอย่างไรก็ตามบรรทัดคำสั่งที่สมบูรณ์ยิ่งขึ้นจะเป็น:

melt melt_file:file.melt -consumer sdl

... ซึ่งจะหมายถึง: ใช้melt_file"โปรดิวเซอร์" เพื่อเปิดfile.meltและแสดงเฟรมของมันบน "consumer" sdl(หน้าต่าง)

โปรดทราบว่าฉันมีประสบการณ์ที่.flvวิดีโอ(พูด) เล่นโดยไม่มีปัญหาในบรรทัดคำสั่ง - อย่างไรก็ตามทำให้เกิดการแบ่งส่วนเมื่อพวกเขาระบุไว้ในfile.meltไฟล์อนุกรม! .dvวิดีโอที่ผลิตด้วยmeltตัวเองดูเหมือนจะทำงานได้ดีในfile.melt...

 

การทำให้เป็นอันดับ XML ประเภทสามารถทำได้โดยใช้-consumer xml:สวิตช์ ( แทน-serialise ) - ดังนั้นตัวอย่างข้างต้นจะเป็น:

melt video.avi in=30 out=79 -blank 15 video.avi in=30 out=79 -consumer xml:file.mlt

หากต้องการ "เล่น" file.mltไฟล์ XML ที่สร้างขึ้นใหม่ตอนนี้คุณสามารถทำได้โดยตรงmelt file.mltหรือบรรทัดคำสั่งที่สมบูรณ์ยิ่งขึ้นจะเป็น:

melt xml:file.mlt -consumer sdl

... ซึ่งจะหมายถึง: ใช้xml"โปรดิวเซอร์" ( หมายเหตุก่อนหน้านี้เป็นผู้บริโภค ) เพื่อเปิดfile.mltและแสดงเฟรมบน "ผู้บริโภค" sdl(หน้าต่าง)

โปรดทราบว่าในกรณีนี้ฉันพบว่า.flvวิดีโอเดียวกันกับที่ทำให้ segfault ด้วยไฟล์การทำให้เป็นอนุกรมอย่างง่าย - ทำงานได้ดีกับไฟล์การทำให้เป็นอนุกรม XML!

ในกรณีนี้file.mltไฟล์ XML ที่ได้มีการตั้งค่ามากขึ้นเช่นความละเอียด, อัตราเฟรม, ข้อมูลตัวแปลงสัญญาณ ฯลฯ - แต่มันก็ทำงานได้ยากขึ้นใน text editor โดยตรง:

<?xml version="1.0" encoding="utf-8"?>
<mlt root="/path/to" title="video.avi">
  <profile description="automatic" width="320" height="240" progressive="1" sample_aspect_num="1" sample_aspect_den="1" display_aspect_num="320" display_aspect_den="240" frame_rate_num="25" frame_rate_den="1" colorspace="601"/>
  <producer id="producer0" in="30" out="79">
    <property name="mlt_type">producer</property>
    <property name="aspect_ratio">1.000000</property>
    <property name="length">125</property>
    <property name="eof">pause</property>
    <property name="resource">video.avi</property>
    <property name="meta.media.nb_streams">2</property>
    <property name="meta.media.0.stream.type">video</property>
    <property name="meta.media.0.stream.frame_rate">25.000000</property>
    <property name="meta.media.0.stream.sample_aspect_ratio">0.000000</property>
    <property name="meta.media.0.codec.frame_rate">25.000000</property>
    <property name="meta.media.0.codec.pix_fmt">yuv420p</property>
    <property name="meta.media.0.codec.sample_aspect_ratio">1.000000</property>
    <property name="meta.media.0.codec.colorspace">601</property>
    <property name="meta.media.0.codec.name">mpeg4</property>
    <property name="meta.media.0.codec.long_name">MPEG-4 part 2</property>
    <property name="meta.media.0.codec.bit_rate">0</property>
    <property name="meta.media.1.stream.type">audio</property>
    <property name="meta.media.1.codec.sample_fmt">s16</property>
    <property name="meta.media.1.codec.sample_rate">22050</property>
    <property name="meta.media.1.codec.channels">1</property>
    <property name="meta.media.1.codec.name">mp2</property>
    <property name="meta.media.1.codec.long_name">MP2 (MPEG audio layer 2)</property>
    <property name="meta.media.1.codec.bit_rate">64000</property>
    <property name="seekable">1</property>
    <property name="meta.media.sample_aspect_num">1</property>
    <property name="meta.media.sample_aspect_den">1</property>
    <property name="meta.attr.title.markup"></property>
    <property name="meta.attr.author.markup"></property>
    <property name="meta.attr.copyright.markup"></property>
    <property name="meta.attr.comment.markup"></property>
    <property name="meta.attr.album.markup"></property>
    <property name="audio_index">1</property>
    <property name="video_index">0</property>
    <property name="mlt_service">avformat</property>
  </producer>
  <producer id="producer1" in="30" out="79">
    <property name="mlt_type">producer</property>
    <property name="aspect_ratio">1.000000</property>
    <property name="length">125</property>
    <property name="eof">pause</property>
    <property name="resource">video.avi</property>
    <property name="meta.media.nb_streams">2</property>
    <property name="meta.media.0.stream.type">video</property>
    <property name="meta.media.0.stream.frame_rate">25.000000</property>
    <property name="meta.media.0.stream.sample_aspect_ratio">0.000000</property>
    <property name="meta.media.0.codec.frame_rate">25.000000</property>
    <property name="meta.media.0.codec.pix_fmt">yuv420p</property>
    <property name="meta.media.0.codec.sample_aspect_ratio">1.000000</property>
    <property name="meta.media.0.codec.colorspace">601</property>
    <property name="meta.media.0.codec.name">mpeg4</property>
    <property name="meta.media.0.codec.long_name">MPEG-4 part 2</property>
    <property name="meta.media.0.codec.bit_rate">0</property>
    <property name="meta.media.1.stream.type">audio</property>
    <property name="meta.media.1.codec.sample_fmt">s16</property>
    <property name="meta.media.1.codec.sample_rate">22050</property>
    <property name="meta.media.1.codec.channels">1</property>
    <property name="meta.media.1.codec.name">mp2</property>
    <property name="meta.media.1.codec.long_name">MP2 (MPEG audio layer 2)</property>
    <property name="meta.media.1.codec.bit_rate">64000</property>
    <property name="seekable">1</property>
    <property name="meta.media.sample_aspect_num">1</property>
    <property name="meta.media.sample_aspect_den">1</property>
    <property name="meta.attr.title.markup"></property>
    <property name="meta.attr.author.markup"></property>
    <property name="meta.attr.copyright.markup"></property>
    <property name="meta.attr.comment.markup"></property>
    <property name="meta.attr.album.markup"></property>
    <property name="audio_index">1</property>
    <property name="video_index">0</property>
    <property name="mlt_service">avformat</property>
  </producer>
  <playlist id="playlist0">
    <entry producer="producer0" in="0" out="49"/>
    <blank length="16"/>
    <entry producer="producer1" in="0" out="49"/>
  </playlist>
  <tractor id="tractor0" title="video.avi" global_feed="1" in="0" out="115">
    <track producer="playlist0"/>
  </tractor>
</mlt>

และนี่คือตัวอย่างสำหรับการตัดที่แม่นยำของเฟรม: ตัดไฟล์วิดีโอจากบรรทัดคำสั่งอย่างแม่นยำ - Super User
sdaau

7

โซลูชัน ffmpeg สำหรับปัญหานี้มีลักษณะดังนี้:

mkfifo temp1 temp2 temp3
ffmpeg -i input.wmv -ss 30 -to 60 -c copy output.wmv temp1 2> /dev/null & \
ffmpeg -i input2.wmv -t 60 -c copy temp2 2> /dev/null & \
ffmpeg -i input3.wmv -i image.png -filter_complex "[0:v][1:v] \
overlay=25:25:enable='between(t,0,20)'" -pix_fmt yuv420p -c:a copy temp3 2> /dev/null & \
ffmpeg -f mpegts -i "concat:temp1|temp2|temp3" -c copy output.mp4

มันใช้ชื่อ pipes ดังนั้นจึงไม่มีการสร้างไฟล์ temp บนดิสก์และช่วยให้คุณตัดส่วนของคลิปวิดีโอและเพิ่มภาพได้

ตัวอย่างนี้ใช้เวลา 30-60 ของอินพุตแรกจากนั้นเพิ่มนาทีแรกของอินพุตที่สองจากนั้นแทรกไฟล์รูปภาพจากนั้นวิดีโอที่สามทั้งหมด

รหัสยกจาก:

หน้าเชื่อมต่อ ffmpeg: https://trac.ffmpeg.org/wiki/Concatenate

หน้า superuser ใช้ ffmpeg เพื่อตัดวิดีโอ

หน้า superuser https://video.stackexchange.com/questions/12105/add-an-image-in-front-of-video-using-ffmpeg


ขอบคุณสำหรับสิ่งนั้นฉันเพิ่งเรียนรู้เกี่ยวกับffmpeg-concatซึ่งเขียนใน JavaScript (และคุณต้องnpmติดตั้ง) ดังนั้นฉันคิดว่าฉันจะพูดถึงมัน
sdaau

4

ฉันก็กำลังมองหาเครื่องมือเช่นนี้และมันก็ดูเหมือนว่าละลายเป็นเครื่องมือสำหรับงาน แต่เอกสารเกือบจะเป็นไปไม่ได้ที่จะเข้าใจ / หายไป คุณสามารถทำการแก้ไขได้หลายแบบรวมกัน ฉันมีคลิปวิดีโอ 'action cam' ... เสียงนั้นไม่สามารถใช้งานได้ ฉันเข้าร่วมวิดีโอ (h264) ด้วยกันเพิ่มเฟรม 60 จางและแทนที่เสียงด้วยแทร็กเสียงโดยใช้:

% melt -video-track vid1.avi vid2.avi -mix 60 -mixer luma vid3.avi \
   -mix 60 -mixer luma -audio-track vorbis:track1.ogg vorbis:track2.ogg \
   -consumer avformat:OUT.avi acodec=libmp3lame vcodec=libx264

คุณสามารถอ่านเพิ่มเติมได้ที่นี่ เว็บไซต์หลักคือที่นี่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.