10

I have approximately 3000 short video clips, each about 3 seconds in duration. I need to rotate each of them 90 degrees. What is the best way to do this? I have Adobe Creative Cloud subscription, as well as access to both Windows and Mac machines. Looking for the easiest solution to automate/batch process the rotation of so many videos.

If you were wondering - the videos are part of an e-learning course on lumber. The learner views each randomly selected video, which is just a short clip of a piece of lumber rotating. The videos were shot so that the lumber (2x4s, etc.) were horizontal. But now the client wants the lumber to be vertical in the clips.

3
  • Only rotation? From e.g. 1280x720 to 720x1280 right?
    – p2or
    Apr 22, 2015 at 12:11
  • Just rotation 90 degrees clockwise (or counter cw - doesn't matter for this project).
    – user172586
    Apr 22, 2015 at 15:49
  • Does the container of your video files includes an 'orientation' metadata ?
    – audionuma
    Apr 23, 2015 at 8:41

4 Answers 4

11

Use ffmpeg and the "transpose" filter as "poor" suggested. For example, if your files are mp4 and are in the current directory:

mkdir -p rotated
for f in *.mp4; do ffmpeg -i "$f" -vf transpose=2 -c:a copy -metadata:s:v rotate="" rotated/"$f"; done
  • The transpose value can be "1" or "clock" for clockwise rotation, "2" or "cclock" for counter-clockwise rotation. There are other values which will also apply a flip.

  • The audio will be stream copied to avoid unnecessary re-encoding.

  • The video stream rotation metadata is cleared in this example. Otherwise ffmpeg will copy it from the input to the output resulting in an incorrect rotation for players that pay attention to this metadata (some do, and some don't).

Another example, more verbose and flexible, and which keeps the rotated file in the same directory with a new name:

ext=mp4
for f in /some/dir/*.$ext; do
    new=${f/%.$ext/-rotated.$ext};
    ffmpeg -i "$f" -vf transpose=2 -c:a copy -metadata:s:v rotate="" "$new"
done
1
  • Yes! I should learn more about bash scripting :)
    – p2or
    Apr 24, 2015 at 18:57
1

You have specified that you are interested in working on a huge number of videos, if you have a multicore machine and you will use a normal for loop provided by your shell, you will have one of your cores running hot, while others are doing absolutely nothing. This is not ideal.

What you should be doing for such a job is using parallel, a tool that allows you to start several jobs at once, and it can do everything that a for-loop can, but better.

I will not write about all the features of this tool, but will concentrate on your specific task.

One way to start all these jobs would be:

parallel avconv -i "{}" -vf transpose=2 "{.}[rotated].mp4" ::: *.mp4

In here {} replaces each filename, and {.} replaces filename without an extension.

I will suggest that you will start as many jobs as you have cores, take away one. The reason for that is so your operating system will still remain useable, and also this will save you in case if you are using harddisk encryption (which will be using processing power to read/write data). To do this simply add --jobs -1 to your command line, and you will limit the number of jobs.

parallel --jobs -1 avconv -i "{}" -vf transpose=2 "{.}[rotated].mp4" ::: *.mp4

Please keep in mind that no output will be given until each encoding completes. So you will not see just how much of each of your video is done.

1

Based on this answer you can use ffmpeg with following commands to rotate a video:

ffmpeg -i input -vf transpose=2 output

To Batch process a folder of movies you can use a programming language of your choice and iterate through the files. I've used linux with python 2.7+ here. You only have to edit folder_movies path, path_to_ffmpeg and set your movie extension:

import os # import os module
import subprocess # import subprocess module

# set the path to your video folder
folder_movies = '/home/user/Desktop/test/'

# set ffmpeg path
path_to_ffmpeg = "/opt/ffmpeg/ffmpeg"

# set file extension
ext = ".mp4"

# collect all videos in folder_movies
movie_files = [f for f in os.listdir(folder_movies) if f.endswith(ext)] 

# iterate through the files
for i in movie_files:

    # setup correct filepath for mov's
    file_path = os.path.join(folder_movies,i)

    # generate new file path
    new_path = os.path.splitext(file_path)[0] + '_rotated_90' + ext

    # call ffmpeg with the correct arguments
    # command: ffmpeg -i input -vf transpose=2 output
    subprocess.call([path_to_ffmpeg, "-i",  file_path, "-vf", "transpose=2", "-c:a", "copy", new_path])

Afterwards your movie folder should looks like:

enter image description here

The advantage of using python is that the code runs cross platform. The only thing you need to consider are the paths to the directory and the ffmpeg executable. In order to run this on a windows machine you only have to replace the paths to something like:

# folder_movies = '/home/user/Desktop/test/' # linux or osx
folder_movies = r'c:\some\directory\test'    # windows, the r is important
folder_movies = 'c:/some/directory\test'     # windows (alternative)

# path_to_ffmpeg = '/opt/ffmpeg/ffmpeg'            # linux or osx
path_to_ffmpeg = r'c:\Program Files\ffmpeg\ffmpeg' # windows, the r is important
path_to_ffmpeg = 'c:/Program Files/ffmpeg\ffmpeg'  # windows (alternative)

Note: I'm not a ffmpeg expert, maybe there is a way to batch process with it directly.

6
  • 1
    You don't really need a whole script for this. It can be done directly on the Mac or Linux command-line with something like : mkdir -p rotated; for f in *.mp4; do ffmpeg -i "$f" -vf transpose=2 rotated/"$f"; done (assuming your video files are .mp4 in this example).
    – mivk
    Apr 23, 2015 at 17:48
  • @mivk nice, why not converting this to an answer?
    – p2or
    Apr 24, 2015 at 7:17
  • @mivk Since you are using a for loop it's nearly the same. For those who don't use linux or osx, it makes sense to use python or another scripting language.
    – p2or
    Jun 5, 2015 at 11:54
  • @poor : well, for those users who are neither on linux nor on mac, the translation into PowerShell is "left as an exercise for the reader"... :-)
    – mivk
    Jun 5, 2015 at 16:51
  • 1
    @mivk : Well, I had to, so here's the implementation for powershell. Get-ChildItem "." -Filter *.mp4 | Foreach-Object { ffmpeg.exe -i "$_" -vf transpose=2 -c:a copy -metadata:s:v rotate="" rotated/"$_" }
    – PvB
    Oct 2, 2017 at 19:53
0

This worked for me. create a batch file. Make a directory called output in your videos directory. Also put a copy of ffmpeg.exe in the directory. You can get ffmpeg download with google. it is a zip file, you just need ffmpeg.exe.

Run the batch file and wait.

for %%a in ("*.mp4") do ffmpeg -i "%%a" -vf transpose=2 -c:a copy -metadata:s:v rotate="" "output\%%~na.mp4"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.