I'm using moviepy to import some videos, but the videos that should be in portrait mode are imported in landscape. I need to check whether the rotation has been changed, and if it has, rotate it back.
Is this functionality built into moviepy? If not, how else can I check it?
I have now worked out a solution to the question.
Moviepy, for some reason, rotates portrait videos to landscape when it imports them. In order to automatically import them back, you need to find the video metadata that records its rotation, then rotate the video as needed. The way I did this is with ffprobe, which can be installed for windows using this youtube tutorial. Note that you will need to delete the ffmpeg.exe file in ffmpeg/bin, as you only need ffprobe.exe. If you don't delete ffmpeg.exe, moviepy will use that one instead of the one it is supposed to be using. This led to some strange problems on my system.
Once ffprobe is installed, you can run the following python function for each video being imported:
import subprocess
import shlex
import json
def get_rotation(file_path_with_file_name):
"""
Function to get the rotation of the input video file.
Adapted from gist.github.com/oldo/dc7ee7f28851922cca09/revisions using the ffprobe comamand by Lord Neckbeard from
stackoverflow.com/questions/5287603/how-to-extract-orientation-information-from-videos?noredirect=1&lq=1
Returns a rotation None, 90, 180 or 270
"""
cmd = "ffprobe -loglevel error -select_streams v:0 -show_entries stream_tags=rotate -of default=nw=1:nk=1"
args = shlex.split(cmd)
args.append(file_path_with_file_name)
# run the ffprobe process, decode stdout into utf-8 & convert to JSON
ffprobe_output = subprocess.check_output(args).decode('utf-8')
if len(ffprobe_output) > 0: # Output of cmdis None if it should be 0
ffprobe_output = json.loads(ffprobe_output)
rotation = ffprobe_output
else:
rotation = 0
return rotation
This calls the ffprobe command ffprobe -loglevel error -select_streams v:0 -show_entries stream_tags=rotate -of default=nw=1:nk=1 your_file_name.mp4, then returns the rotation metadata for that file.
Then call the following function which calls the above function, and rotates the clip you pass to it. Note that the argument clip is a movie VideoFileClip object, and the argument file_path is the complete path to the file that clip is (e.g. file_path could be /usr/local/documents/mymovie.mp3)
from moviepy.editor import *
def rotate_and_resize(clip, file_path):
rotation = get_rotation(file_path)
if rotation == 90: # If video is in portrait
clip = vfx.rotate(clip, -90)
elif rotation == 270: # Moviepy can only cope with 90, -90, and 180 degree turns
clip = vfx.rotate(clip, 90) # Moviepy can only cope with 90, -90, and 180 degree turns
elif rotation == 180:
clip = vfx.rotate(clip, 180)
clip = clip.resize(height=720) # You may want this line, but it is not necessary
return clip
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With