8

If I use:

ffmpeg -i in.mov -vf "transpose=1" out.mov

all .mov files are getting rotated, but what I need is to automatically detect just the rotated videos and change orientation for just those videos.

How can I automatically detect the rotation or orientation of the video during upload and rotate if needed, so that all .mov files play in the correct orientation? How can I get that metadata of current degree rotation of my video?

6 Answers 6

9

Applied to your question, in concrete terms, you can get the rotation by: ffprobe -loglevel error -select_streams v:0 -show_entries stream_tags=rotate -of default=nw=1:nk=1 -i in.mov

Legend:

-loglevel error: only show the rotate field, no other info.

-select_streams v:0: process the first video stream (ignore if multiple video streams are present)

-show_entries stream_tags=rotate: returns the rotate information from the input video

-of default=nw=1:nk=1: use default output format and don't show anything else, i.e. no-wrappers (nw) and no key (nk)

4

Use ffprobe, like this.

ffprobe -i in.mov

This should result in showing a "rotate:" field somewhere in the output if such a field is present in the file.

8
  • 1
    FFmpeg nowadays autorotates the video i.e. if a rotation tag is present, it applies the filter and resets the tag, So the exercise is moot.
    – Gyan
    Dec 5, 2016 at 20:31
  • This would be bad practice due to transcoding in the case of remultiplexing a video container file with a video stream that has a rotation flag. It is useful to know exactly what is happening to prevent transcoding. Dec 5, 2016 at 23:23
  • 1
    The autorotate does not effect if the video stream is being copied. That can be done by specifying -c:v copy
    – Gyan
    Dec 6, 2016 at 5:18
  • 1
    I guess there's some lines crossed here. We don't know if the OP's target players respect the rotation tag. In fact, if they did, there would be no need for the OP to ask the Q. The OP is permanently baking in the correct orientation using the transpose filter. To that end, transcoding is required, and my point is recent ffmpeg versions automatically take care of it.
    – Gyan
    Dec 12, 2016 at 15:01
  • 6
    So write your own answer. Dec 13, 2016 at 1:14
4

The location of orientation/rotation metadata got changed in ffmpeg from stream_tag to side_data and the name changed from 'rotate' to 'rotation'.

An updated version of @Agile Bean's would be:

fprobe -loglevel error 
-select_streams v:0 
-show_entries side_data="rotation" 
-of default=nw=1:nk=1 -i in.mov
2
  • Upvoting for the information that the structure has changed; but for me, this doesn't work either: "rotation" gives nothing. I've tried "displaymatrix", and that gives me: 00000000: 0 65536 0 00000001: -65536 0 0 00000002: 0 0 1073741824 Sep 4, 2022 at 18:40
  • 1
    Thanks, this worked for me, but I had to use -show_entries stream_side_data=rotation instead of -show_entries side_data=rotation
    – user125355
    Jan 31, 2023 at 1:43
1

For me the field was called rotation NOT rotate. The only way I could extract it was like so:

ffprobe -v quiet -select_streams v:0 -show_streams rgb.mp4 | grep -i rotation=

Which outputs, for example rotation=-180

0

Just to get this more complete, in case FFMPEG's metadata structure changed again, here's a script-suitable version of getting just the rotation value with grep and sed:

ffprobe input.mp4 2>&1 | grep rotation | sed -e 's#.*rotation of \(.*\).00 degrees#\1#'

Explanation: The info goes to stderr, hence a redirect; then grep to filter the line; and then sed with a regex group replace.

case $ROTATION in
  0) ... ;;
  90|-270) ...  ;;
  180|-180) ...  ;;
  270|-90) ...  ;;
esac
0

For those folks using python:

import ffmpeg

def get_rotation(video_file_path: str):
    try:
        # fetch video metadata
        metadata = ffmpeg.probe(video_file_path)
    except Exception as e:
        print(f'failed to read video: {video_file_path}\n'
              f'{e}\n',
              end='',
              flush=True)
        return None
    # extract rotate info from metadata
    video_stream = next((stream for stream in metadata['streams'] if stream['codec_type'] == 'video'), None)
    rotation = int(video_stream.get('tags', {}).get('rotate', 0))
    # extract rotation info from side_data_list, popular for Iphones
    if len(video_stream.get('side_data_list', [])) != 0:
        side_data = next(iter(video_stream.get('side_data_list')))
        side_data_rotation = int(side_data.get('rotation', 0))
        if side_data_rotation != 0:
            rotation -= side_data_rotation
    return rotation

checkout this gist for details.

1
  • Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
    – Community Bot
    Nov 5, 2022 at 11:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .