Tôi có một video được quay 180 ° khi quay. Có thể sửa lỗi này với FFmpeg không?
Tôi có một video được quay 180 ° khi quay. Có thể sửa lỗi này với FFmpeg không?
Câu trả lời:
ffmpeg
sẽ tự động xoay video trừ khi:
ffmpeg
quá giàMột số video, chẳng hạn như từ iPhone, không được lật vật lý, nhưng chứa dữ liệu bên màn hình hiển thị luồng video hoặc xoay siêu dữ liệu. Một số người chơi bỏ qua các siêu dữ liệu này và một số thì không. Tham khảo ffmpeg
đầu ra của bàn điều khiển để xem liệu đầu vào của bạn có siêu dữ liệu như vậy không:
$ 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
sẽ tự động xoay video theo bất kỳ siêu dữ liệu xoay luồng video hiện có.
Bạn cần một bản dựng bao gồm cam kết 1630224, từ ngày 2 tháng 5 năm 2015, để có thể sử dụng tính năng tự động.
ffmpeg -i input.mp4 -c:a copy output.mp4
Để vô hiệu hóa hành vi này sử dụng -noautorotate
tùy chọn.
ffmpeg
cũ của bạnBạn sẽ phải sử dụng bộ lọc để xoay video và nếu có bất kỳ siêu dữ liệu xoay nào tồn tại, nó sẽ phải bị xóa như trong các ví dụ dưới đây:
Sử dụng ffmpeg
bạn có thể lựa chọn ba phương pháp sử dụng bộ lọc video để xoay 180 °.
hflip
và 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
Bộ lọc này có thể xoay đến bất kỳ góc tùy ý nào và sử dụng radian làm đơn vị thay vì độ. Ví dụ này sẽ xoay π / 1 radian hoặc 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
Bạn có thể sử dụng độ thay thế. Một độ bằng với π / 180 radian. Vì vậy, nếu bạn muốn xoay 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
Khi sử dụng rotate
bộ lọc, nên tắt nội suy song tuyến tính (bằng cách sử dụng bilinear=0
) cho các góc chia hết cho 90, nếu không nó có thể bị mờ.
Lọc đòi hỏi phải mã hóa. Những ví dụ này làm cho đầu ra video H.264. Xem Hướng dẫn mã hóa video FFmpeg H.264 để được hướng dẫn về chất lượng bạn muốn.
Lấy mẫu con Chroma. Tôi bao gồm format=yuv420p
vì ffmpeg
sẽ cố gắng giảm thiểu hoặc tránh lấy mẫu màu (tùy thuộc vào bộ mã hóa, đầu vào, ffmpeg
phiên bản, v.v.). Đây là hành vi tốt theo nghĩa kỹ thuật thuần túy, nhưng hầu hết người chơi không tương thích với các sơ đồ lấy mẫu sắc độ "tiên tiến" hơn. Điều này giống như sử dụng -pix_fmt yuv420
, nhưng được đặt thuận tiện trong bộ lọc .
Sao chép âm thanh. Các -codec:a copy
tùy chọn sẽ truyền bản sao (re-MUX) thay vì mã hóa. Không có lý do để mã hóa lại âm thanh nếu bạn chỉ muốn thao tác video mà thôi (trừ khi bạn muốn chuyển đổi sang định dạng âm thanh khác). Điều này sẽ tiết kiệm thời gian vì mã hóa tốn thời gian và nó sẽ bảo vệ chất lượng âm thanh.
Ngoài ra, bạn có thể xoay khi phát lại và tránh mã hóa lại. ffplay
sẽ tự động xoay:
ffplay input.mp4
Nếu không có dữ liệu bên hiển thị hoặc xoay siêu dữ liệu thì bạn có thể sử dụng các bộ lọc:
ffplay -vf "hflip,vflip" -i input.mp4
... Hoặc tham khảo người chơi yêu thích của bạn. Hầu hết người chơi đáng sử dụng, như VLC, có khả năng này.
ffmpeg
Các bản dựng cũ hơn của ffmpeg không bao gồm các khả năng lọc. Xem trang tải xuống FFmpeg để biết một số tùy chọn bao gồm các bản dựng thuận tiện cho Linux, OS X và Windows hoặc tham khảo Wiki FFmpeg để biết hướng dẫn biên dịch ffmpeg từng bước .
-vf vflip
và nó hoạt động như một lá bùa. Nhưng đó là một mã hóa lại. Tôi không chắc là tôi có đọc đúng không. Bạn đang nói -vf hflip,vflip
sẽ không mã hóa lại?
ffmpeg
yêu cầu bạn mã hóa lại khi sử dụng các bộ lọc video và âm thanh. Tuy nhiên, ffplay
cũng có thể sử dụng nhiều bộ lọc trong khi phát lại như trong ví dụ thứ hai của tôi.
-codec:v libx264
? Có thể ffmpeg
chỉ sử dụng cùng một mã hóa mà không cần người dùng cố gắng tìm ra nó?
FFMPEG đã thay đổi hành vi mặc định để tự động xoay các nguồn video đầu vào với siêu dữ liệu "xoay" trong phiên bản v2.7 năm 2015 .
Nếu bạn biết tập lệnh hoặc lệnh của bạn sẽ không bao giờ chạy trên các bản phát hành ffmpeg cũ hơn 2.7, giải pháp đơn giản nhất là xóa mọi xoay vòng tùy chỉnh dựa trên siêu dữ liệu.
Đối với các trường hợp khác, bạn có thể chứng minh trong tương lai bằng cách giữ mã xoay tùy chỉnh và thêm -noautorotate
cờ (điều này được hỗ trợ trong các phiên bản cũ hơn vẫn được duy trì tại thời điểm đó).
Trình phát phương tiện sử dụng ffmpeg làm phụ trợ giải mã cũng có thể sử dụng tất cả các bộ lọc của nó. Xem ảnh chụp màn hình này với bộ lọc "Offset & flip".
Ngoài ra, nếu bạn muốn mã hóa lại video của mình, hãy xem Xoay video với FFmpeg trên Stackoverflow.
transpose
bộ lọc được tham chiếu trong Xoay video với FFmpeg sẽ không xoay 180 ° như tôi có thể nói.
transpose
bộ lọc lại với nhau để đạt được hiệu quả.
Sau đây là một tập lệnh bash sẽ xuất ra các tệp có cấu trúc thư mục trong "fixedFiles". Nó biến đổi và quay video iOS và chuyển mã AVI. Kịch bản dựa trên việc đã cài đặt cả exiftool và 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
Tôi đã được yêu cầu chỉnh sửa điều này, để mở đầu văn bản, chỉ ra giải pháp cuối cùng tôi tìm thấy là ở cuối văn bản. Vì vậy, cuối cùng, bạn sẽ tìm thấy hai lệnh ffmpeg liên tiếp đã xoay thành công video của tôi theo đúng hướng. Văn bản trước đó có nghĩa là cung cấp càng nhiều thông tin càng tốt, vì tôi đã thấy các tin nhắn khác bị từ chối vì thiếu thông tin. Dù sao, tôi hy vọng điều này sẽ giúp những người khác sử dụng ffmpeg. Dường như với tôi mục đích của hflip và vflip trong ffmpeg, ở mức tối thiểu, khó hiểu và trái với những gì tôi mong đợi.
Tệp merlin.mov là bản sao của video tôi đã quay trên iphone, đầu tiên được tải lên Dropbox, sau đó được tải xuống máy tính xách tay của tôi, chạy 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
Tôi biết rằng tôi đã có thể gắn iphone của mình qua USB và sao chép các tệp trực tiếp, nhưng điều đó không hiệu quả; máy tính xách tay của tôi sẽ nhận ra iphone đã được kết nối, nhưng sẽ không gắn hệ thống tập tin của nó và tôi không nhận được lời nhắc nào trên iphone để "tin tưởng" máy tính xách tay.
Lệnh tôi đã sử dụng để sao chép từ Dropbox vào máy tính xách tay của mình là:
cp ~/Dropbox/Camera\ Uploads/Video\ Nov\ 02\,\ 9\ 41\ 55\ AM.mov \
merlin.mov
Tệp gốc là Video 1920 x 1080 Codec HEVC / H.265 Tốc độ khung hình 30 / giây, Bitrate 8140 kbps, Audio Codec MPEG-4 AAC kênh Âm thanh stereo, Tốc độ mẫu 44100 Hz, Tốc độ bit 85 kbps. Khi tôi phát nó trên iphone, nó được định hướng đúng và âm thanh được đồng bộ hóa. Khi tôi phát nó trong Video trên máy tính xách tay của mình, cả hai đều lộn ngược và đảo ngược theo chiều ngang và âm thanh không được đồng bộ hóa. Đây là một phần đầu ra từ "ffmpeg -i merlin.mov":
Metadata:
rotate : 180
creation_time : 2017-11-02T14:41:55.000000Z
handler_name : Core Media Data Handler
encoder : HEVC
Đây là dòng đầu ra đầu tiên từ "ffmpeg -version":
phiên bản ffmpeg 3.3.3 Bản quyền (c) 2000-2017 các nhà phát triển FFmpeg
Sau đây, phát lại đảo ngược cả theo chiều dọc và chiều ngang, mặc dù nó đã chuyển đổi thành video MPEG-4 (video / mp4) và đồng bộ hóa âm thanh:
ffmpeg -i merlin.mov -vf 'hflip,vflip' merlinhflipvflip.mp4
Đoạn sau được đảo ngược theo chiều dọc để phát lại thẳng đứng, đồng bộ hóa âm thanh và được chuyển đổi thành MPEG-4, nhưng lại kết thúc lật không chính xác theo chiều ngang cho đến hết (đây không phải là lỗi chính tả, tôi đã chỉ định 'hflip'):
ffmpeg -i merlin.mov -vf 'hflip' merlinhflip.mp4
Sau đây lật ngang theo hướng chính xác, nhưng để phát lại lộn ngược:
ffmpeg -i merlin.mov -vf 'vflip' merlinvflip.mp4
Những điều sau đây dường như không có tác dụng gì:
ffmpeg -i merlin.mov -vf 'hflip' merlinhflip.mp4
ffmpeg -i merlinhflip.mp4 -vf 'vflip' merlin2stepA.mp4
Tôi cũng đã thử điều này, dựa trên một lệnh tôi tìm thấy tại superuser.com. Nó đã đồng bộ hóa thành công âm thanh và chuyển đổi thành MPEG-4, nhưng cả hai chiều ngang và dọc vẫn không chính xác:
ffmpeg -i merlin.mov \
-vf "rotate=PI:bilinear=0,format=yuv420p" \
-metadata:s:v rotate=0 -codec:v libx264 \
-codec:a copy merlinrotate.mp4
Tôi cũng đã thử cách này, nó không hoạt động về mặt điều chỉnh hướng:
ffmpeg -noautorotate -i merlin.mov merlinnoautorotate.mp4
Quá trình 2 bước sau đây cuối cùng đã có được điều tôi muốn; dọc và ngang cả lật, đồng bộ hóa âm thanh và định dạng được chuyển đổi thành MPEG-4 (Một lần nữa, đây không phải là lỗi chính tả; Tôi đã sử dụng hflip trong cả hai lệnh):
ffmpeg -i merlin.mov -vf 'hflip' merlinhflip.mp4
ffmpeg -i merlinhflip.mp4 -vf 'hflip' merlin2stepB.mp4
Dưới đây là các bước:
Đầu tiên hãy mở tập tin video của bạn trong QuickTime. Trước tiên, bạn có thể kích hoạt chương trình QuickTime, chuyển đến tập tin của tập tin và sau đó chuyển xuống tập tin mở tập tin. Hoặc bạn có thể nhấp chuột phải vào chính tập tin đó, chọn Mở Open Với, và sau đó chọn QuickTime.
Khi video được mở, nhấp vào Chỉnh sửa Chỉnh sửa và sau đó bạn sẽ tìm thấy các tùy chọn xoay và lật ngay bên dưới
Khi bạn đã khóa hướng bạn muốn, sau đó bạn phải xuất video của mình với những thay đổi mới mà bạn đã thêm. Bạn sẽ tìm thấy tùy chọn Xuất xuất trực tuyến trên menu Menu File File trong QuickTime.
Chọn cài đặt tệp bạn muốn xuất và nhấp vào Ok Ok, để bắt đầu xuất.
Khi thao tác xuất hoàn tất, bạn sẽ tìm thấy tệp mới của mình ở bất kỳ nơi nào bạn chọn để lưu tệp với hướng chính xác!
Toàn bộ sửa chữa này chỉ mất chưa đầy 5 phút để hoàn thành, nhưng tùy thuộc vào độ dài của video, có thể mất nhiều thời gian hơn (hoặc ngắn hơn, một lần nữa, nó sẽ thay đổi).