如何找到视频旋转并使用 moviepy 相应地旋转剪辑?
How can I find video rotation and rotate the clip accordingly using moviepy?
我正在使用 moviepy 导入一些视频,但是应该是纵向模式的视频却被横向导入了。我需要检查旋转是否已更改,如果已更改,则将其旋转回去。
moviepy 是否内置了此功能?如果没有,我还能如何检查?
我现在已经找到了问题的解决方案。
Moviepy,出于某种原因,在导入视频时会将纵向视频旋转为横向。为了自动将它们导回,您需要找到记录其旋转的视频元数据,然后根据需要旋转视频。我这样做的方法是使用 ffprobe,可以使用 this youtube 教程为 windows 安装它。请注意,您需要删除 ffmpeg/bin 中的 ffmpeg.exe 文件,因为您只需要 ffprobe.exe。如果你不删除 ffmpeg.exe,moviepy 将使用那个而不是它应该使用的那个。这导致我的系统出现一些奇怪的问题。
安装 ffprobe 后,您可以 运行 对每个导入的视频执行以下 python 功能:
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
whosebug.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
这会调用 ffprobe 命令 ffprobe -loglevel error -select_streams v:0 -show_entries stream_tags=rotate -of default=nw=1:nk=1 your_file_name.mp4
,然后 returns 该文件的旋转元数据。
然后调用调用上述函数的以下函数,并旋转您传递给它的剪辑。请注意,参数 clip
是电影 VideoFileClip 对象,参数 file_path
是 clip
所在文件的完整路径(例如 file_path
可能是 /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
我正在使用 moviepy 导入一些视频,但是应该是纵向模式的视频却被横向导入了。我需要检查旋转是否已更改,如果已更改,则将其旋转回去。
moviepy 是否内置了此功能?如果没有,我还能如何检查?
我现在已经找到了问题的解决方案。
Moviepy,出于某种原因,在导入视频时会将纵向视频旋转为横向。为了自动将它们导回,您需要找到记录其旋转的视频元数据,然后根据需要旋转视频。我这样做的方法是使用 ffprobe,可以使用 this youtube 教程为 windows 安装它。请注意,您需要删除 ffmpeg/bin 中的 ffmpeg.exe 文件,因为您只需要 ffprobe.exe。如果你不删除 ffmpeg.exe,moviepy 将使用那个而不是它应该使用的那个。这导致我的系统出现一些奇怪的问题。
安装 ffprobe 后,您可以 运行 对每个导入的视频执行以下 python 功能:
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
whosebug.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
这会调用 ffprobe 命令 ffprobe -loglevel error -select_streams v:0 -show_entries stream_tags=rotate -of default=nw=1:nk=1 your_file_name.mp4
,然后 returns 该文件的旋转元数据。
然后调用调用上述函数的以下函数,并旋转您传递给它的剪辑。请注意,参数 clip
是电影 VideoFileClip 对象,参数 file_path
是 clip
所在文件的完整路径(例如 file_path
可能是 /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