github email
使用moviepy进行电影剪辑

使用moviepy进行电影剪辑

退一步,海阔天空!

有个执念,总想比一下到底谁最快,python/c#/go/rust/java。但是,现实告诉我,谁能快速的解决问题,就够了。

最近,老婆的工作要进行视频剪辑,老师推荐了剪影,可是呢?有水印,要充VIP,我一看,就答应了帮老婆来干这个事情。满怀信心的打开PR,发现自己已经不会用了。🤣这可咋办呢?问了一下文心一言,在chatGPT3.5还没有免费的时候,文心一言还是比较好用的。文心一言告诉我有个moviepy的库,好的用一下。

以下是文心一言给的代码,蛮不错。

from moviepy.editor import VideoFileClip  
  
# 加载视频文件  
clip = VideoFileClip("my_video.mp4")  
  
# 剪辑视频,从第10秒到第20秒  
subclip = clip.subclip(10, 20)  
  
# 写入剪辑后的视频文件  
subclip.write_videofile("my_subclip.mp4")

用下来,每次都要自己算一下时间,所以自己又写了一个。

from moviepy.editor import VideoFileClip  
  
# 加载视频文件  
video = VideoFileClip("demo.mp4")  
  
# 剪辑视频,设置开始和结束时间(单位为秒)  
# 这里假设我们想要剪辑从第5秒到第15秒的部分
# 16:40 ~ 21:21 
# 24:30 ~ 26:00
# 33:00 ~ 33:47
# 39:00~ 43:00
# 47:30 ~ 57:00
# 58:10 ~ 1:00:02
# 1:04:40 ~ 1:07:10
# 1:13:00 ~ 1:18:42
# 1:19:18 ~ 1:23:40
s_h = 1
s_min = 19
s_sec = 18

e_h = 1
e_min = 23
e_sec = 40

start_time = s_h * 60 * 60 + s_min * 60 + s_sec
end_time = e_h * 60 * 60 + e_min * 60 + e_sec
#print( 'Start time :',start_time)
#print( 'End time :',end_time)
subclip = video.subclip(start_time, end_time)  
  
# 写入剪辑后的视频到新的文件  
subclip.write_videofile("output_08.mp4", codec='libx264')

基本上可以和视频时间一致,可是呢?转化的过程中电脑在怒吼,电池下降很快,最主要的就是慢。但是,可用,而且满足需求,在没有时间的情况下,勉强完成工作。

今天“闲来无事”,去moviepy的官网看了一下,发现有许多的功能可以用哦。但是,也告诉我,如果只是剪辑视频的话,还是推荐ffmpeg使用。好奇的我,尝试了一下昨天的视频,发现的确很快,而且电脑很安静。

使用c#代码调用,chatGPT提供。

using System;
using System.Diagnostics;

// 输入视频文件路径和输出视频文件路径
string inputVideoPath = "/Volumes/Transcend/download/bobi.mp4";
string outputVideoPath = "output_video.mp4";

// 剪辑的起始时间和结束时间(单位:秒)

int s_hour = 1;
int s_min = 19;
int s_sec = 18;

int e_hour = 1;
int e_min = 23;
int e_sec = 40;


int startTime = s_hour * 60 * 60 + s_min * 60 + s_sec;
int endTime = e_hour * 60 * 60 + e_min * 60 + e_sec;

// 构造FFmpeg命令
string ffmpegArgs = $"-i \"{inputVideoPath}\" -ss {startTime} -to {endTime} -c copy \"{outputVideoPath}\"";

// 调用FFmpeg命令
Process ffmpegProcess = new Process();
ffmpegProcess.StartInfo.FileName = "ffmpeg";
ffmpegProcess.StartInfo.Arguments = ffmpegArgs;
ffmpegProcess.StartInfo.UseShellExecute = false;
ffmpegProcess.StartInfo.RedirectStandardOutput = true;
ffmpegProcess.StartInfo.RedirectStandardError = true;

ffmpegProcess.Start();
ffmpegProcess.WaitForExit();

// 输出FFmpeg命令的输出和错误信息
string output = ffmpegProcess.StandardOutput.ReadToEnd();
string error = ffmpegProcess.StandardError.ReadToEnd();

Console.WriteLine("Output:");
Console.WriteLine(output);
Console.WriteLine("Error:");
Console.WriteLine(error); 
time dotnet run
dotnet run  8.92s user 4.18s system 43% cpu 29.978 total

我使用了原来的moviepy的代码,速度如下:

time python cute_test.py
python cute_test.py  480.43s user 19.80s system 248% cpu 3:21.37 total

我原本想用go/rust/java都写一遍的时候,在发现我其实不就是调用一下ffmpeg嘛,核心都是ffmpeg。所以我放弃了,我用python再使用了一遍。

import subprocess

def clip_video(input_file, output_file, start_time, end_time):
    # 构造FFmpeg命令
    ffmpeg_args = [
        'ffmpeg', 
        '-i', input_file, 
        '-ss', start_time, 
        '-to', end_time, 
        '-c', 'copy', 
        output_file
    ]

    # 调用FFmpeg命令
    subprocess.run(ffmpeg_args)

# 输入视频文件路径和输出视频文件路径
input_video_path = "/Volumes/Transcend/download/bobi.mp4"
output_video_path = "output_video.mp4"

# 剪辑的起始时间和结束时间(单位:秒)
start_time = "01:19:18"  # 从第10秒开始剪辑
end_time = "02:23:40"    # 剪辑到第30秒结束

# 执行视频剪辑操作
clip_video(input_video_path, output_video_path, start_time, end_time)

print("视频剪辑完成!")
time python cut_call_ffmepg.py
python cut_call_ffmepg.py  6.69s user 4.12s system 30% cpu 35.530 total

速度上已经没有什么优势了,前提是用moviepy,还是ffmepg。

所以,好比数学题一样,有多种解法,已先完成作业为主,后续在多思考一下,就可以得出一个最优解。

真的是,学海无涯苦作舟。