ฉันมีวิดีโอที่หมุนได้ 180 °เมื่อบันทึก เป็นไปได้ไหมที่จะแก้ไขด้วย FFmpeg?
ฉันมีวิดีโอที่หมุนได้ 180 °เมื่อบันทึก เป็นไปได้ไหมที่จะแก้ไขด้วย FFmpeg?
คำตอบ:
ffmpeg
จะหมุนวิดีโอโดยอัตโนมัติเว้นแต่:
ffmpeg
แก่เกินไปวิดีโอบางรายการเช่นจาก iPhone ไม่ได้พลิกทางกายภาพ แต่มีสตรีมวิดีโอแสดงข้อมูลด้านเมทริกซ์หรือหมุนข้อมูลเมตา ผู้เล่นบางคนไม่สนใจข้อมูลเมตาเหล่านี้และบางคนก็ไม่สนใจ อ้างถึงffmpeg
คอนโซลเอาต์พุตเพื่อดูว่าอินพุตของคุณมีข้อมูลเมตาดังกล่าวหรือไม่:
$ ffmpeg -i input.mp4
...
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
Duration: 00:00:05.00, start: 0.000000, bitrate: 43 kb/s
Stream #0:0(und): Video: h264 (High 4:4:4 Predictive) (avc1 / 0x31637661), yuv444p, 320x240 [SAR 1:1 DAR 4:3], 39 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)
Metadata:
rotate : 180
Side data:
displaymatrix: rotation of -180.00 degrees
ffmpeg
จะหมุนวิดีโอโดยอัตโนมัติตามข้อมูลเมตาการหมุนสตรีมวิดีโอที่มีอยู่
คุณต้องมีบิลด์ที่รวมการคอมมิชชัน 1630224 ตั้งแต่วันที่ 2 พฤษภาคม 2558 เพื่อให้สามารถใช้คุณสมบัติการ autorotation ได้
ffmpeg -i input.mp4 -c:a copy output.mp4
หากต้องการปิดใช้งานลักษณะการทำงานนี้ให้ใช้-noautorotate
ตัวเลือก
ffmpeg
เป็นคนเก่าคุณจะต้องใช้ตัวกรองเพื่อหมุนวิดีโอและหากมีข้อมูลเมตาหมุนใด ๆ จะต้องถูกลบดังแสดงในตัวอย่างด้านล่าง:
การใช้ffmpeg
คุณมีตัวเลือกสามวิธีในการใช้ตัวกรองวิดีโอเพื่อหมุน 180 °
hflip
และ vflip
ffmpeg -i input.mp4 -vf "hflip,vflip,format=yuv420p" -metadata:s:v rotate=0 \
-codec:v libx264 -codec:a copy output.mkv
transpose
ffmpeg -i input.mp4 -vf "transpose=2,transpose=2,format=yuv420p" \
-metadata:s:v rotate=0 -codec:v libx264 -codec:a copy output.mp4
rotate
ตัวกรองนี้สามารถหมุนไปที่มุมใดก็ได้และใช้เรเดียนเป็นหน่วยแทนองศา ตัวอย่างนี้จะหมุนπ / 1 เรเดียนหรือ 180 °:
ffmpeg -i input.mp4 -vf "rotate=PI:bilinear=0,format=yuv420p" \
-metadata:s:v rotate=0 -codec:v libx264 -codec:a copy output.mp4
คุณสามารถใช้องศาแทน หนึ่งองศามีค่าเท่ากับπ / 180 เรเดียน ดังนั้นหากคุณต้องการหมุน 45 °:
ffmpeg -i input.mp4 -vf "rotate=45*(PI/180),format=yuv420p" \
-metadata:s:v rotate=0 -codec:v libx264 -codec:a copy output.mp4
เมื่อใช้rotate
ตัวกรองการแก้ไข bilinear ควรปิด (โดยใช้bilinear=0
) สำหรับมุมที่หารด้วย 90 มิฉะนั้นอาจดูไม่ชัด
การกรองต้องมีการเข้ารหัส ตัวอย่างเหล่านี้สร้างวิดีโอ H.264 ดูคู่มือการเข้ารหัสวิดีโอ FFmpeg H.264สำหรับคำแนะนำในการรับคุณภาพที่คุณต้องการ
การสุ่มตัวอย่าง Chroma ฉันรวมไว้format=yuv420p
ตั้งแต่ffmpeg
จะพยายามย่อเล็กสุดหรือหลีกเลี่ยงการสุ่มสี Chroma (ขึ้นอยู่กับตัวเข้ารหัสอินพุตffmpeg
รุ่น ฯลฯ ) นี่เป็นพฤติกรรมที่ดีในด้านเทคนิคล้วนๆ แต่ผู้เล่นส่วนใหญ่ไม่เข้ากันกับโครงร่างการสุ่มสีที่ "ก้าวหน้า" มากกว่า สิ่งนี้เหมือนกับการใช้-pix_fmt yuv420
แต่ตั้งอยู่ในfilterchainอย่างสะดวก
คัดลอกเสียง -codec:a copy
ตัวเลือกที่จะสตรีมสำเนา (อีกครั้ง MUX) แทนการเข้ารหัส ไม่มีเหตุผลที่จะเข้ารหัสเสียงอีกครั้งหากคุณต้องการจัดการวิดีโอเท่านั้น (เว้นแต่คุณต้องการแปลงเป็นรูปแบบเสียงอื่น) นี่จะประหยัดเวลาเนื่องจากการเข้ารหัสใช้เวลานานและจะรักษาคุณภาพของเสียงไว้
หรือคุณสามารถหมุนเมื่อเล่นและหลีกเลี่ยงการเข้ารหัสใหม่ ffplay
จะหมุนโดยอัตโนมัติ:
ffplay input.mp4
หากไม่มีข้อมูลด้านข้างของ displaymatrix หรือหมุนข้อมูลเมตาคุณสามารถใช้ตัวกรองได้:
ffplay -vf "hflip,vflip" -i input.mp4
... หรืออ้างอิงถึงผู้เล่นที่คุณชื่นชอบ ผู้เล่นส่วนใหญ่ที่มีค่าควรใช้เช่น VLC มีความสามารถนี้
ffmpeg
บิลด์ที่เก่ากว่าของ ffmpeg ไม่รวมความสามารถในการกรอง ดูดาวน์โหลด FFmpegหน้าหาตัวเลือกหลายคนรวมทั้งสร้างความสะดวกสบายสำหรับ Linux, OS X และ Windows หรือดูที่FFmpeg วิกิพีเดียสำหรับขั้นตอนโดยขั้นตอน ffmpeg รวบรวมคำแนะนำ
-vf vflip
และใช้งานได้อย่างมีเสน่ห์ แต่มันเป็นรหัสอีกครั้ง ฉันไม่แน่ใจว่าฉันอ่านคุณถูกไหม คุณกำลังบอกว่า-vf hflip,vflip
จะไม่เข้ารหัสอีกครั้ง?
ffmpeg
ต้องการให้คุณเข้ารหัสอีกครั้งเมื่อใช้ตัวกรองวิดีโอและเสียง อย่างไรก็ตามffplay
ยังสามารถใช้ตัวกรองจำนวนมากในระหว่างการเล่นดังที่แสดงในตัวอย่างที่สองของฉัน
-codec:v libx264
หรือไม่? สามารถffmpeg
ใช้การเข้ารหัสเดียวกันโดยที่ผู้ใช้ไม่ได้ลองคิดดู
FFMPEG เปลี่ยนพฤติกรรมเริ่มต้นอัตโนมัติหมุนแหล่งวิดีโออินพุตกับเมตาดาต้า "หมุน" ในรุ่น v2.7 ในปี 2015
หากคุณรู้ว่าสคริปต์หรือคำสั่งของคุณจะไม่ทำงานบน ffmpeg ที่เก่ากว่า 2.7 โซลูชันที่ง่ายที่สุดคือการลบการหมุนเวียนแบบกำหนดเองใด ๆ ตามข้อมูลเมตา
สำหรับกรณีอื่น ๆ คุณสามารถพิสูจน์ได้ในอนาคตโดยเก็บรหัสการหมุนที่กำหนดเองของคุณและเพิ่มการ-noautorotate
ตั้งค่าสถานะ
เครื่องเล่นสื่อที่ใช้ ffmpeg เป็นแบ็คเอนด์ถอดรหัสยังสามารถใช้ตัวกรองทั้งหมดได้ ดูภาพหน้าจอนี้ด้วยตัวกรอง "Offset & flip"
หรือถ้าคุณต้องการเข้ารหัสวิดีโออีกครั้งให้ลองดูวิดีโอการหมุนด้วย FFmpegบน Stackoverflow
transpose
ตัวกรองที่อ้างถึงในวิดีโอการหมุนด้วย FFmpegจะไม่หมุน 180 องศาเท่าที่ฉันสามารถบอกได้
transpose
โยงสองตัวกรองเข้าด้วยกันเพื่อให้ได้ผล
ต่อไปนี้เป็นสคริปต์ทุบตีซึ่งจะส่งออกไฟล์ที่มีโครงสร้างไดเรกทอรีภายใต้ "fixedFiles" มันแปลงและหมุนวิดีโอ iOS และแปลงสัญญาณ AVIs สคริปต์อาศัยได้ติดตั้งได้ทั้งexiftoolและffmpeg
#!/bin/bash
# rotation of 90 degrees. Will have to concatenate.
#ffmpeg -i <originalfile> -metadata:s:v:0 rotate=0 -vf "transpose=1" <destinationfile>
#/VLC -I dummy -vvv <originalfile> --sout='#transcode{width=1280,vcodec=mp4v,vb=16384,vfilter={canvas{width=1280,height=1280}:rotate{angle=-90}}}:std{access=file,mux=mp4,dst=<outputfile>}\' vlc://quit
#Allowing blanks in file names
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
#Bit Rate
BR=16384
#where to store fixed files
FIXED_FILES_DIR="fixedFiles"
#rm -rf $FIXED_FILES_DIR
mkdir $FIXED_FILES_DIR
# VLC
VLC_START="/Applications/VLC.app/Contents/MacOS/VLC -I dummy -vvv"
VLC_END="vlc://quit"
#############################################
# Processing of MOV in the wrong orientation
for f in `find . -regex '\./.*\.MOV'`
do
ROTATION=`exiftool "$f" |grep Rotation|cut -c 35-38`
SHORT_DIMENSION=`exiftool "$f" |grep "Image Size"|cut -c 39-43|sed 's/x//'`
BITRATE_INT=`exiftool "$f" |grep "Avg Bitrate"|cut -c 35-38|sed 's/\..*//'`
echo Short dimension [$SHORT_DIMENSION] $BITRATE_INT
if test "$ROTATION" != ""; then
DEST=$(dirname ${f})
echo "Processing $f with rotation $ROTATION in directory $DEST"
mkdir -p $FIXED_FILES_DIR/"$DEST"
if test "$ROTATION" == "0"; then
cp "$f" "$FIXED_FILES_DIR/$f"
elif test "$ROTATION" == "180"; then
# $(eval $VLC_START \"$f\" "--sout="\'"#transcode{vfilter={rotate{angle=-"$ROTATION"}},vcodec=mp4v,vb=$BR}:std{access=file,mux=mp4,dst=\""$FIXED_FILES_DIR/$f"\"}'" $VLC_END )
$(eval ffmpeg -i \"$f\" -vf hflip,vflip -r 30 -metadata:s:v:0 rotate=0 -b:v "$BITRATE_INT"M -vcodec libx264 -acodec copy \"$FIXED_FILES_DIR/$f\")
elif test "$ROTATION" == "270"; then
$(eval ffmpeg -i \"$f\" -vf "scale=$SHORT_DIMENSION:-1,transpose=2,pad=$SHORT_DIMENSION:$SHORT_DIMENSION:\(ow-iw\)/2:0" -r 30 -s "$SHORT_DIMENSION"x"$SHORT_DIMENSION" -metadata:s:v:0 rotate=0 -b:v "$BITRATE_INT"M -vcodec libx264 -acodec copy \"$FIXED_FILES_DIR/$f\" )
else
# $(eval $VLC_START \"$f\" "--sout="\'"#transcode{scale=1,width=$SHORT_DIMENSION,vcodec=mp4v,vb=$BR,vfilter={canvas{width=$SHORT_DIMENSION,height=$SHORT_DIMENSION}:rotate{angle=-"$ROTATION"}}}:std{access=file,mux=mp4,dst=\""$FIXED_FILES_DIR/$f"\"}'" $VLC_END )
echo ffmpeg -i \"$f\" -vf "scale=$SHORT_DIMENSION:-1,transpose=1,pad=$SHORT_DIMENSION:$SHORT_DIMENSION:\(ow-iw\)/2:0" -r 30 -s "$SHORT_DIMENSION"x"$SHORT_DIMENSION" -metadata:s:v:0 rotate=0 -b:v "$BITRATE_INT"M -vcodec libx264 -acodec copy \"$FIXED_FILES_DIR/$f\"
$(eval ffmpeg -i \"$f\" -vf "scale=$SHORT_DIMENSION:-1,transpose=1,pad=$SHORT_DIMENSION:$SHORT_DIMENSION:\(ow-iw\)/2:0" -r 30 -s "$SHORT_DIMENSION"x"$SHORT_DIMENSION" -metadata:s:v:0 rotate=0 -b:v "$BITRATE_INT"M -vcodec libx264 -acodec copy \"$FIXED_FILES_DIR/$f\" )
fi
fi
echo
echo ==================================================================
sleep 1
done
#############################################
# Processing of AVI files for my Panasonic TV
# Use ffmpegX + QuickBatch. Bitrate at 16384. Camera res 640x424
for f in `find . -regex '\./.*\.AVI'`
do
DEST=$(dirname ${f})
DEST_FILE=`echo "$f" | sed 's/.AVI/.MOV/'`
mkdir -p $FIXED_FILES_DIR/"$DEST"
echo "Processing $f in directory $DEST"
$(eval ffmpeg -i \"$f\" -r 20 -acodec libvo_aacenc -b:a 128k -vcodec mpeg4 -b:v 8M -flags +aic+mv4 \"$FIXED_FILES_DIR/$DEST_FILE\" )
echo
echo ==================================================================
done
IFS=$SAVEIFS
ฉันถูกขอให้แก้ไขสิ่งนี้เพื่อนำหน้าข้อความโดยระบุวิธีการแก้ปัญหาที่ฉันพบในท้ายที่สุดว่าเป็นตอนท้ายของข้อความ ดังนั้นในตอนท้ายคุณจะพบคำสั่ง ffmpeg ต่อเนื่องสองคำที่หมุนวิดีโอของฉันให้เป็นแนวที่ถูกต้อง ข้อความก่อนหน้าซึ่งตั้งใจจะให้ข้อมูลมากที่สุดเท่าที่จะทำได้อย่างที่ฉันเห็นข้อความอื่น ๆ ที่ถูกคัดค้านเนื่องจากขาดข้อมูล อย่างไรก็ตามฉันหวังว่านี่จะช่วยให้ผู้อื่นใช้ ffmpeg สำหรับฉันแล้ววัตถุประสงค์ของ hflip และ vflip ใน ffmpeg คืออย่างน้อยสับสนและตรงข้ามกับสิ่งที่ฉันคาดไว้
ไฟล์ merlin.mov เป็นสำเนาของวิดีโอที่ฉันถ่ายบน iphone ของฉันอัปโหลดไปยัง Dropbox ก่อนจากนั้นดาวน์โหลดไปยังแล็ปท็อปของฉันโดยใช้ Ubuntu:
$ uname -a
Linux gazelle 3.13.0-135-generic #184-Ubuntu SMP
Wed Oct 18 11:55:51 UTC 2017 x86_64 x86_64 x86_64
GNU/Linux
ฉันรู้ว่าฉันควรจะติดตั้ง iphone ของฉันผ่าน USB และคัดลอกไฟล์โดยตรง แต่นั่นไม่ได้ผล แล็ปท็อปของฉันจะรับรู้ว่า iPhone เชื่อมต่ออยู่ แต่จะไม่เชื่อมต่อกับระบบไฟล์ของมันและฉันไม่ได้แจ้งให้ iPhone ของฉัน "เชื่อถือ" แล็ปท็อป
คำสั่งที่ฉันใช้เพื่อคัดลอกจาก Dropbox ไปยังแล็ปท็อปของฉันคือ:
cp ~/Dropbox/Camera\ Uploads/Video\ Nov\ 02\,\ 9\ 41\ 55\ AM.mov \
merlin.mov
ไฟล์ต้นฉบับคือวิดีโอ 1920 x 1080 Codec HEVC / H.265 Framerate 30 / วินาที, บิตเรต 8140 kbps, Audio Codec MPEG-4 AAC เสียงช่องสเตอริโอ, อัตราตัวอย่าง 44100 Hz, บิตเรต 85 kbps เมื่อฉันเล่นมันบน iphone ของฉันมันถูกวางแนวอย่างเหมาะสมและเสียงจะถูกซิงโครไนซ์ เมื่อฉันเล่นในวิดีโอบนแล็ปท็อปของฉันมันทั้งคว่ำและกลับด้านในแนวนอนและเสียงไม่ได้ถูกซิงโครไนซ์ นี่คือผลลัพธ์บางส่วนจาก "ffmpeg -i merlin.mov":
Metadata:
rotate : 180
creation_time : 2017-11-02T14:41:55.000000Z
handler_name : Core Media Data Handler
encoder : HEVC
นี่คือบรรทัดแรกของเอาต์พุตจาก "ffmpeg -version":
ffmpeg รุ่น 3.3.3 ลิขสิทธิ์ (c) 2000-2017 นักพัฒนา FFmpeg
ต่อไปนี้ทำให้การเล่นกลับด้านทั้งในแนวตั้งและแนวนอนแม้ว่ามันจะแปลงเป็นวิดีโอ MPEG-4 (วิดีโอ / mp4) และซิงโครไนซ์เสียง:
ffmpeg -i merlin.mov -vf 'hflip,vflip' merlinhflipvflip.mp4
ฤvertedษีต่อไปนี้ในแนวตั้งเพื่อให้การเล่นตั้งตรงซิงโครไนซ์เสียงและแปลงเป็น MPEG-4 แต่ปล่อยให้แนวนอนพลิกไปมาอย่างไม่ถูกต้องจบจุดสิ้นสุด (นี่ไม่ใช่การพิมพ์ผิดฉันได้ระบุ 'hflip'):
ffmpeg -i merlin.mov -vf 'hflip' merlinhflip.mp4
ต่อไปนี้พลิกแนวนอนไปในทิศทางที่ถูกต้อง แต่ทำให้การเล่นกลับด้าน:
ffmpeg -i merlin.mov -vf 'vflip' merlinvflip.mp4
ต่อไปนี้ดูเหมือนจะไม่มีผลใด ๆ :
ffmpeg -i merlin.mov -vf 'hflip' merlinhflip.mp4
ffmpeg -i merlinhflip.mp4 -vf 'vflip' merlin2stepA.mp4
ฉันยังลองสิ่งนี้ตามคำสั่งที่ฉันพบที่ superuser.com ประสบความสำเร็จในการซิงโครไนซ์เสียงและแปลงเป็น MPEG-4 แต่การวางแนวทั้งแนวนอนและแนวตั้งยังคงไม่ถูกต้อง:
ffmpeg -i merlin.mov \
-vf "rotate=PI:bilinear=0,format=yuv420p" \
-metadata:s:v rotate=0 -codec:v libx264 \
-codec:a copy merlinrotate.mp4
ฉันก็ลองทำเช่นนี้ซึ่งไม่ได้ผลทั้งในแง่ของการแก้ไขการวางแนว:
ffmpeg -noautorotate -i merlin.mov merlinnoautorotate.mp4
กระบวนการสองขั้นตอนต่อไปนี้ได้ในสิ่งที่ฉันต้องการในที่สุด แนวตั้งและแนวนอนทั้งพลิกซิงโครไนซ์เสียงและรูปแบบที่แปลงเป็น MPEG-4 (อีกครั้งนี่ไม่ใช่การพิมพ์ผิดฉันใช้ hflip ในทั้งสองคำสั่ง):
ffmpeg -i merlin.mov -vf 'hflip' merlinhflip.mp4
ffmpeg -i merlinhflip.mp4 -vf 'hflip' merlin2stepB.mp4
นี่คือขั้นตอน:
ก่อนเปิดไฟล์วิดีโอของคุณใน QuickTime คุณสามารถเปิดไฟ QuickTime ก่อนไปที่ "ไฟล์" จากนั้นลงไปที่ "เปิดไฟล์" หรือคุณสามารถคลิกขวาที่ไฟล์นั้นเองเลือก“ Open With” แล้วเลือก QuickTime
เมื่อวิดีโอเปิดขึ้นให้คลิก“ แก้ไข” แล้วคุณจะพบตัวเลือกการหมุนและพลิกด้านล่าง
เมื่อคุณล็อคการวางแนวที่คุณต้องการแล้วคุณต้องส่งออกวิดีโอของคุณด้วยการเปลี่ยนแปลงใหม่ที่คุณเพิ่ม คุณจะพบตัวเลือก“ ส่งออก” ใต้เมนู“ ไฟล์” ใน QuickTime
เลือกการตั้งค่าไฟล์ที่คุณต้องการส่งออกและคลิก“ ตกลง” เพื่อเริ่มต้นการส่งออก
เมื่อการส่งออกเสร็จสมบูรณ์คุณจะพบไฟล์ใหม่ของคุณที่คุณเคยเลือกที่จะบันทึกด้วยการวางแนวที่ถูกต้อง!
การแก้ไขทั้งหมดนี้ใช้เวลาน้อยกว่า 5 นาทีในการดำเนินการ แต่ขึ้นอยู่กับความยาวของวิดีโออาจใช้เวลานานกว่านั้น
ffmpeg -i input.mp4 -filter:v "transpose=1,transpose=1" output.mp4
เคล็ดลับสำหรับฉัน ไม่แน่ใจว่าทำไมตัวกรองขนย้ายไม่ได้ให้ความเป็นไปได้ในการหมุน 180 องศาในคราวเดียว แต่อย่างใด ตรวจสอบเอกสารสำหรับข้อมูลเพิ่มเติม