使用FFMpeg及Python进行视频裁剪

最近追剧《风筝》,从某管下载的视频,前后有不低于1分钟的片头和片尾,片头更是达到了2分40秒,又懒得每次遥控下一个文件,干脆写个脚本裁剪片头和片尾。

注意事项: 1、文件名不能含有空格,含有空格的文件需要预先处理。原文件名称为风筝 _ Kite 29【DVD版】(柳雲龍、羅海瓊、李小冉等主演).mp4,可以使用下列脚本进行批量重命名:

1
2
3
4
5

files = [f for f in os.listdir('.') if f.startswith('风筝') and f.endswith('.mp4')]
for f in files:
os.rename(f,"{}_{}.mp4".format(f[:2],f[10:12]))

注:下面的脚本中已经包含上述处理步骤。

2、系统中需要有ffmpeg,下载地址在这里下载FFMpeg,对于绿色版,请预先设置好环境变量。

新文件在上一级目录保存,转换完成后,可以删除原文件,如果懒得可以,可以直接在脚本中删除。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#!/usr/bin/python3
# -*- coding: utf-8 -*-


import subprocess
import shlex
import os

def runCommand(cmd):
output = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE, stderr = subprocess.STDOUT)
#rst = output.stdout.read().decode("UTF8").strip()
rst = output.stdout.readlines()#.decode("UTF8").strip()

return rst

def processVideoStripCmd():
def secondsToString(seconds):
strSeconds = []
strSeconds.append(seconds//3600)
strSeconds.append((seconds-strSeconds[0]*3600)//60)
strSeconds.append(seconds%60)
strSeconds = list(map(lambda x :str.format('{:02d}',x),strSeconds))
strSeconds = ":".join(strSeconds)
return strSeconds

timeFromBegin = 160 # 距离文件开始起始时间
timeToEOF =90 # 距离文件结束截止时间

files = [f for f in os.listdir('.') if f.startswith('old_风筝') and f.endswith('.mp4')]
for f in files:
print("----\n",f)
cmd = 'ffprobe "{}"'.format(f)
rst = runCommand(cmd)
rst = [r.decode("UTF8").strip() for r in rst if "Duration" in r.decode("UTF8").strip()]
#print(len(rst))
duration = ""
validDura = 0
if len(rst)>0:
start = len('Duration: ')
duration=rst[0][start:start+8]
t = list(map(int,duration.split(':')))
v = t[0]*3600+t[1]*60+t[2]
v = v-timeFromBegin #开头
v = v-timeToEOF #结尾
validDura = secondsToString(v)
print("\t 总时长:{}, 有效时长:{}".format(duration,validDura))

cmd = 'ffmpeg -ss {} -i "{}" -t {} -vcodec copy -acodec copy "../{}"'.format(secondsToString(timeFromBegin),f,validDura,f[4:])
print(cmd)
rst = runCommand(cmd)
rst = [ r.decode("UTF8").strip() for r in rst]
os.remove(f)
#print("\n".join(rst))
print('共处理{}个文件'.format(len(files)))

if __name__ == "__main__":

files = [f for f in os.listdir('.') if f.startswith('风筝') and f.endswith('.mp4')]
for f in files:
os.rename(f,"old_{}_{}.mp4".format(f[:2],f[10:12]))

result = processVideoStripCmd()