1

我编写了一个 MoviePy 脚本,它接受输入视频,进行一些处理,然后输出一个视频文件。我想通过整个视频文件夹运行它。任何帮助或方向表示赞赏。

这是我尝试过的...

for f in *; do python resize.py $f; done

和 resize.py 源代码在这里:

from moviepy.editor import *

clip = VideoFileClip(input)

clip1 = clip.rotate(270)

clip2 = clip1.crop(x_center=540,y_center=960,width=1080,height=608)

clip3 = clip2.resize(width=1920)

clip3.write_videofile(output,codec='libx264')

真的不确定在我的 .py 文件中为“输入”和“输出”添加什么内容。

谢谢,埃文

4

2 回答 2

3

我知道你在 Github 上有答案,但我会添加我自己的解决方案。

首先,您需要将代码放入函数中:

def process_video(input):
    """Parameter input should be a string with the full path for a video"""

    clip = VideoFileClip(input, output)

    clip1 = clip.rotate(270)

    clip2 = clip1.crop(x_center=540,y_center=960,width=1080,height=608)

    clip3 = clip2.resize(width=1920)

    clip3.write_videofile(output,codec='libx264')

然后,您可以拥有一个返回文件路径列表的函数,以及与上述函数一起使用的最终文件名列表(请注意,最终文件名将与原始文件名相同,但在正面):

import os
def get_video_paths(folder_path):
    """ 
    Parameter folder_path should look like "Users/documents/folder1/"
    Returns a list of complete paths
    """
    file_name_list = os.listdir(folder_path)

    path_name_list = []
    final_name_list = []
    for name in file_name_list:
        # Put any sanity checks here, e.g.:
        if name == ".DS_Store":
            pass
        else:
            path_name_list.append(folder_path + name)
            # Change the format of the output file names below
            final_name_list.append(folder_path + "output" + name)  
    return path_name_list, final_name_list

最后,在底部,我们得到输入文件夹,并利用上述两个函数:

if __name__ == "__main__":
    video_folder = input("What folder would you like to process? ")
    path_list, final_name_list = get_video_paths(video_folder)
    for path, name in zip(path_list, final_name_list):
        process_video(path, name)
    print("Finished")

请注意,因为如果文件夹中有任何不能作为电影读取的文件,这将崩溃。例如,在 Mac 上,操作系统会在每个文件夹中放置一个“.DS_Store”文件,这会使程序崩溃。我已经设置了一个区域进行完整性检查以忽略某些文件名。

完整代码:

import os

from moviepy.editor import *


def process_video(input, output):
    """Parameter input should be a string with the full path for a video"""

    clip = VideoFileClip(input)

    clip1 = clip.rotate(270)

    clip2 = clip1.crop(x_center=540,y_center=960,width=1080,height=608)

    clip3 = clip2.resize(width=1920)

    clip3.write_videofile(output,codec='libx264')


def get_video_paths(folder_path):
    """ 
    Parameter folder_path should look like "Users/documents/folder1/"
    Returns a list of complete paths
    """
    file_name_list = os.listdir(folder_path)

    path_name_list = []
    final_name_list = []
    for name in file_name_list:
        # Put any sanity checks here, e.g.:
        if name == ".DS_Store":
            pass
        else:
            path_name_list.append(folder_path + name)
            final_name_list.append(folder_path + "output" + name)
    return path_name_list, final_name_list

if __name__ == "__main__":
    video_folder = input("What folder would you like to process? ")
    path_list, final_name_list = get_video_paths(video_folder)
    for path, name in zip(path_list, final_name_list):
        process_video(path, name)
    print("Finished")
于 2017-04-13T09:07:28.223 回答
0

我在您的Github 问题 #542上做出了回应,但我将其复制在这里以供将来参考!

首先,下面的例子不是铁定的,但它应该做你需要的。您可以通过以下方式实现此目的:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Convert all media assets located in a specified directory."""
import glob
import os
from optparse import OptionParser

from moviepy.editor import VideoFileClip


def get_dir_files(dir_path, patterns=None):
    """Get all absolute paths for pattern matched files in a directory.

    Args:
        dir_path (str): The path to of the directory containing media assets.
        patterns (list of str): The list of patterns/file extensions to match.

    Returns:
        (list of str): A list of all pattern-matched files in a directory.
    """
    if not patterns or type(patterns) != list:
        print('No patterns list passed to get_dir_files, defaulting to patterns.')
        patterns = ['*.mp4', '*.avi', '*.mov', '*.flv']

    files = []
    for pattern in patterns:
        dir_path = os.path.abspath(dir_path) + '/' + pattern
        files.extend(glob.glob(dir_path))

    return files

def modify_clip(path, output):
    """Handle conversion of a video file.

    Args:
        path (str): The path to the directory of video files to be converted.
        output (str): The filename to associate with the converted file.
    """
    clip = VideoFileClip(path)
    clip = clip.rotate(270)
    clip = clip.crop(x_center=540, y_center=960, width=1080, height=608)
    clip = clip.resize(width=1920)

    clip.write_videofile(output, codec='libx264')
    print('File: {} should have been created.'.format(output))


if __name__ == '__main__':
    status = 'Failed!'
    parser = OptionParser(version='%prog 1.0.0')
    parser.add_option('-p', '--path', action='store', dest='dir_path',
                      default='.', type='string',
                      help='the path of the directory of assets, defaults to .')

    options, args = parser.parse_args()
    print('Running against directory path: {}'.format(options.dir_path))
    path_correct = raw_input('Is that correct?').lower()

    if path_correct.startswith('y'):
        dir_paths = get_dir_files(options.dir_path)
        for dir_path in dir_paths:
            output_filename = 'converted_' + os.path.basename(dir_path)
            modify_clip(path=dir_path, output=output_filename)

        status = 'Successful!'

    print('Conversion {}'.format(status))

使用上面的示例,您可以简单地将其放入您希望转换和运行的资产目录中:python this_file.py它应该为您在同一目录中转换文件,名称前加:converted_

同样,您可以将该文件放在任何地方并针对绝对路径运行它: python this_file.py -p /Users/thisguy/media它将转换所有带有扩展名的文件:['*.mp4', '*.avi', '*.mov', '*.flv']

无论哪种方式,如果您有任何问题(或者这是否解决了您的问题),请告诉我,我会尽力帮助您!

感谢您使用电影!

于 2017-04-13T11:09:38.040 回答