python引用的su_media_util库可参考使用uTools打造方便工具流末尾链接。
1.极速生成首尾自然过渡视频,方便做成视频桌面。
原理:将视频剪切前一小段拼到视频尾部,在两段视频中键添加alpha过渡特效。
需要安装moviepy
cmd:pip install moviepy --user
from moviepy.editor import VideoFileClip,CompositeVideoClip
from su_util import su_media_util
import os
import subprocess
ffmpeg_path = '%s/%s' % (os.environ['UtoolsCoreAssets'],'ffmpeg/bin/ffmpeg.exe')
cut_time = 1
fade_time = 1
cfilepath = r'{{MatchedFiles[0].path}}'
vidoe_total_length = float(su_media_util.get_video_info(cfilepath)['duration'])
cut_length_ce = vidoe_total_length - cut_time
filename = cfilepath[cfilepath.rindex('\\')+1:len(cfilepath)]
filename_noextension = filename[0:filename.index('.')]
newfilepath = cfilepath.replace(filename_noextension,filename_noextension+'_cut_')
tempfilePrefix = 't1_cp.mp4'
tempfilepathEnd = 't1_ce.mp4'
subprocess.call([ffmpeg_path,'-y','-ss',str(cut_time),'-t',str(cut_length_ce),'-i',cfilepath,'-c:v','libx264','-c:a','aac','-strict','experimental',tempfilepathEnd])
subprocess.call([ffmpeg_path,'-y','-ss','0','-t',str(cut_time),'-i',cfilepath,'-c:v','libx264','-c:a','aac','-strict','experimental',tempfilePrefix])
#clip1 放前(长) clip2 放后(短)
clip1 = VideoFileClip(tempfilepathEnd)
clip2 = VideoFileClip(tempfilePrefix).set_start(clip1.duration-fade_time).crossfadein(fade_time)
final_clip = CompositeVideoClip([clip1,clip2])
final_clip.write_videofile(newfilepath)
print('生成成功: ' + newfilepath)
os.remove(tempfilePrefix)
os.remove(tempfilepathEnd)
2.视频快速转码截取。
支持一次多段截取。
速度较快,压缩后清晰度损失较小,剪切点比较精确。
import os
import subprocess
from su_util import su_media_util
import time
def slice_video(begin_time, end_time):
global src_video_path
begin_second = su_media_util.timestr_clock2second(begin_time)
duration = float(su_media_util.timestr_clock2second(end_time)-begin_second)
cfilepath = src_video_path
dirname = os.path.dirname(cfilepath)
filename = os.path.basename(cfilepath)
filename_noextension = os.path.splitext(filename)[0]
newfilepath = os.path.join(dirname,filename_noextension+'_cut_'+str(time.time()) + '.mp4')
print(newfilepath)
# ffmpeg -ss [start] -t [duration] -i [in].mp4 -c:v libx264 -c:a aac -strict experimental -b:a 98k [out].mp4
subprocess.call([ffmpeg_path,'-y','-ss', begin_time, '-t', str(duration), '-i',
cfilepath, '-c:v', 'libx264', '-c:a', 'aac', '-strict', 'experimental', newfilepath])
src_video_path = r'{{MatchedFiles[0].path}}'
ffmpeg_path = '%s/%s' % (os.environ['UtoolsCoreAssets'],
'ffmpeg/bin/ffmpeg.exe')
#2.5|5
cotin = 'y'
slice_info = []
print('时间格式:xx:xx:xx或则20')
while cotin == 'y':
begin_time = input('开始时间:')
end_time = input('结束时间:')
slice_info.append({'begin': begin_time, 'end': end_time})
cotin = input('是否继续添加片段?y/n default n:') or 'n'
print(slice_info)
for item in slice_info:
slice_video(item['begin'], item['end'])
3.快捷转码压制。
直接调用ffmpeg的默认转码。压缩比率较高,清晰度损失很小,速度很快。
import os
import json
import subprocess
infoStr = r'{{MatchedFiles}}'
ffmpeg_path = '%s/%s' % (os.environ['UtoolsCoreAssets'],'ffmpeg/bin/ffmpeg.exe')
infoObjects = json.loads(infoStr)
if len(infoObjects) > 0:
for finfo in infoObjects:
cfilepath = finfo['path']
filename = cfilepath[cfilepath.rindex('\\')+1:len(cfilepath)]
filename_noextension = filename[0:filename.index('.')]
newfilename = '%s_codic_.mp4' % filename_noextension
newfilepath = cfilepath.replace(filename,newfilename)
# print(newfilepath)
subprocess.call([ffmpeg_path,'-y','-i',cfilepath,newfilepath])
4.从视频快速生成gif。
与视频转码截取类似,同样支持一次多个制作,速度飞起,效果很不错。
import os
import subprocess
import time
def slice_video(begin_time, length,rate,scale,name):
global path
gif_path = '%s/%s.gif' % (os.path.dirname(path),name)
subprocess.call([ffmpeg_path, '-y', '-ss', begin_time, '-t',
length, '-i', path, '-r', rate, '-vf', scale, gif_path])
path = r'{{MatchedFiles[0].path}}'
path = path.replace('\\', '/')
ffmpeg_path = '%s/%s' % (os.environ['UtoolsCoreAssets'],
'ffmpeg/bin/ffmpeg.exe')
#2.5|5
cotin = 'y'
slice_info = []
print('时间格式:xx:xx:xx或则20')
while cotin == 'y':
begin_time = input('开始时间:') or '0'
length = input('长度:') or '5'
gif_rate = input('gif帧率(fps):') or '10'
gif_width = input('gif宽度:') or '500'
gif_filename = input('gif文件名:') or str(time.time())
scale = 'scale=%s:-1' % gif_width
slice_info.append({'begin': begin_time, 'length': length,'rate':gif_rate,'scale':scale,'name':gif_filename})
cotin = input('是否继续添加片段?y/n default n:') or 'n'
print(slice_info)
for item in slice_info:
slice_video(item['begin'], item['length'],item['rate'],item['scale'],item['name'])
5.视频按比例裁切。
自动将目标视频按最优裁剪成自定义的比例。方便做视频壁纸。
import os
import sys
import json
import subprocess
import ffmpeg
def get_video_info(in_file):
"""
获取视频基本信息
"""
try:
probe = ffmpeg.probe(in_file)
video_stream = next(
(stream for stream in probe['streams'] if stream['codec_type'] == 'video'), None)
if video_stream is None:
print('No video stream found', file=sys.stderr)
sys.exit(1)
return video_stream
except ffmpeg.Error as err:
print(str(err.stderr, encoding='utf8', errors='ignore'))
sys.exit(1)
def get_new_filepath(filepath):
filename = filepath[filepath.rindex('\\')+1:len(filepath)]
filename_noextension = filename[0:filename.index('.')]
newfilepath = filepath.replace(filename_noextension,filename_noextension+'_cut_')
print(newfilepath)
return newfilepath
def crop_video(filepath,newfilepath,targetAspectRadio=0.5625):
"""
裁剪视频
"""
global ffmpeg_path
video_info = get_video_info(filepath)
# print(video_info)
video_width = video_info['coded_width']
video_height = video_info['coded_height']
videoAspectRadio = video_height / video_width
crop_value = 'crop=100:100:0:0'
if videoAspectRadio > targetAspectRadio:
video_width-=50
target_height = int(video_width * targetAspectRadio)
crop_value = 'crop=%s:%s:%s:%s' % (video_width,target_height,0,int((video_height - target_height) * 0.5))
elif videoAspectRadio < targetAspectRadio:
video_height-=50
target_width = int(video_height / targetAspectRadio)
crop_value = 'crop=%s:%s:%s:%s' % (target_width,video_height,int((video_width - target_width) * 0.5),0)
#裁剪视频
#ffmpeg -y -i filename -strict -2 -vf crop=width:height:startX,startY fileout.mp4
subprocess.call([ffmpeg_path,'-y','-i',filepath,'-strict','-2','-vf',crop_value,newfilepath])
infoStr = r'{{MatchedFiles}}'
ffmpeg_path = '%s/%s' % (os.environ['UtoolsCoreAssets'],'ffmpeg/bin/ffmpeg.exe')
aspectStr = r'{{subinput:目标视频比例,默认9:16}}' or '9:16'
hwArr = aspectStr.split(':')
targetAspectRadio = int(hwArr[0]) / int(hwArr[1])
print(targetAspectRadio)
infoObjects = json.loads(infoStr)
for infoObject in infoObjects:
filepath = infoObject['path']
newpath = get_new_filepath(filepath)
crop_video(filepath,newpath,targetAspectRadio)
6.视频无损闪截
视频闪截不进行转码。所以无论视频怎样,截取都是瞬间完成的。
截取精度会差一些。同样支持一次截取多个片段。
import os
import subprocess
from su_util import su_media_util
import time
def slice_video(begin_time, end_time):
begin_second = su_media_util.timestr_clock2second(begin_time)
duration = float(su_media_util.timestr_clock2second(end_time)-begin_second)
cfilepath = src_video_path
filename = cfilepath[cfilepath.rindex('\\')+1:len(cfilepath)]
filename_noextension = filename[0:filename.index('.')]
newfilepath = cfilepath.replace(
filename_noextension, filename_noextension+'_cut_'+str(time.time()))
print(newfilepath)
# ffmpeg -y -accurate_seek -ss 3 -t 10 -i "E:/Video/Video of Record/Video from Recorder/Ni/Dream Date 2020-12-14 12-27-11-415.mp4" -acodec copy -vcodec copy -async 1 -avoid_negative_ts 1 "D:/aa.mp4"
subprocess.call([ffmpeg_path, '-y', '-accurate_seek', '-ss', begin_time, '-t', str(duration), '-i',
cfilepath, '-acodec', 'copy', '-vcodec', 'copy', '-async', '1', '-avoid_negative_ts', '1', newfilepath])
src_video_path = r'{{MatchedFiles[0].path}}'
ffmpeg_path = '%s/%s' % (os.environ['UtoolsCoreAssets'],
'ffmpeg/bin/ffmpeg.exe')
#2.5|5
cotin = 'y'
slice_info = []
print('时间格式:xx:xx:xx或则20')
while cotin == 'y':
begin_time = input('开始时间:')
end_time = input('结束时间:')
slice_info.append({'begin':begin_time,'end':end_time})
cotin = input('是否继续添加片段?y/n default n:') or 'n'
print(slice_info)
for item in slice_info:
slice_video(item['begin'],item['end'])
7.从视频创建字幕。
这个功能需要往工具目录里添加autosub工具。配合subedit软件,实乃字幕制作神器。
import os
import json
#字幕编辑和翻译推荐使用subtitle edit软件翻译
#subtitle edit:https://github.com/SubtitleEdit/subtitleedit/releases
#使用此功能需要先下载autosub,并将路径进行替换
#autosub:https://github.com/BingLingGroup/autosub/releases
#部分参数 英语:en-us 日语:ja-jp 中文:cmn-hans-cn 更多的请参看autosub帮助
#调用的是谷歌的服务,需要科学上网
print('英语:en-us 日语:ja-jp 中文:cmn-hans-cn 更多的请参看autosub帮助')
lan_code = input('请输入视频语言(如:en-us):')
apkinfosStr = r'{{MatchedFiles}}'
autosubPath = '%s/%s' % (os.environ['UtoolsCoreAssets'],'autosub_pyinstaller/autosub.exe')
apkobjs = json.loads(apkinfosStr)
if len(apkobjs) > 0:
for obj in apkobjs:
cmd = '%s -S %s -i "%s"' % (autosubPath,lan_code,obj['path'])
os.system(cmd)