วิธีการสร้างวิดีโอจากภาพโดยใช้ FFmpeg


86

เป็นไปได้หรือไม่ที่จะใช้ffmpegสร้างวิดีโอจากชุดของลำดับซึ่งจำนวนไม่เริ่มจากศูนย์

ตัวอย่างเช่นฉันมีรูปภาพ [test_100.jpg, test_101.jpg, test_102.jpg, ... , test_200.jpg] และฉันต้องการแปลงเป็นวิดีโอ ฉันลองใช้คำสั่งต่อไปนี้ แต่มันไม่ทำงาน (ดูเหมือนว่าหมายเลขควรเริ่มจากศูนย์):

ffmpeg -i test_% d.jpg -vcodec mpeg4 test.avi

มีคำแนะนำอะไรบ้าง?


ไม่นานมานี้เมื่อคุณถามคำถามนี้ แต่ถ้าคุณยังสนใจคำถามคำตอบคือใช่ - ฉันได้โพสต์รายละเอียดและตัวอย่างด้านล่าง: stackoverflow.com/a/12160155/181638
Assad Ebrahim

@casperOne จะมีประโยชน์ที่จะมีความคิดว่าทำไมถึงเป็นหัวข้อ ดูเหมือนว่าปัญหาการเขียนโปรแกรมเฉพาะ แท็ก FFmpeg มีผู้ติดตาม 3.7k และมีผู้ดู 27k เห็นได้ชัดว่าผู้คนพบว่ามีประโยชน์ ..
geotheory

2
@geotheory สถิติแท็กไม่เกี่ยวข้อง ffmpeg เป็นโปรแกรมมากในทางพูด WinRar แม้ว่าคุณจะสามารถเขียนโปรแกรมกับไลบรารีในffmpeg ได้แต่คำถามนี้ไม่เกี่ยวกับเรื่องนั้น การใช้ ffmpeg จากบรรทัดคำสั่งจะถูกถามในSuper Userซึ่งเป็นหัวข้อ
casperOne

คำตอบ:


81

ไม่จำเป็นต้องเปลี่ยนชื่อไฟล์หากใช้-start_numberสวิตช์ดังนี้:

ffmpeg -start_number n -i test_%d.jpg -vcodec mpeg4 test.avi

ซึ่งnเป็นจุดเริ่มต้นของลำดับของภาพนิ่ง

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

มีสวิตช์อื่นที่คุณอาจพบว่ามีประโยชน์

ฉันใช้หนึ่งซับต่อไปนี้เพื่อให้ได้อัตราเฟรมที่ช้ากว่าและบีบอัดรูปภาพและมีวิดีโอขนาดเล็กลง:

ffmpeg.exe -f image2 -framerate 25 -pattern_type sequence -start_number 1234 -r 3 -i Imgp%04d.jpg -s 720x480 test.avi

-r 3ตัวเลือกชุดเฟรมของวิดีโอที่เกิดขึ้นถึง 3 เฟรมต่อวินาทีเพื่อที่ฉันสามารถเห็นกันยังคงเป็นช่วงเวลาสั้น ๆ -sตัวเลือก rescales ภาพเพื่อความละเอียดที่ต้องการที่จะจัดการกับขนาดของวิดีโอที่เกิด

(ในเชลล์ Windows ให้แทนที่-i Imgp%04d.jpgด้วย-i "Imgp%%04d.jpg". เครดิตสำหรับสิ่งนี้เป็น Mike Fitzpatrick https://superuser.com/a/344178/153054 )


4
ความแตกต่างระหว่าง -r และ -framerate คืออะไร

1
พวกเขาเป็น IIRC เดียวกัน
rogerdpack

22
ไม่จำเป็นต้องคิดเลขไร้สาระตราบใดที่คุณมีความสุขที่จะยอมรับคำสั่งที่ปรากฏใน (พูด) 'ls' ... เพียงใช้: ffmpeg -pattern_type glob -i '* .jpg' movie.mp4
Orwellophile

2
มีสวิตช์ใดบ้างในการควบคุมช่วงเวลาระหว่างภาพพูดว่าฉันต้องการแสดงภาพแรก 13s, 15 วินาทีที่สอง, 24 วินาทีสำหรับช่องว่างเวลาที่สามที่ผู้ใช้กำหนดเป็นไปได้หรือไม่?
zionpi

2
ดูเพิ่มเติมที่trac.ffmpeg.org/wiki/…
david.libremone

38

คุณสามารถใช้ข้อมูลโค้ดด้านล่างนี้:

 cat *.jpg | ffmpeg -f image2pipe -r 1 -vcodec mjpeg -i - -vcodec libx264 out.mp4

สิ่งนี้ไม่หมุน JPGs เป็นการหมุนที่ระบุในข้อมูลเมตา
Erik Johansson

17

คุณสามารถค้นหาสคริปต์ตัวอย่างได้ในเอกสาร ffmpeg :

3.2 ฉันจะเข้ารหัสภาพเดี่ยวเป็นภาพยนตร์ได้อย่างไร

หากคุณมีรูปภาพจำนวนมากที่จะเปลี่ยนชื่อคุณสามารถใช้คำสั่งต่อไปนี้เพื่อลดภาระ คำสั่งโดยใช้ไวยากรณ์เปลือก bourne เชื่อมโยงไฟล์ทั้งหมดในไดเรกทอรีปัจจุบันที่ตรงกับ * jpg กับ/tmp' directory in the sequence ofimg001.jpg ', `img002.jpg' และอื่น ๆ

x=1; for i in *jpg; do counter=$(printf %03d $x); ln "$i" /tmp/img"$counter".jpg; x=$(($x+1)); done

จากนั้นเรียกใช้:

ffmpeg -f image2 -i /tmp/img%03d.jpg /tmp/a.mpg

2
คุณน่าจะทำให้ x = 0 เริ่มต้นได้ดีขึ้นเพื่อเริ่มต้นชื่อภาพ img000.jpg เนื่องจากนี่คือสิ่งที่ ffmpeg คาดหวัง การเชื่อมโยงด้วยกันไม่ได้ผลสำหรับฉันเนื่องจาก ffmpeg ไม่สามารถค้นหาไฟล์ได้ดังนั้นฉันจึงต้องใช้ cp แทน (ความเร็วที่เห็นได้ชัดและพื้นที่วาดกลับหลัง แต่ฉันก็ลองใหม่ดู) mv ก็ใช้ได้เช่นกันถ้าคุณไม่รังเกียจที่จะสูญเสียต้นฉบับ

โปรดทราบว่าในคำตอบนี้คำสั่งที่ให้ไว้จะสร้างฮาร์ดลิงก์ไม่ใช่ symlinks เกี่ยวกับการใช้งานcpถ้าการเชื่อมโยงไม่ทำงานหากระบบไฟล์ของคุณรองรับมันcp --reflink=autoจะทำให้การใช้งานความเร็ว / พื้นที่ดีขึ้นมาก
Félix Saparelli

12

จากเอกสารของ ffmpeg:

ใช้รูปแบบ glob

ffmpeg ยังรองรับ globbing แบบทุบตี (* แสดงถึงจำนวนของอักขระใด ๆ )

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

ffmpeg -r 1 -pattern_type glob -i 'test_*.jpg' -c:v libx264 out.mp4

ดังนั้นตราบใดที่ไฟล์ของคุณถูกเรียงลำดับการใช้-pattern_type globสวิตช์ควรทำงานให้คุณ


โปรดทราบว่า glob นี้มีข้อ จำกัด มากกว่าเปลือกปกติ globs: trac.ffmpeg.org/ticket/3620อย่างเห็นได้ชัดเพราะประเภทของภาพจะถูกอนุมานจากส่วนขยาย
Ciro Santilli 新疆改造中心法轮功六四事件

11

เท่าที่ฉันรู้คุณไม่สามารถเริ่มต้นลำดับในตัวเลขสุ่ม (ฉันจำไม่ได้ว่าคุณควรเริ่มต้นที่ 0 หรือ 1) บวกมันไม่สามารถมีช่องว่างถ้ามัน ffmpeg จะถือว่าลำดับอยู่เหนือและ หยุดเพิ่มภาพมากขึ้น

นอกจากนี้ตามที่ระบุไว้ในความคิดเห็นต่อคำตอบของฉันโปรดจำไว้ว่าคุณต้องระบุความกว้างของดัชนีของคุณ ชอบ:

ภาพ 03d.jpg%

และถ้าคุณใช้ชนิดดัชนี% 03d คุณจะต้องใส่ชื่อไฟล์ด้วย 0 เช่น:

image001.jpg image002.jpg image003.jpg

เป็นต้น


1
หากชื่อไฟล์ภาพมีศูนย์นำหน้าสตริงรูปแบบจะต้องระบุความกว้างเช่น "% 03d"

1
หากนั่นเป็นอุปสรรคเดียวคุณสามารถเขียนสคริปต์เพื่อเปลี่ยนชื่อหรือเชื่อมโยงภาพของคุณไปยังชุดการทำดัชนีใหม่อย่างเหมาะสม
Cascabel

1
ใช่ฉันเคยทำงานกับเรื่องนี้มาก่อนฉันเขียน wrapper ใน Ruby เมื่อไม่นานมานี้โดยที่คุณเรียกว่า instance.addImage () จากนั้น instance.processVideo () และมันจะสร้างไดเรกทอรีชั่วคราวคัดลอก / เปลี่ยนชื่อภาพด้วยดัชนีที่เหมาะสม และสร้างวิดีโอ มันค่อนข้างง่าย

@Jefromi ฉันได้สร้าง symlink แต่ฉันจะให้เส้นทางของไฟล์ symlink ไปยัง ffmpeg ได้อย่างไร มันแค่คิดว่าไฟล์ symlink เป็นภาพที่ฉันพยายามจะแปลง? ฉันใช้งาน win7 btw

ลำดับสามารถเริ่มที่ใดก็ได้จาก 0 ถึง 4 รวม
อัสซาด Ebrahim

5

ฉันเห็นด้วยกับ Francisco แต่เป็นวิธีแก้ปัญหาคุณสามารถเขียนสคริปต์ด่วนเพื่อย้ายหรือสร้างลิงก์สัญลักษณ์ไปยังไฟล์ด้วยหมายเลขลำดับที่ ffmpeg ต้องการ สคริปต์สามารถเรียก ffmpeg แล้วลบลิงก์หรือย้ายไฟล์กลับไปที่ตำแหน่งเดิม


1

เงยหน้าขึ้นมอง

x=1; for i in *jpg; do counter=$(printf %03d $x); ln "$i"
/tmp/img"$counter".jpg; x=$(($x+1)); done

1

ฉันรู้ว่านี่เป็นคำถามเก่า แต่ฉันเจอใน Google ในขณะที่มองหาคำตอบเดียวกัน ไม่มีคำตอบที่นี่ทำให้ฉันพึงพอใจอย่างสมบูรณ์ดังนั้นฉันจึงทำการค้นหาและอ่านมากขึ้นและนี่คือคำสั่งที่ฉันคิดขึ้นสำหรับปัญหาของตัวเอง

cat {0032..1501}*.png | ffmpeg -f image2pipe -framerate 5 -i - -s 720x480 test2.avi

เหตุผลที่ฉันใช้คำสั่งเช่นนี้คือ ...

  1. Cat และ -f image2pipe ให้คุณควบคุมภาพได้ดียิ่งขึ้น ตัวอย่างเช่นช่วยให้คุณใช้คุณสมบัติทุบตีเช่นการขยายตัวของวงเล็บปีกกาและคำสั่งอื่น ๆ เช่น grep เพื่อปรับแต่งผลลัพธ์ของคุณอย่างที่คุณเลือก
  2. จำได้น้อยลง
  3. ฉันไม่แนะนำให้ใช้ -r และใช้ -framerate แทน จากประสบการณ์ของฉัน - มีแนวโน้มที่จะดร็อปเฟรมบ่อยขึ้น
  4. ซับซ้อนน้อยลงไม่มีสวิตช์ที่ไม่จำเป็นในการใช้งานและจะทำงานตามที่เป็นอยู่ คุณอาจเพิ่มความซับซ้อนมากขึ้น (ตัวอย่างเช่นการระบุตัวเข้ารหัส) และปรับแต่งให้เหมาะกับความต้องการของคุณ

สำหรับคำถามของ OP -start_numberคือทั้งหมดที่จำเป็น
Gyan

0

ฉันใช้ตัวเข้ารหัส flv เนื่องจากวิดีโอของฉันเล่นเป็น Flash Player (Jwplayer)

ffmpeg -i% d.jpg -vcodec flv test.flv


0

จากเอกสารดูเหมือนว่าคุณสามารถใช้ *

For example, for creating a video from filenames matching the glob pattern foo-*.jpeg:

ffmpeg -f image2 -pattern_type glob -framerate 12 -i 'foo-*.jpeg' -s WxH foo.avi

เพื่อทราบว่าการปรับปรุงมีผลต่อคุณภาพอัตรา / เฟรมต่อวินาทีอาจมีความสำคัญ (เช่นก่อนระบุอัตราเฟรมที่ต่ำมาก / สูงจากนั้นผ่านจากตัวกรองที่สองที่จะทำให้วิดีโอภาพเคลื่อนไหวช้าเป็นปกติหรือไม่)


0

ในกรณีของฉันมันมีเล่ห์เหลี่ยมเล็กน้อยเนื่องจากตัวเลขในไฟล์ นี่คือรูปของฉันที่มีลักษณะ:

$ ls | head -5
2014_aq_unprocessed 001.jpg
2014_aq_unprocessed 002.jpg
2014_aq_unprocessed 003.jpg
2014_aq_unprocessed 004.jpg
2014_aq_unprocessed 005.jpg

และนี่คือคำสั่งที่ฉันใช้:

ffmpeg -i 2014_aq_unprocessed\ %3d.jpg  -vcodec mpeg4 test.avi

0

คุณสามารถทำได้ด้วยconvert -morph:

convert *.jpg -delay 10 -morph 10 %05d.jpg

ถ้าคุณต้องการใช้ffmpegฉันใช้

ffmpeg -pattern_type glob -i '*.jpg' -vf "setpts=10*PTS" movie.mp4

โดยที่10*PTSffmpeg บอกให้ช้าลง 10 ครั้ง คุณสามารถมีเศษส่วนเพื่อเร่งความเร็วได้


นี่เป็นเพียงการแก้ไขลำดับภาพต้นฉบับของคุณไปยังพื้นที่ใหม่มันไม่ได้สร้างไฟล์วิดีโอเหมือนที่ OP ถาม
f0ster

0

-pattern_type glob ตัวอย่างที่เป็นรูปธรรมพร้อมเสียง

ตัวเลือกนี้ถูกกล่าวถึงที่: https://superuser.com/a/782520/128124แต่นี่เป็นตัวอย่างที่ชัดเจนของการใช้งานรวมถึงการเพิ่มเสียงลงในวิดีโอออก

วิดีโอสไลด์โชว์ที่มีหนึ่งภาพต่อวินาที

ffmpeg -framerate 1 -pattern_type glob -i '*.png' \
  -c:v libx264 -r 30 -pix_fmt yuv420p out.mp4

เพิ่มเพลงลงไปตัดเสียงเมื่อภาพจบ:

ffmpeg -framerate 1 -pattern_type glob -i '*.png' -i audio.ogg \
  -c:a copy -shortest -c:v libx264 -r 30 -pix_fmt yuv420p out.mp4

นี่คือตัวอย่างสองตัวอย่างบน YouTube:

เป็นพวกฮิปปี้และใช้รูปแบบวิดีโอที่ไม่มีสิทธิบัตรของ Theora :

ffmpeg -framerate 1 -pattern_type glob -i '*.png' -i audio.ogg \
  -c:a copy -shortest -c:v libtheora -r 30 -pix_fmt yuv420p out.ogg

แน่นอนว่ารูปภาพของคุณควรถูกจัดเรียงตามตัวอักษรโดยทั่วไปเป็น:

0001-first-thing.jpg
0002-second-thing.jpg
0003-and-third.jpg

และอื่น ๆ

ดูเพิ่มเติมที่: http://unix.stackexchange.com/questions/68770/converting-png-frames-to-video-at-1-fps/339399#339399

วิดีโอความเร็วปกติที่มีหนึ่งภาพต่อเฟรมที่ 30 FPS

ffmpeg -framerate 30 -pattern_type glob -i '*.png' \
  -c:v libx264 -pix_fmt yuv420p out.mp4

นี่คือสิ่งที่ดูเหมือนว่า:

สร้างจาก GIF ด้วย: https://askubuntu.com/questions/648603/how-to-create-an-animated-gif-from-mp4-video-via-command-line/837574#837574

เพิ่มเสียง:

ffmpeg -framerate 30 -pattern_type glob -i '*.png' \
  -i audio.ogg -c:a copy -shortest -c:v libx264 -pix_fmt yuv420p out.mp4

ผลลัพธ์: https://www.youtube.com/watch?v=HG7c7lldhM4

แปลงไฟล์เพลงหนึ่งไฟล์เป็นวิดีโอที่มีภาพคงที่สำหรับการอัพโหลด YouTube

ตอบเมื่อ: วิธีแปลง MP3 เป็นรูปแบบวิดีโอที่อนุญาต Youtube?

ขอรับอิมเมจการทดสอบสังเคราะห์บางอย่าง

นี่คือภาพทดสอบที่ฉันใช้ในคำตอบนี้:

wget -O opengl-rotating-triangle.zip https://github.com/cirosantilli/media/blob/master/opengl-rotating-triangle.zip?raw=true
unzip opengl-rotating-triangle.zip
cd opengl-rotating-triangle
wget -O audio.ogg https://upload.wikimedia.org/wikipedia/commons/7/74/Alnitaque_%26_Moon_Shot_-_EURO_%28Extended_Mix%29.ogg

รูปภาพที่สร้างด้วย: https://stackoverflow.com/questions/3191978/how-to-use-glut-opengl-to-render-to-a-file/14324292#14324292

มันยอดเยี่ยมที่จะสังเกตว่าวิดีโอบีบอัดลำดับภาพเท่าไหร่ดีกว่า ZIP เนื่องจากสามารถบีบอัดข้ามเฟรมด้วยอัลกอริธึมพิเศษ:

  • opengl-rotating-triangle.mp4: 340K
  • opengl-rotating-triangle.zip: 7.3 ล้าน

เกี่ยวกับตัวเลือก CLI

อย่างไรก็ตามโปรดทราบว่าแม้จะมีชื่อ-globสิ่งนี้ไม่เป็นทั่วไปเช่นเดียวกับเชลล์ Glob patters เช่น: -i '*'ล้มเหลว: https://trac.ffmpeg.org/ticket/3620 (เห็นได้ชัดว่าเป็นเพราะไฟล์เป็นชนิดที่อนุมานได้จากการขยาย)

-r 30ทำให้-framerate 1วิดีโอ 30 FPS เอาชนะข้อบกพร่องในผู้เล่นเช่น VLC สำหรับผู้ที่มีเฟรมต่ำ: https://stackoverflow.com/questions/19267443/playback-issues-in-vlc-with-low-fps-video-from-images-use ffmpeg / 41797724 # 41797724ดังนั้นจึงทำการทำซ้ำแต่ละเฟรม 30 ครั้งเพื่อให้ได้ภาพที่ต้องการ 1 ภาพต่อวินาที

ขั้นตอนถัดไป

คุณจะต้อง:

สิ่งที่ต้องทำ: เรียนรู้ที่จะตัดและต่อเชื่อมไฟล์เสียงหลายไฟล์ลงในวิดีโอจากบรรทัดคำสั่ง:

ทดสอบแล้ว

ffmpeg 3.4.4, vlc 3.0.3, Ubuntu 18.04

บรรณานุกรม

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