如何使用moviepy找到视频旋转并相应地旋转剪辑?

时间:2016-12-17 15:14:17

标签: python video ffmpeg rotation moviepy

我使用moviepy导入一些视频,但是应该处于纵向模式的视频是横向导入的。我需要检查旋转是否已经改变,如果有,则将其旋转回来。

这个功能是否内置于moviepy中?如果没有,我还能检查它吗?

1 个答案:

答案 0 :(得分:3)

我现在已经找到了问题的解决方案。

由于某些原因,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
    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

这将调用ffprobe命令ffprobe -loglevel error -select_streams v:0 -show_entries stream_tags=rotate -of default=nw=1:nk=1 your_file_name.mp4,然后返回该文件的循环元数据。

然后调用以下调用上述函数的函数,并旋转传递给它的剪辑。请注意,参数clip是一个电影VideoFileClip对象,参数file_pathclip所在文件的完整路径(例如file_path可能是/usr/local/documents/mymovie.mp3 })

from moviepy 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