รวมหนึ่งภาพ + ไฟล์เสียงหนึ่งรายการเพื่อสร้างวิดีโอหนึ่งรายการโดยใช้ FFmpeg


180

นี่ควรจะเป็นเรื่องเล็กน้อย แต่ฉันไม่สามารถหาวิธีที่จะให้มันทำงานได้

ฉันต้องการ FFmpeg ถ่ายภาพ JPEG หนึ่งไฟล์และไฟล์เสียงเป็นอินพุตและสร้างไฟล์วิดีโอที่มีระยะเวลาเท่ากับไฟล์เสียง (โดยยืดภาพนิ่งตลอดระยะเวลาทั้งหมด)

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

บรรทัดคำสั่งที่ถูกต้องคืออะไรที่จะทำเช่นนั้น?

ฉันเหนื่อย:

ffmpeg -i image8.jpg -i sound11.amr -acodec copy test.avi

และพยายามมากของชุดที่มีและไม่มี-s 640x360, -loop_input, -shortest, -t xxx, -r 0.1(อัตราเฟรมที่ต่ำเกินจริงในความหวังว่าวิดีโอจะเป็นอีกต่อไป) และ-f image2

ฉันอาจได้รับข้อผิดพลาดหรือฉันได้รับไฟล์วิดีโอในระยะเวลาหนึ่งเฟรม

ฉันไปเที่ยวรอบ ๆ และพบโซลูชันที่เสนอมาหลายสิบข้อ (ซึ่งเป็นคำถามเดียวกันนี้) ไม่มีวิธีใดที่ใช้งานได้

ใครช่วยแนะนำคำสั่งการทำงานและอธิบายเหตุผลเบื้องหลังได้ไหม?


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

ภายใน "ตามที่คาดหมาย" คุณหมายถึงวิดีโอที่ได้นั้นมีระยะเวลาเท่ากับอินพุตเสียงหรือไม่ คุณเล่นหรือยัง ไม่ใช่หนึ่งเฟรมยาวหรือไม่
matteo

รูปแบบเสียงไม่ใช่ปัญหาการแปลงรหัสเสียงใช้งานได้
matteo

ฉันมีปัญหาเรื่อง params ออกมาด้วยและมันก็มีค่าใช้จ่ายฉันชั่วโมง! น่าเสียดายที่ปัญหาเหล่านี้ไม่ได้ครอบคลุมในความช่วยเหลือ gregoire.org/2009/12/05/fun-with-ffmpeg
Paul Gregoire

2
นี้จะดีกว่าคำตอบที่ได้รับการแต่งตั้งผมทดลองและก็รวดเร็วและมีขนาดไฟล์ที่มีขนาดเล็ก ..ffmpeg -y -i image.png -i audio.mp3 -c:a copy result.avi
มูฮัมหมัด Umer

คำตอบ:


143

ลำดับของตัวเลือกในบรรทัดคำสั่งมีความสำคัญ งานต่อไปนี้สำหรับกรณีของฉัน:

ffmpeg -loop 1 -y -i image8.jpg -i sound11.amr -shortest -acodec copy -vcodec mjpeg result.avi

ในกรณีทั่วไปมากขึ้นโดยที่image.jpgและaudio.wavเป็นอินพุตของคุณคุณสามารถใช้คำสั่งต่อไปนี้ซึ่งดัดแปลงจากFFmpeg wiki :

ffmpeg -loop 1 -i image.jpg -i audio.wav -c:v libx264 -tune stillimage -c:a aac -b:a 192k -pix_fmt yuv420p -shortest out.mp4

นี่จะใช้โปรแกรมเปลี่ยนlibx264ไฟล์และให้การบีบอัดที่ดีกว่าตัวแปลงสัญญาณ MJPEG ที่ใช้ด้านบน เสียงคือ AAC พร้อมตัวffmpegเข้ารหัส AAC ในตัว


5
ทำไมไฟล์ถึงท้ายขนาดใหญ่กว่า [ขนาดของภาพ] + [ขนาดของไฟล์เสียง] ฉันคาดว่าการบีบอัดวิดีโอจะเป็นบ้ากับเฟรมคงที่หรือไม่
Alec Jacobson

2
ขึ้นอยู่กับตัวแปลงสัญญาณวิดีโอที่คุณใช้ หากคุณกำลังคัดลอกคำสั่งในตัวอย่างของฉันฉันกำลังใช้ mjpeg เป็นตัวแปลงสัญญาณซึ่งบีบอัดแต่ละเฟรมแยกจากกันดังนั้นจึงไม่มีประโยชน์จากความจริงที่ว่าทุกเฟรมเท่ากัน นอกจากนี้ฉันคิดว่าแม้แต่ตัวแปลงสัญญาณอื่น ๆ ก็จะทำการถอดรหัสเฟรมใหม่ทุก ๆ ครั้งเช่นกรอบ N-th ดังนั้นคุณจะได้ไฟล์ที่เล็กกว่า แต่ยังใหญ่กว่าขนาดของภาพและเสียง พวกเขาทำเช่นนั้นเพราะ (a) มิฉะนั้นตัวถอดรหัสจะต้องอ่านไฟล์ทั้งหมดตั้งแต่ต้นถึงแม้ว่าคุณเพียงแค่ต้องการข้ามไปยังเฟรมสุดท้ายและ
matteo

2
Option shortest (finish encoding within shortest input) cannot be applied to input file image.jpg -- you are trying to apply an input option to an output file or vice versa. Move this option before the file it belongs to.
Wim

2
ใช้ffmpeg -y -i image.png -i audio.mp3 -c:a copy result.aviงานได้ดีกว่านี้ !!!?!?!?!
มูฮัมหมัดอูเมอร์

2
คำตอบนี้กำลังถูกกล่าวถึงในเมตาดาต้า
DavidPostill

41

คุณกำลังทำให้มันเป็นวิธีที่ยากกว่าก็จะต้องมี FFmpeg นั้นฉลาดกว่าที่คุณให้เครดิตเพราะรู้ว่าคุณต้องการให้วิดีโอมีความยาวเท่ากับแทร็กเสียงของคุณ

ffmpeg -i still.png -i narrate.wav -acodec libvo_aacenc -vcodec libx264 final.flv

pause

เพียงแอตทริบิวต์ของคุณมีการระบุเป็นinput filenamesที่output codecsและoutput filename(ซึ่งeo IPSOรวมถึงoutput container)

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

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

pauseคำสั่งในตอนท้ายของแฟ้มชุดช่วยเปิด CLI - The วิธีที่ดีที่สุดในการแก้ปัญหาบรรทัดคำสั่งของคุณจะโดยการอ่านข้อความผิดพลาดมันสร้าง พวกเขามีความเฉพาะเจาะจงอย่างยิ่ง - และเอกสารที่ดีที่สุดที่ FFmpeg มี - แต่การทำงานอย่างหนักของนักพัฒนาจะสูญเปล่าหากคุณอนุญาตให้หน้าต่างปิดก่อนที่คุณจะอ่าน

เชลล์คำสั่งมีสวิตช์cmd /kที่ดูแลหน้าต่างแบบเปิดซึ่งคุณสามารถเรียกใช้คำสั่งเดียวกันจากสคริปต์ชุดงานของคุณได้ที่หน้าจอพร้อมรับคำสั่ง

FFmpegและavconvทั้งสองจะทำให้คุณใช้-c:aสำหรับ-acodecและ-c:vสำหรับ-vcodecในที่สุด แต่คำแนะนำเก่าทำงานได้ดีในการสร้างผมใช้

Nota Bene: การกระทำทุกอย่างนั้นมีนิสัยแปลก ๆ หากบรรทัดคำสั่งของคุณล้มเหลวโดยไม่มีเหตุผลที่ชัดเจนก็มักจะเป็นประโยชน์ในการลองสร้างใหม่ - หรือทำตามทางแยกไปสู่libavซึ่งนักพัฒนาที่ใช้งานมากที่สุดของ FFmpeg มาสองสามปีที่ผ่านมา เครื่องมือแปลงรหัสของพวกเขาได้ถูกเปลี่ยนชื่อเป็นavconvแต่ไฟล์แบทช์ของคุณควรทำงานกับอันใดอันหนึ่ง


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

2
สวัสดี Matteoใช่ฉันใช้รหัสนั้นแล้วและใช่มันทำงานได้ตามที่โฆษณาไว้ ฉันแน่ใจว่ามีจำนวนมากครึ่งที่จะประมาทมากที่จะเรียกร้องดังกล่าวโดยไม่ต้องทดสอบพวกเขาดังนั้นฉันจะพยายามไม่โกรธเคือง :) ในการโพสต์เต็มรูปแบบด้านล่างฉันจะจัดหาลิงก์ Pastebin ไปยังคอนโซลเอาต์พุต FFmpeg และ MediaInfo ข้อมูลเกี่ยวกับไฟล์อินพุตและไฟล์เอาต์พุตสุดท้าย ไฟล์อินพุตของฉัน, ไฟล์แบตช์ของฉัน, ไฟล์เอาต์พุตของฉันอยู่บน GoogleDrive ซึ่งสามารถดาวน์โหลดได้อย่างอิสระหากคุณต้องการทดสอบพวกเขากับ FFmpeg build ของคุณ

@ ShinMuraoka Mine is a win-64 ffmpeg build compiled on: Jan 6 2013, at: 16:16:53ทั้งวิธีการแก้ปัญหาของคุณและ @matteo แก้ปัญหาไม่ได้สำหรับฉัน นอกจากนี้ฉันดาวน์โหลดไฟล์ของคุณจาก Google Drive แต่ไม่ได้ให้ผลลัพธ์ที่คาดหวัง (ไฟล์ที่ส่งออกเป็นสีดำมีเพียงเสียง) โปรดช่วยฉันในการหาคำสั่งที่ถูกต้องที่จะใช้
coding_idiot

2
"ไม่มีเอาต์พุตสามารถมีแอตทริบิวต์ความสูงหรือความกว้างเลขคี่" ไม่เป็นความจริง ตั้งค่า pix_fmt เป็นสิ่งที่ไม่มีการสุ่มสี Chroma เช่น rgb24 หรือ yuv444p จากนั้นตรวจสอบให้แน่ใจว่าตัวแปลงสัญญาณและคอนเทนเนอร์รองรับและไม่มีข้อ จำกัด เพิ่มเติม เกี่ยวกับ pix_fmt FFmpeg น้อยกว่าอัจฉริยะ มันจะถือว่า yuv420p (ซึ่งมี subsampling chroma) เว้นแต่คุณจะบอกเป็นอย่างอื่น
Jonathan Baldwin

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

36

ง่ายยิ่งขึ้น:

ffmpeg -i ep1.png -i ep1.wav ep1.flv

FFmpeg จะพยายามเลือกตัวแปลงสัญญาณที่ดีที่สุดโดยอัตโนมัติขึ้นอยู่กับนามสกุลของไฟล์ผลลัพธ์ของคุณ

อัปเดต: ฉันสังเกตเห็นว่า YouTube มีปัญหาในการประมวลผลวิดีโอ (ติดค้างที่ 95%) ฉันคิดว่ามีเพียงเฟรมเดียว วิธีแก้ปัญหาที่ฉันพบว่าทำให้ YouTube มีความสุข: เพิ่มเฟรมมากขึ้น นอกจากนี้ฉันเพิ่ม-acodec copyเพื่อรักษาคุณภาพเสียง คุณต้องการ-shortestหรือมันวนซ้ำไปตลอดกาล (มันจะหยุดที่ส่วนท้ายของสตรีมที่สั้นที่สุดซึ่งเป็นเสียงเนื่องจากการวนซ้ำของรูปภาพนั้นไม่มีที่สิ้นสุด) ลำดับตัวเลือกของคุณมีความสำคัญมากต่อความเร็วเนื่องจากตัวกรอง (และตัวกรอง) ถูกประมวลผลตามลำดับที่คุณระบุ หากคุณเปลี่ยนลำดับของพารามิเตอร์เหล่านี้ผลลัพธ์จะแตกต่างกันอย่างมาก

ffmpeg -r 1 -loop 1 -i ep1.jpg -i ep1.wav -acodec copy -r 1 -shortest -vf scale=1280:720 ep1.flv

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


นอกจากนี้ยังเป็นไปได้ที่ไฟล์เสียงของคุณจะไม่สามารถทำงานร่วมกับคอนเทนเนอร์. flv ของคุณได้ ในกรณีนี้คุณควรลองคอนเทนเนอร์ (เอาต์พุต) อื่นเช่น. webm, .avi หรือรูปแบบใด ๆ จนกว่าคุณจะพบรูปแบบคอนเทนเนอร์ที่เข้ากันได้กับไฟล์เสียงของคุณ
PJ Brunet

1
ใช้สิ่งนี้สำหรับ. JPG และ. MP4 เพื่อสร้าง MP4 - ทำงานได้อย่างสมบูรณ์แบบ FLV ที่ฉันสร้างขึ้นจาก JPG / MP3 ดูเหมือนจะไม่ทำงาน - ซึ่งอาจเป็นไปตามคำเตือนความคิดเห็นก่อนหน้า

2
เวอร์ชันที่อัปเดตใช้งานได้สำหรับ Youtube ฉันคิดว่ามันติดอยู่ที่ 95% แต่ในที่สุดมันก็ใช้งานได้
Basj

ได้สิ่งนี้: No pixel format specified, yuvj420p for H.264 encoding chosen. Use -pix_fmt yuv420p for compatibility with outdated media players. [libx264 @ 0x2b5c940] height not divisible by 2 (700x457)... ใช้งานได้:ffmpeg -r 1 -loop 1 -i ep1.jpg -i ep1.wav -acodec copy -r 1 -shortest -vf scale=1280:-2 video.mp4
NineCattoRules

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

14

รุ่นที่เหมาะกับฉัน:

 ffmpeg -loop 1 -y -i pic.jpg -i sound.amr -shortest video.mp4

ชำระเงินตัวเลือก-shortestจะต้องอยู่ด้านหน้าของไฟล์ที่ส่งออกถ้าฉันไม่ได้รับข้อผิดพลาดด้านล่าง:

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


ขอบคุณสำหรับสิ่งนี้. คำตอบอื่น ๆ ส่วนใหญ่ไม่ได้ผลสำหรับฉัน (ใช้ ffmpeg บน Alpine linux) คำตอบนี้มีคำสั่งสั้นที่สุดที่ทำงานไร้ที่ติสำหรับฉัน
DannyB

8

จาก manf ffmpeg:

ffmpeg [[infile options][-i infile]]... {[outfile options] outfile}...

ในขณะที่คุณค้นพบตัวเลือก infile ต้องมาก่อน infile ที่พวกเขาใช้

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


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

4

สิ่งนี้ใช้ได้สำหรับฉัน

ffmpeg -loop 1 -shortest -y -i image.jpg -i audio.mp3 -acodec copy -vcodec libx264 video.avi

ฉันพบ vcodec libx264สร้างไฟล์เล็กกว่าmpjeg(10 MB มากกว่า 100 MB)


1
-shortestเป็นตัวเลือกเอาต์พุตและอาจถูกละเว้นเป็นตัวเลือกอินพุตตามที่คุณใช้
llogan

1

ฉันพยายามทำในฐานะ@matteoแต่ไม่มีเสียงและโซลูชันของ @Colonel Panicนั้นทำงานได้ดีที่สุด:

ffmpeg -loop 1 -shortest -y -i still.png -vcodec libx264 -t 10 video.avi

ฉันต้องเพิ่มอาร์กิวเมนต์ระยะเวลาในไม่กี่วินาที ( -t 10)


-shortestเป็นตัวเลือกเอาต์พุต แต่คุณใช้เป็นตัวเลือกอินพุต ย้ายไปข้างหน้าไฟล์เอาต์พุตและคุณสามารถกำจัดออกได้-t 10แต่จากนั้นคำตอบของคุณจะเหมือนกับคำอื่น ๆ
llogan

0

ffmpeg -loop 1 -i img.jpg -i audio.wav -c:v libx264 -c:a aac -strict experimental -b:a 192k -shortest out.mp4


5
คุณช่วยอธิบายวิธีที่คำสั่งที่คุณเพิ่มทำงานได้หรือไม่?
neelsg

คำตอบนี้ไม่แตกต่างจาก "ความเห็นคำตอบ" ทั่วไปอื่น ๆ ที่นี่
llogan

0

ในกรณีที่มีคนต้องการแปลงชุดพวกเขาลองนี้

คุณสามารถตั้งค่าโฟลเดอร์ Input และ Output และรูปแบบที่คุณต้องการให้วิดีโอเป็นในกรณีนี้ฉันตั้งค่าเป็น AVI

คำตอบนี้รวมหนึ่งภาพ + ไฟล์เสียงหนึ่งไฟล์เพื่อสร้างหนึ่งวิดีโอโดยใช้ FFmpegช่วยฉันได้มาก

 @echo off
 set "sourcedir=C:\Users\CodeHard\Desktop\BOX\Newfolder"  
 set "outputdir=C:\Users\CodeHard\Desktop\BOX\Converted" 

 PUSHD "%sourcedir%"

 for %%F in (*.mp3) DO ffmpeg -r 1 -loop 1 -i abc.jpeg -i "%%F" -acodec copy -r 1 -shortest -vf scale=1280:720 "%outputdir%\%%F.avi"  

 POPD

-1

ลองคำสั่งนี้ มันใช้งานได้สำหรับฉัน

-y -i /storage/emulated/0/images.jpg -i /storage/emulated/0/audio.wav -acodec aac -vcodec mpeg4 -s 480*320 -f mp4 -r 2 /storage/emulated/0/output.mp4"

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