การใช้งาน FFMPEG
เขียนโดย ดร.จักรกฤษณ์ แสงแก้ว วันที่ 5 ธันวาคม 2561
กล่าวนำ
FFMPEG เป็นโอเพ่นซอร์สสำหรับจัดการไฟล์ multimedia ใช้แปลงไฟล์หนัง หั่นไฟล์หนัง สกัดเสียง แทรกเสียง อื่น ๆ
กูเกิ้ล ใช้ FFMPEG ใน Data Centers เพื่อ บันทึก, แปลงไฟล์, สตรีมเสียงและวิดีโอ โดยได้มีการแก้ไขบั๊กใน FFMPEG มากกว่า 1000 จุด
นอกจากนั้น FFMpeg ถูกใช้ในแอพลิเคชั่นหลายตัว เช่น Chrome, MPlayer, VLC และ Xine
การติดตั้ง FFMPEG
$ sudo apt-get install ffmpeg
การสกัดภาพจากหนังในทุก 1 วินาที
$ ffmpeg -i yourvideo.mp4 -f image2 -bt 20M -vf fps=fps=10/60 img%03d.jpg
โปรแกรม ffplay
สำหรับเป็น media player ที่มาพร้อมกับ ffmpeg เวลาใช้งาน เรียกโปรแกรมและตามด้วยชื่อไฟล์หนัง หรือวิดีโอ เช่น
$ffplay walk.mp4
การสกัดเสียงออกมาจากวิดีโอ
$ ffmpeg -i yourvideo.mp4 -ab 160k -ac 2 -ar 44100 -vn output.mp3
- i คือ input file
- ab คือ บิตต่อวินาที ตัวอย่างนี้กำหนด 160kb/sec
- vn คือ no video output
- ac 2 คือ 2 ช่อง
- ar 44100 คือ อัตราแซมปลิ้ง (sampling frequency)
การแปลงวิดีโอฟอร์แมตต่าง ๆ
1. แปลง MOV เป็น FLV
$ ffmpeg -i movie1.mov movi
2. แปลง Mpeg เป็น FLV
ffmpeg -i movie1.mpeg movie1.flv
3. แปลงจาก AVI เป็น FLV
ffmpeg -i movie1.avi -s 500×500 movie1.flv
ปล. resolution 500x500
4. แปลงจาก 3GP เป็น FLV
ffmpeg -i movie1.3gp -sameq -an movie1.flv
5. แปลง MPEG เป็น 3GP
ffmpeg -i movie1.mpeg -ab 8.85k -acodec libamr_wb -ac 1 -ar 16000 -vcodec h263 -s qcif movie2.3gp
6. แปลง FFV1
ffmpeg -i -vcodec ffv1 -an output.mov
7. แปลง FLV เป็น MPG
ffmpeg -i myvideo.flv -ar 22050 -b 500 -s 320x240 myvideo.mpg
8. แปลง FLV เป็น AVI
ffmpeg -i input.flv output.avi
การแปลงฟอร์แมตเสียงต่าง ๆ
1. จาก AAC เป็น MP3
ffmpeg -i audio1.aac -ar 22050 -ab 32 -map_meta_data audio1.mp3:audio1.aac audio1.mp3
ปล. ใช้ 22.05Khz และ BitRate 32KHz
2. WMV เป็น MP3
ffmpeg -i audio1.wmv audio1.mp3
3. จาก WMV เป็น FLV
ffmpeg -i audio1.wmv audio1.flv
4. แปลง AMR เป็น MP3
ffmpeg -i audio1.amr -ar 22050 audio1.mp3
ปรแกรม WINFF เป็นกราฟิกอินเตอร์เฟส
สำหรับใครที่ไม่ถนัด command line interface (CLI) สามารถใช้กราฟิกได้ โดยติดตั้ง WINFF และใช้งานได้ดังนี้
$ sudo apt-get install winff
เรียกใช้งาน winff
$ winff
เมื่อเลือกไฟล์ input /output / format ต่าง ๆ และกด convert โปรแกรม winff จะสังเคราะห์อาร์กิวเมนต์ที่ต้องใช้ใน ffmpeg และเรียก ffmpeg ให้ทำงานเบื้องหลังแทนการออกคำสั่งโดยตรงจาก command line แบบนี้สะดวกเพราะไม่ต้องจดจำอาร์กิวเมนต์ต่าง ๆ ครับ
การเขียนเมตาดาต้า ลงในวิดีโอ
คำว่า metadata หมายถึง ข้อมูลที่อธิบายข้อมูล เช่น HELLO จะเห็นว่าแท็ก คือ เมตาดาต้า ที่อธิบายข้อมูลคือคำว่า HELLO ว่าให้มันเป็นตัวเข้มเมื่อแสดงผลในบราวเซอร์ เป็นต้น
เมตาดาต้าของไฟล์วิดีโอแต่ละประเภทก็ต่างกัน ดูตัวอย่างเพิ่มเติมจาก wiki ที่นี่ครับ
http://wiki.multimedia.cx/index.php?title=FFmpeg_Metadata
การสกัดช่วงหนึ่งช่วงใดในวิดีโอ
ffmpeg -ss 00:00:10 -i yourvideo.mp4 -t 00:00:14 -vcodec copy -acodec copy -y segment1.mp4
ในตัวอย่างนี้ตัดวิดีโอจากเวลา 00:00:10 (ชั่วโมง:นาที:วินาที) จนถึง 00:00:14 ตัดออกมา 4 วินาที และบันทึกในไฟล์ segment1.mp4
หมายเหตุ : สามารถใช้ -vcodec libx264 -codec:a เพื่อบีบอัดด้วยรูปแบบ x264
การบันทึกวิดีโอด้วย ffmpeg
1. ตรวจสอบว่าในระบบลินุกซ์ที่ใช้มี video devices อะไรบ้าง ด้วย v4l2-ctl ดังนี้
$ sudo apt-get install v4l-utils
2. ตรวจสอบอุปกรณ์บันทึกภาพวิดีโอที่เชื่อมต่อกับคอมพิวเตอร์
$ v4l2-ctl --list-devices
ปล. ตรวจสอบด้วย ls /dev/video* ก็ได้แต่ต้องการรายละเอียดเกี่ยวกับกล้องด้วย เช่น สนับสนุนการบันทึกด้วยความละเอียดเท่าไรบ้าง เป็นต้น
ในตัวอย่างนี้ ได้เพิ่ม usb webcam เข้าไป 1 ตัว มีชื่อ /dev/video1 จะบันทึกด้วยกล้องเว็บแคมตัวนี้ ด้วยคำสั่ง
3. บันทึกวิดีโอ
$ ffmpeg -f v4l2 -framerate 25 -video_size 640x480 -i /dev/video1 output.mkv
ปล. หยุดบันทึกกด Ctrl + c
4. จะได้ไฟล์ output.mkv ให้เปิดด้วย media player ต่อไป.. ตัวอย่างนี้ใช้ ffplayer
วิดีโอเอาพุตหลายช่องและเล่นไปพร้อม ๆ กัน
ในตัวอย่างนี้ผลลัพธ์ 4 ช่องในหนึ่งวิดีโอไฟล์ โดยแสดงหนังแต่ละเรื่องไปพร้อม ๆ กัน
เขียนโค๊ดดังนี้
$ ffmpeg -i 1.avi -i 2.avi -i 3.avi -i 4.avi -filter_complex "nullsrc=size=640x480 [base]; [0:v] setpts=PTS-STARTPTS, scale=320x240 [upperleft]; [1:v] setpts=PTS-STARTPTS, scale=320x240 [upperright]; [2:v] setpts=PTS-STARTPTS, scale=320x240 [lowerleft]; [3:v] setpts=PTS-STARTPTS, scale=320x240 [lowerright]; [base][upperleft] overlay=shortest=1 [tmp1]; [tmp1][upperright] overlay=shortest=1:x=320 [tmp2]; [tmp2][lowerleft] overlay=shortest=1:y=240 [tmp3]; [tmp3][lowerright] overlay=shortest=1:x=320:y=240" -c:v libx264 output.mkv
การใส่ watermask ให้วิดีโอ
1. ภาพลายน้ำที่ใช้ มีนามสกุล .png ให้ตัด alpha channel (พื้นหลังที่โปร่งแสง)
ตัวอย่างนี้ผมใช้ภาพนกเพนกิ้ว ให้มันตัวโต ๆ เพราะต้อการแสดงให้เห็นการใช้ alpha channel กับวิดีโอ
2. ใช้คำสั่ง ดังนี้
ffmpeg -i walk.mp4 -vf "movie=lix.png [watermark]; [in][watermark] overlay=10:10 [out]" outputvideo.mp4
จะได้วิดีโอที่มีการใส่ลายน้ำทับลงไป
การแปลงไฟล์วิดีโอเป็น Gif Animation
$ ffmpeg -i test.mp4 -pix_fmt rgb8 c.gif
หรือระบุช่วงเวลาในวิดีโอ ด้วยโค๊ดต่อไปนี้
$ ffmpeg -ss 00:00:00.000 -i yesbuddy.mov -pix_fmt rgb24 -r 10 -s 320x240 -t 00:00:10.000 output.gif
เมื่อ -pix_fmt คือ ฟอร์แมต ได้แก่ rgb8 หรือ rgb24 จำนวนบิตต่อ 1 พิกเซล เป็นต้น
บันทึก Webcam เป็น Video File
$ ffmpeg -f v4l2 -framerate 25 -video_size 640x480 -i /dev/video0 output.mp4
การลบเสียงออกจากวีดิโอ
$ ffmpeg -i vieo.mov -c copy -an output.mp4
เมื่อพารามิเตอร์ -an คือ ลบเสียงออกจากวีดิโอ
-c copy คือ คัดลอก
การสกัดเอาภาพในฉากวิดีโอที่กำลังเปลี่ยนแปลงด้วย FFMPEG
หากต้องการสกัดเอาภาพ Scene ที่เปลี่ยนแปลงระหว่างวิดีโอสั้น ๆ ภายในวิดีโอหลัก ถ้าทำด้วยมือจะช้ามากเพราะต้องเลื่อนเมาส์ขยับไปที่ตำแหน่งเฟรมที่กำลังเปลี่ยนแปลงแต่ละฉาก สำหรับงานนี้ต้องมอบให้ FFMPEG มีขั้นตอนดังนี้
$ ffmpeg -i video.mp4 -vf select="eq(pict_type\,PICT_TYPE_I)" -vsync 2 -s 320x240 thumb-%02d.png
หรือ
$ ffmpeg -i video-input.mp4 -f image2 -vf "select=gt(scene\,.4)" -vsync vfr thumb%04d.png
ตอนนี้สามารถสกัดเฉพาะเฟรมที่เปลี่ยนแปลงในฉากย่อย ๆ ในวิดีโอหลักได้แล้ว
การใช้งาน FFMPEG ในวินโดวส์
ดาวน์โหลดได้ที่ลิงค์ต่อไปนี้
https://ffmpeg.zeranoe.com/builds/
เนื่องจากเป็น portable จึงเพียงขยายไฟล์ออกมา และเรียกใช้งานได้เลย สะดวกมาก !!
การลดเสียงสัญญาณรบกวน (noise) ในวิดีโอด้วย FFMPEG
$ ffmpeg -i pyscenedetect-output.mp4 -af "highpass=f=200, lowpass=f=3000 output.mp4
- พารามิเตอร์ -af คือ ความถี่เสียง (audio frequency)
- กำหนด highpass=f=200 คือ การกำหนดการกรองความถี่สูง 200 คือให้ความถี่ที่มากกว่า 200 Hz ผ่านไปได้
- กำหนด lowpass=f=3000 คือ การกรองความถี่ต่ำ 3000 คือ ให้ความถี่ที่ต่ำกว่า 3000 Hz ผ่านไปได้
ปล. ปกติเสียงที่มนุษย์สามารถได้ยินอยู่ช่วง 20 - 20,000 Hz
สกัดเฟรมออกจากวิดีโอ
$ ffmpeg -i input.flv -vf fps=1 out%d.png
เมื่อ vps คือ จำนวนเฟรมต่อวินาที ถ้ากำหนด 1 หมายถึงสกัดออกมา 1 เฟรมภาพต่อวินาที
การนำไฟล์เสียงทับเสียงภายในวิดีโอ
$ ffmpeg -i v.mp4 -i a.wav -c:v copy -map 0:v:0 -map 1:a:0 new.mp4
การสกัดเฟรมที่เปลี่ยนแปลงออกมาจากวิดีโอ
$ ffmpeg -i input.mp4 -q:v 1 -filter:v "select='gt(scene,0.1)', showinfo" -vsync 0 FRAMES/%05d.jpg
เมื่อ -q:v 1 คือคุณภาพเฟรมที่บันทึกลงในไฟล์ภาพ ยิ่งมีค่าต่ำยิ่งมีคุณภาพสูง ปกติมีค่าระหว่าง 2-5
การแปลง MP4 เป็น Gif Animation
1. สกัดเอาช่วงที่ต้องการ
ffmpeg -ss 00:07:08 -i a.mp4 -t 00:00:08 -vcodec copy -y -strict -2 test.mp4
2. แปลงวีดิโอเป็นเฟรมภาพ
$ mkdir frames
$ ffmpeg -i test.mp4 -vf scale=640:-1:flags=lanczos,fps=10 frames/ffout%03d.png
3. แปลงเฟรมภาพเป็น GIF
$ convert -loop 0 frames/ffout*.png output.gif
ปล. convert เป็นคำสั่งของ image magic
การแปลงเปลี่ยน Frame Per Second (fps)
$ ffmpeg -i <input> -filter:v fps=fps=30
การปรับความเร็วเสียง
$ ffmpeg -i t1.wav -af asetrate=44100*0.37,atempo=1.0,atempo=1.0 -strict -2 output.mp4
- 0.37 นั้นทำให้ความเร็วเพิ่มขึ้นเล็กน้อย
- atempo=1.0 ปรับความให้เสียงเล็กแหลมค่าปกติเท่ากับ 1.0
การบันทึกเสียงจากไมโครโฟน
$ ffmpeg -f pulse -i default ไฟล์เสียง.wav
ปล. กด Ctrl + c เพื่อหยุดการบันทึกเสียง
การบันทึกเสียงและกำหนด sampling rate
$ ffmpeg -f alsa -ac 2 -i default -acodec libmp3lame -ab 320k ouput.mp3
การบันทึกหน้าจอคอมพิวเตอร์และเสียงบรรยาย
ffmpeg -f x11grab -video_size 1360x768 -framerate 30 -i :0.0 -f pulse -i default -preset ultrafast -crf 18 -pix_fmt yuv420p out.mkv
สร้างไฟล์ screen-capture.bat ดังนี้
echo off
set arg1=%1
ffmpeg -f gdigrab -framerate ntsc -i desktop -f dshow -i audio="Microphone (Realtek High Definition Audio)" -vcodec libx264 -pix_fmt yuv420p -preset ultrafast C:\Users\learning\Documents\video\%arg1%.mp4
การใช้งาน
screen-capture myscreen-record
ปล. โปรแกรมจะบันทึกวีดีโอไว้ใน document/ชื่อไฟล์ที่ตั้ง.mp4
การเปิดวีดิโอยูทูปด้วย vlc
$ cvlc --preferred-resolution 240 https://www.youtube.com/watch?v=m2Oo4kBHBNU
$ vlc "http://www.youtube.com/watch?v=m2Oo4kBHBNU&fmt=18"
การใช้ python-vlc
$ sudo pip3 install python-vlc
การสตรีมออนไลน์วีดีโอด้วย VLC
$ sudo pip3 install streamlink
$ sudo sudo3 apt-get install vlc
รูปแบบการใชังาน : $ streamlink [video-URL] [stream-quality]
$ streamlink https://youtu.be/B3OjfK0t1XM best
บันทึกวีดีโอด้วยพารามิเตอร์ --output เช่น
$ streamlink https://youtu.be/B3OjfK0t1XM best --output test.mp4
$ streamlink --plugins # แสดงรายชื่อปลั๊กอินที่ติดตั้งเรียบร้อยแล้ว
$ streamlink --plugin-dirs DIRECTORY # โหลดปลั๊กอินจากไดเร็คทอรี่
$ streamlink --json # แสดงรายละเอียดออกมาเป็นไฟล์ json
การดีบักใช้พารามิเตอร์ -l debug เช่น
$ streamlink -l debug https://youtu.be/B3OjfK0t1XM best --output test.mp4
การเปิดวีดีโอไฟล์จาก google drive
$ streamlink https://drive.google.com/open?id=0B0tRrdcY7CwJWGdVdHEyYWpfTTQ 1080p
การระบุโปรแกรมสำหรับเล่นไฟล์วีดีโอ
$ streamlink --player mpv https://drive.google.com/open?id=0B0tRrdcY7CwJWGdVdHEyYWpfTTQ 1080p
ปล. ตัวอย่างด้านบนเป็นการระบุให้ใช้โปรแกรม mpv ในการเล่นวีดีโอ
ศึกษาเพิ่มเติม :
- https://streamlink.github.io/cli.html
วิเคราะห์เว็บหนังที่เก็บข้อมูลบนกูเกิ้ลไดรว์
ลักษณะของลิงค์จะมี 2 แบบ โดยพิจารณารหัสวีดีโอหมายเลข : bb79d8e0872
1. เป็นวีดีโอยูทูปปกติแต่ไม่สามารถเปิดได้เพราะกำหนดนโยบายการเข้าถึง (policy) https://www.youtube.com/watch?v=bb79d8e0872
2. https://r1---sn-npoeene7.googlevideo.com/
videoplayback?
- id=bb79d8e0872bb105
- itag=37
- source=webdrive
- requiressl=yes
- pl=24
- sc=yes
- ei=8j0lXN-sOdGyogOmqYbACw
- susc=drp
- app=fife
- driveid=1Ncnzfr1yAHHJ-AZIUzutjEIsjg7fBif5
- mime=video/mp4
- dur=6151.732
- lmt=1533374158213685
- ip=2401:5700:100:503::5134
- ipbits=48
- expire=1545951762
- sparams=app,driveid,dur,ei,expire,id,ip,ipbits,ipbypass,itag,lmt,mime,mip,mm,mn,ms,mv,pl,requiressl,sc,source,susc
- signature=444B638D55DADF7A40002FA92C58969282B35041.1D6854DC67C50603CF0A3F9428D531C003944828
- key=cms1
- redirect_counter=1
- rm=sn-30aer7e
- fexp=23763603
- req_id=d36a0e04b94a36e2
- cms_redirect=yes
- ipbypass=yes
- mip=202.28.35.153
- mm=30
- mn=sn-npoeene7
- ms=nxu
- mt=1545947557
- mv=m
ตัวอย่างลิงค์จาก streamlink จะได้ดังนี้
https://r1---sn-j5u-c33k.googlevideo.com/videoplayback?
- dur=2719.056
- ip=202.28.35.153
- mm=31%2C29
- mn=sn-j5u-c33k%2Csn-npoe7n7y
- key=yt6
- fvip=3
- ms=au%2Crdu
- source=youtube
- sparams=dur%2Cei%2Cid%2Cinitcwndbps%2Cip%2Cipbits%2Citag%2Clmt%2Cmime%2Cmm%2Cmn%2Cms%2Cmv%2Cpl%2Cratebypass%2Crequiressl%2Csource%2Cexpire
- mv=m
- initcwndbps=1703750
- id=o-AAu89fTOrthq-KUR9dT6TjfXFUSEWb-bsdoxhnP465WY
- mime=video%2Fmp4
- pl=24&txp=5431432
- ei=2E8lXJuMEZKLoAPHwJ3ABg&c=WEB&ratebypass=yes
- itag=22
- signature=CDE86E9185138DA341B6026997F5BB33E534FE94.C4080EAAC07A3FB4C9AE6FB6BBCC47765FC0E7CA
- requiressl=yes
- lmt=1542080865581626
- ipbits=0
- mt=1545949021
- expire=1545970745
การแปลงไฟล์ทั้งหมดเป็นฟอร์แมตอื่น
ในตัวอย่างนี้แปลงจาก MOV เป็น mp4 ดังนี้
$ for i in *.MOV; do ffmpeg -i "$i" -strict -2 "${i%.*}.mp4"; done
การบันทึกหน้าจอพร้อมเสียงบรรยาย
การแสดงรายชื่อไมโครโฟน
$ ffmpeg -list_devices true -f dshow -i dummy
การบันทึกเฉพาะเสียง
ffmpeg -f dshow -i audio="Microphone (Realtek High Definition Audio)" D:\Audio\output.mp3
การบันทึกหน้าจอและเสียง
$ffmpeg -f gdigrab -framerate ntsc -video_size 1920x1080 -i desktop -f dshow -i audio="Microphone (Realtek High Definition Audio)" -vcodec libx264 -pix_fmt yuv420p -preset ultrafast c:\tmp\test.mp4
การบันทึกหน้าจอบนระบบปฏิบัติการวินโดวส์ด้วย Hardware Encoding พบว่าใช้ PowerShell จะให้เสียงที่สดใสกว่าเรียกผ่าน CMD
การตรวจสอบไมค์
ffmpeg -list_devices true -f dshow -i dummy
การบันทึกหน้าจอด้วยฮาร์ดแวร์เร่งสามมิติ nvidia
ffmpeg -f gdigrab -framerate 30 -i desktop -c:v h264_nvenc -qp 0 output.mkv
ปล. ใช้พารามิเตอร์ -c:v h264_nvenc
การบันทึกหน้าจอและเสียง
ffmpeg -f gdigrab -framerate ntsc -video_size 800x600 -i desktop -f dshow -i audio="Microphone (Realtek High Definition Audio)" -vcodec libx264 -pix_fmt yuv420p -preset ultrafast test.mp4
บันทึกหน้าจอทั้งหมดโดยไม่ใช้งาน -video_size
ffmpeg -f gdigrab -framerate ntsc -i desktop -f dshow -i audio="Microphone (Realtek High Definition Audio)" -vcodec libx264 -pix_fmt yuv420p -preset ultrafast test.mp4
การบันทึกหน้าจอ desktop แบบไม่บันทึกเสียง
ffmpeg -f gdigrab -framerate 30 -i desktop ffmpeg.mp4
ปล. เมื่อต้องการยุติการบันทึกวีดีโอให้กดคีย์ q เพื่อจบการทำงาน
ปล. h264_nvenc เป็นฮาร์ดแวร์การ์ดเร่งสามมิติของบริษัท Nvidia
ดาวน์โหลด FFMPEG สำหรับ Windows
ffmpeg-20190112-1ea5529-win64-static.zip
การขยายสเกลของวีดีโอ
1. การกำหนดสัดส่วนกว้างxสูงเดิมเหมือนต้นฉบับ ใช้คำสั่งต่อไปนี้
ffmpeg -i input.avi -filter:v scale=720:-1 -c:a copy output.mp4
2. การกำหนดสัดส่วนกว้างxสูงใหม่ ใช้คำสั่งต่อไปนี้
ffmpeg -i input.avi -s 720x480 -c:a copy output.mp4
คุณสมบัติกล้องสำหรับตรวจจับทะเบียนรถยนต์
- IP Camera
- 2MPixel 25-30FPS
- Lens 5-100mm
- Resolution 1280x720
การบีบอัดด้วยมาตรฐาน H.265
$ ffmpeg -i input.mp4 -c:v libx265 -preset medium -x265-params crf=28 -c:a aac -strict -2 -b:a 128k output.mp4
การเพิ่มเสียงในไฟล์ MP4
$ ffmpeg -i source.mp4 -af volume=5 -vcodec copy newfile.mp4
พารามิเตอร์ volume=5 คือ ขยายเสียงขึ้น 5 %
การแปลงไฟล์เสียง
การแปลง wav เป็น mp3
$ ffmpeg -i input.wav -vn -ar 44100 -ac 2 -b:a 192k output.mp3
การต่อไฟล์วีดีโอเข้าด้วยกัน
สร้างรายชื่อไฟล์ ตั้งชื่อตามต้องการ เช่น filelist.txt ภายในไฟล์มีรายชื่อไฟล์วีดีโอ ดังนี้
file '1.mp4'
file '2.mp4'
file '3.mp4'
คำสั่ง ffmpeg -f concat -safe 0 -i filelist.txt -c copy output.mp4
การกลับวีดีโอ (Reverse)
ffmpeg -i originalVideo.mp4 -vf reverse reversedVideo.mp4
การเลือกตัดบางพื้นที่ของวีดีโอ
ffmpeg -i input.mp4 -filter:v "crop=1600:900:0:0" output.mp4
การแปลงเสียง mp3 ให้เป็น mono และ sampling rate 11025 hz
ffmpeg -i inputfile.mp3 -ac 1 -ar 11025 outputfile.mp3
ปล. กำหนด sampling rate ได้ตามต้องการ เช่น 22050 11025 ฯลฯ
ปบ. -ac 1 คือ mono -ac 2 คือ stereo (audio channel)