diff --git a/.DS_Store b/.DS_Store index 558ef79..b5c08ab 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/.gitignore b/.gitignore index 894a44c..3277328 100644 --- a/.gitignore +++ b/.gitignore @@ -102,3 +102,4 @@ venv.bak/ # mypy .mypy_cache/ +.DS_Store diff --git a/EveryDay/.DS_Store b/EveryDay/.DS_Store index 57d97b7..24908e1 100644 Binary files a/EveryDay/.DS_Store and b/EveryDay/.DS_Store differ diff --git "a/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/.idea/exec_js_summary.iml" "b/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/.idea/exec_js_summary.iml" new file mode 100644 index 0000000..7c9d48f --- /dev/null +++ "b/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/.idea/exec_js_summary.iml" @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git "a/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/.idea/misc.xml" "b/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/.idea/misc.xml" new file mode 100644 index 0000000..8656114 --- /dev/null +++ "b/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/.idea/misc.xml" @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git "a/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/.idea/modules.xml" "b/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/.idea/modules.xml" new file mode 100644 index 0000000..bc1a7a0 --- /dev/null +++ "b/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/.idea/modules.xml" @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git "a/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/.idea/workspace.xml" "b/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/.idea/workspace.xml" new file mode 100644 index 0000000..94dc021 --- /dev/null +++ "b/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/.idea/workspace.xml" @@ -0,0 +1,410 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1595339185159 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + file://$PROJECT_DIR$/js2py_demo.py + 60 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git "a/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/js2py_demo.py" "b/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/js2py_demo.py" new file mode 100644 index 0000000..5d94530 --- /dev/null +++ "b/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/js2py_demo.py" @@ -0,0 +1,61 @@ +#!/usr/bin/env python +# encoding: utf-8 + +""" +@version: v1.0 +@author: xag +@license: Apache Licence +@contact: xinganguo@gmail.com +@site: http://www.xingag.top +@software: PyCharm +@file: js2py_demo.py +@time: 2020-07-22 17:49 +@description:js2py +""" + +# 依赖 +# pip3 install js2py + +import js2py + +from js_code import * + + +def test_simple(): + """ + 简单 + :return: + """ + # 将js代码转为python + add = js2py.eval_js(js_simple()) + + # 当做python函数调用 + result = add(1, 2) + + print(result) + + +def test_js_from_file(): + """ + 从文件中读取js进行执行 + :return: + """ + + # 从文件中读取js代码 + js_content = js_from_file('./norm.js') + + # 使用获取上下js2py生成一个上下文环境 + context = js2py.EvalJs() + + # 执行整段JS代码 + context.execute(js_content) + + # 使用context调用具体的函数 + result = context.add(1, 2) + + print(result) + + +if __name__ == '__main__': + # test_simple() + test_js_from_file() diff --git "a/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/js_code.py" "b/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/js_code.py" new file mode 100644 index 0000000..cd3a113 --- /dev/null +++ "b/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/js_code.py" @@ -0,0 +1,37 @@ +#!/usr/bin/env python +# encoding: utf-8 + +""" +@version: v1.0 +@author: xag +@license: Apache Licence +@contact: xinganguo@gmail.com +@site: http://www.xingag.top +@software: PyCharm +@file: js_code.py +@time: 2020-07-22 13:30 +@description:待执行的JS代码 +""" + + +def js_simple(): + """ + 返回简单的js代码 + :return: + """ + return """ + function add(num1 , num2){ + return num1 + num2; + } + """ + + +def js_from_file(file_name): + """ + 读取js文件 + :return: + """ + with open(file_name, 'r', encoding='UTF-8') as file: + result = file.read() + + return result diff --git "a/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/node_demo.py" "b/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/node_demo.py" new file mode 100644 index 0000000..31e80f0 --- /dev/null +++ "b/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/node_demo.py" @@ -0,0 +1,32 @@ +#!/usr/bin/env python +# encoding: utf-8 + +""" +@version: v1.0 +@author: xag +@license: Apache Licence +@contact: xinganguo@gmail.com +@site: http://www.xingag.top +@software: PyCharm +@file: node_demo.py +@time: 2020-07-22 22:19 +@description:使用node命令调用js +""" + +import os + + +def func1(): + # 组成调用js的命令 + cmd = 'node -e "require(\\"%s\\").init(%s,%s)"' % ('./norm1', 3, 5) + + pipeline = os.popen(cmd) + + # 读取结果 + result = pipeline.read() + + print('结果是:', result) + + +if __name__ == '__main__': + func1() diff --git "a/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/norm.js" "b/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/norm.js" new file mode 100644 index 0000000..ce69ffe --- /dev/null +++ "b/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/norm.js" @@ -0,0 +1,4 @@ +//计算两个数的和 +function add(num1, num2) { + return num1 + num2; +} diff --git "a/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/norm1.js" "b/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/norm1.js" new file mode 100644 index 0000000..b625346 --- /dev/null +++ "b/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/norm1.js" @@ -0,0 +1,10 @@ +//计算两个数的和 +function add(num1, num2) { + return num1 + num2; +} + +//新增一个导出函数(node方式) +module.exports.init = function (arg1, arg2) { + //调用函数 + console.log(add(arg1, arg2)); +}; \ No newline at end of file diff --git "a/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/py_exec_js_demo.py" "b/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/py_exec_js_demo.py" new file mode 100644 index 0000000..8b0b778 --- /dev/null +++ "b/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/py_exec_js_demo.py" @@ -0,0 +1,39 @@ +#!/usr/bin/env python +# encoding: utf-8 + +""" +@version: v1.0 +@author: xag +@license: Apache Licence +@contact: xinganguo@gmail.com +@site: http://www.xingag.top +@software: PyCharm +@file: py_exec_js_demo.py +@time: 2020-07-22 13:24 +@description:使用PyExecJS调用JS代码 +""" + +# 依赖 +# pip3 install PyExecJS + +import execjs + +from js_code import * + +# 1、简单的JS字符串 +# 编译并加载 js 文件内容,方便执行里面的方法 +context = execjs.compile(js_simple()) + +# 使用call()函数调用js内部函数 +result = context.call("add", 2, 3) + +print(result) + +# 2、js文件 +# 编译加载js字符串 +context1 = execjs.compile(js_from_file('./norm.js')) + +# 调用js代码中的add()方法,参数为2和3 +result1 = context1.call("add", 2, 3) + +print(result1) diff --git "a/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/py_v8_demo.py" "b/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/py_v8_demo.py" new file mode 100644 index 0000000..6113fe7 --- /dev/null +++ "b/Python\346\211\247\350\241\214JS\346\200\273\347\273\223/py_v8_demo.py" @@ -0,0 +1,24 @@ +#!/usr/bin/env python +# encoding: utf-8 + +""" +@version: v1.0 +@author: xag +@license: Apache Licence +@contact: xinganguo@gmail.com +@site: http://www.xingag.top +@software: PyCharm +@file: py_v8_demo.py +@time: 2020-07-22 14:53 +@description:PyV8调用JS +""" + +import PyV8 +from js_code import js_from_file + +with PyV8.JSContext() as ctx: + ctx.eval(js_from_file('./norm.js')) + +# 调用js函数,指定参数 +ctx.locals.add(1, 2) + diff --git a/README.md b/README.md index 3acf8d5..c2f7236 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ ## 文章列表 +* [制作截图快捷翻译](./截图快捷翻译) +* [朋友圈防折叠](./朋友圈防折叠/) * [批量生成手机号码](./批量生成手机号码) * [短视频二次创作](./video_auto/二次剪辑) * [使用 Python 制作 GIF 动画视频](./video_auto/制作GIF视频/) @@ -20,3 +22,9 @@ * [替换 `apk` 的资源并重新打包全解析](./android/replace_apk_resource_pro/readme.md) * [`appium` 配合压力测试 `app` 应用](./android/appium_demo/) * [每天固定时间发送天气、笑话给微信个人和群,并部署到云服务器](./EveryDay/) +* [视频特殊处理,保证唯一性](./视频特殊处理.py) +* [发送邮件的几种方式](./发送邮件) +* [Python 调用 JS 的 4 种方式](./Python执行JS总结) +* [批处理脚本](./批处理脚本) +* [生成九宫格视频+生成九宫格朋友圈图片](./图片视频九宫格/) + diff --git "a/\345\217\221\351\200\201\351\202\256\344\273\266/.idea/misc.xml" "b/\345\217\221\351\200\201\351\202\256\344\273\266/.idea/misc.xml" new file mode 100644 index 0000000..8656114 --- /dev/null +++ "b/\345\217\221\351\200\201\351\202\256\344\273\266/.idea/misc.xml" @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git "a/\345\217\221\351\200\201\351\202\256\344\273\266/.idea/modules.xml" "b/\345\217\221\351\200\201\351\202\256\344\273\266/.idea/modules.xml" new file mode 100644 index 0000000..87ce3b3 --- /dev/null +++ "b/\345\217\221\351\200\201\351\202\256\344\273\266/.idea/modules.xml" @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git "a/\345\217\221\351\200\201\351\202\256\344\273\266/.idea/vcs.xml" "b/\345\217\221\351\200\201\351\202\256\344\273\266/.idea/vcs.xml" new file mode 100644 index 0000000..c2365ab --- /dev/null +++ "b/\345\217\221\351\200\201\351\202\256\344\273\266/.idea/vcs.xml" @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git "a/\345\217\221\351\200\201\351\202\256\344\273\266/.idea/workspace.xml" "b/\345\217\221\351\200\201\351\202\256\344\273\266/.idea/workspace.xml" new file mode 100644 index 0000000..e46d549 --- /dev/null +++ "b/\345\217\221\351\200\201\351\202\256\344\273\266/.idea/workspace.xml" @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MIMEMultipart + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1598624346550 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git "a/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/.idea/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274.iml" "b/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/.idea/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274.iml" new file mode 100644 index 0000000..7c9d48f --- /dev/null +++ "b/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/.idea/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274.iml" @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git "a/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/ninecell_image.py" "b/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/ninecell_image.py" new file mode 100644 index 0000000..67f4b24 --- /dev/null +++ "b/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/ninecell_image.py" @@ -0,0 +1,109 @@ +#!/usr/bin/env python +# encoding: utf-8 + +""" +@version: v1.0 +@author: xag +@license: Apache Licence +@contact: xinganguo@gmail.com +@site: http://www.xingag.top +@software: PyCharm +@file: ninecell_image.py +@time: 2020-08-28 22:20 +@description:九宫格图片朋友圈 +""" + +from PIL import Image + + +class ImageObj(object): + def __init__(self): + pass + + def start(self, file_path): + # 1、打开图片 + image = Image.open(file_path) + + # 2、将图片填充为正方形,组成:原图+百底+正方形 + image = self.__fill_image(image) + + # 保存图片 + image.save('temp.jpg') + + # 3、裁剪合成后图片,为9张图片 + nine_images = self.__cut_image(image) + + # 4、保存9张图片到本地 + self.save_images(nine_images) + + def __cut_image(self, image): + """ + 把一张图片裁剪成9张图片的坐标值,然后进行裁剪成小图片 + :return: + """ + width, height = image.size + + # 6000 + print('原图的宽/高分别为:', width, height) + + # 2000 + # 每张图片的宽度 + item_width = int(width / 3) + + print('裁剪后的宽度为:', item_width) + + box_list = [] + + for i in range(0, 3): + for j in range(0, 3): + # 坐标值分别是:左、上、右、底 + box = (j * item_width, i * item_width, (j + 1) * item_width, (i + 1) * item_width) + print(box) + box_list.append(box) + + # 裁剪图片 + image_list = [image.crop(box) for box in box_list] + + return image_list + + def __fill_image(self, image): + """ + 将图片填充为正方形 + :param image: + :return: + """ + width, height = image.size + + # 长和宽较大值,作为新图片的宽高 + new_image_length = width if width > height else height + + # 生成新图片[纯白底] + new_image = Image.new(image.mode, (new_image_length, new_image_length), color='white') + + # 将之前的图粘贴在新图上,居中 + # 如果原图宽大于高(横图),则填充图片的竖直维度 + if width > height: + # (x,y)二元组表示粘贴上图相对下图的起始位置 + new_image.paste(image, (0, int((new_image_length - height) / 2))) + else: + # 如果原图宽小于高(竖图),则填充图片的水平纬度 + new_image.paste(image, (int((new_image_length - width) / 2), 0)) + return new_image + + def save_images(self, nine_images): + """ + 保存图片 + :param nine_images: + :return: + """ + index = 1 + for image in nine_images: + image.save('result/' + str(index) + '.jpg') + index += 1 + + +if __name__ == '__main__': + # 图片路径 + image_file_path = './raw/pic.jpg' + image_obj = ImageObj() + image_obj.start(image_file_path) diff --git "a/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/ninecell_video.py" "b/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/ninecell_video.py" new file mode 100644 index 0000000..cc6cdbd --- /dev/null +++ "b/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/ninecell_video.py" @@ -0,0 +1,159 @@ +#!/usr/bin/env python +# encoding: utf-8 + +""" +@version: v1.0 +@author: xag +@license: Apache Licence +@contact: xinganguo@gmail.com +@site: http://www.xingag.top +@software: PyCharm +@file: ninecell_video.py +@time: 2020-08-28 23:16 +@description:九宫格视频朋友圈 +""" + +from PIL import Image + +from utils.video_utils import * + + +class VideoObj(object): + def __init__(self, file_path): + self.video_raw_clip = VideoFileClip(file_path) + + # 宽、高 + self.video_width, self.video_height = self.video_raw_clip.w, self.video_raw_clip.h + + # 帧率 + self.fps = self.video_raw_clip.fps + + # 视频时长 + self.during = self.video_raw_clip.duration + + # 白色间隙宽度,用于分割图片 + self.item_space = 10 + + # 视频原路径 + self.path_video_raw = file_path + + # 临时文件夹,用于保存处理后的帧图片 + self.path_temp = './temp/' + + # 输出文件夹 + self.path_output = './output/' + + # 音频文件保存路径 + self.path_bgm = self.path_temp + 'bg.wav' + + # 临时保存的视频文件 + self.path_video_temp = self.path_temp + 'temp.mp4' + + # 最终输出的视频文件 + self.path_video_output = self.path_output + 'result.mp4' + + def pre(self): + """ + 准备工作 + :return: + """ + # 新建临时文件夹和输出文件夹 + mkdir_folder(self.path_temp) + mkdir_folder(self.path_output) + + def start(self): + + # 1、准备工作 + self.pre() + + print('视频宽/高为:', self.video_width, '/', self.video_height, '帧率/时长:', self.fps, '/', self.during) + + # 2、获取音频文件保存到本地 + get_audio_from_video(self.video_raw_clip, self.path_bgm) + + # 3、保存所有的帧图片到临时文件夹 + self.save_frames() + + # 4、将一篮子图片重新合成视频 + pics_to_video(self.path_temp, self.path_video_temp, self.fps) + + # 5、视频加入BGM + video_with_audio(self.path_video_temp, self.path_bgm, self.path_video_output) + + # 6、删除临时文件 + self.teardown() + + def save_frames(self): + """ + 保存视频的所有帧,并做处理 + :return: + """ + i = 1 + for frame in self.video_raw_clip.iter_frames(): + image = Image.fromarray(frame) + + # 视频帧图片保存的临时路径(完整路径) + frame_file_complete_path = self.path_temp + "%04d.jpg" % i + + # 对图片进一步处理,加入白色间隔距离 + self.handle_frame(image, frame_file_complete_path) + + i += 1 + + def handle_frame(self, image, frame_file_complete_path): + """ + 对帧图片进一步的处理 + 包含,裁剪图片、新建扩张画布、粘贴裁剪图片、保存新图片到本地 + :return: + """ + # 1、剪成9张图片,计算每张图片的宽、高 + item_width = int(self.video_width / 3) + item_height = int(self.video_height / 3) + + # 2、新的宽、高 + item_width_new = self.video_width + self.item_space * 2 + item_height_new = self.video_height + self.item_space * 2 + + # 3、重新建一个画布背景 + new_image = Image.new(image.mode, (item_width_new, item_height_new), + color='white') + + # 4、裁剪图片,然后粘贴到新的画布中去 + # i:横向、j:纵向 + for i in range(0, 3): + for j in range(0, 3): + # 裁剪区域 + box = (j * item_width, i * item_height, (j + 1) * item_width, (i + 1) * item_height) + + # 坐标,左、顶部、右、底 + # print(box) + + # 根据区域,裁剪图片 + crop_image = image.crop(box) + + # 横向、纵向第2块和第3块,要加上偏移距离 + x = 0 if j == 0 else (item_width + self.item_space) * j + y = 0 if i == 0 else (item_height + self.item_space) * i + + # 将9张图片,按照上面计算的坐标值,粘贴到背景中去 + new_image.paste(crop_image, (int(x), int(y))) + + # 保存图片到本地 + new_image.save(frame_file_complete_path) + + def teardown(self): + """ + 最后处理 + :return: + """ + # 删除临时文件 + remove_folder(self.path_temp) + + +if __name__ == '__main__': + # 待处理的文件 + file_path = './raw/至今无人超越的3个动作.mp4' + video_obj = VideoObj(file_path) + + # 处理 + video_obj.start() diff --git "a/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/output/result.mp4" "b/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/output/result.mp4" new file mode 100644 index 0000000..97a3bd5 Binary files /dev/null and "b/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/output/result.mp4" differ diff --git "a/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/raw/pic.jpg" "b/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/raw/pic.jpg" new file mode 100644 index 0000000..2322d6e Binary files /dev/null and "b/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/raw/pic.jpg" differ diff --git "a/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/raw/\350\207\263\344\273\212\346\227\240\344\272\272\350\266\205\350\266\212\347\232\2043\344\270\252\345\212\250\344\275\234.mp4" "b/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/raw/\350\207\263\344\273\212\346\227\240\344\272\272\350\266\205\350\266\212\347\232\2043\344\270\252\345\212\250\344\275\234.mp4" new file mode 100644 index 0000000..88938d1 Binary files /dev/null and "b/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/raw/\350\207\263\344\273\212\346\227\240\344\272\272\350\266\205\350\266\212\347\232\2043\344\270\252\345\212\250\344\275\234.mp4" differ diff --git "a/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/utils/file_utils.py" "b/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/utils/file_utils.py" new file mode 100644 index 0000000..b474878 --- /dev/null +++ "b/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/utils/file_utils.py" @@ -0,0 +1,59 @@ +#!/usr/bin/env python +# encoding: utf-8 + +""" +@version: v1.0 +@author: xag +@license: Apache Licence +@contact: xinganguo@gmail.com +@site: http://www.xingag.top +@software: PyCharm +@file: file_utils.py +@time: 2020-02-01 23:05 +@description:TODO +""" + +import os +import shutil + + +def get_file_path_and_name(filename): + """ + 获取文件的路径、文件名(不含后缀),后缀名 + :param filename: + :return: + """ + (filepath, tempfilename) = os.path.split(filename) + (shotname, extension) = os.path.splitext(tempfilename) + return filepath, shotname, extension + + +def rename_file(path, filename): + """ + 更改文件名(处理文件名中包含空格的情况) + :param path: + :param filename: + :return: + """ + os.rename(os.path.join(path, filename), os.path.join(path, filename.replace(' ', '_'))) + + +def mkdir_folder(file_path): + """ + 创建一个文件夹,如果不存在就创建;否则不做处理 + :param file_path: + :return: + """ + if os.path.exists(file_path): + return + + os.mkdir(file_path) + + +def remove_folder(file_path): + """ + 删除文件夹 + :param file_path: + :return: + """ + shutil.rmtree(file_path) diff --git "a/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/utils/math_utils.py" "b/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/utils/math_utils.py" new file mode 100644 index 0000000..78a8975 --- /dev/null +++ "b/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/utils/math_utils.py" @@ -0,0 +1,45 @@ +#!/usr/bin/env python +# encoding: utf-8 + +""" +@version: v1.0 +@author: xag +@license: Apache Licence +@contact: xinganguo@gmail.com +@site: http://www.xingag.top +@software: PyCharm +@file: math_utils.py +@time: 2020-08-29 10:14 +@description:TODO +""" + + +import re + +re_digits = re.compile(r'(\d+)') + + +def emb_numbers(s): + pieces = re_digits.split(s) + pieces[1::2] = map(int, pieces[1::2]) + return pieces + + +def sort_strings_with_emb_numbers(alist): + """ + DSU排序 + :param alist: + :return: + """ + aux = [(emb_numbers(s), s) for s in alist] + aux.sort() + return [s for __, s in aux] + + +def sort_strings_with_emb_numbers2(alist): + """ + 内置DSU排序 + :param alist: + :return: + """ + return sorted(alist, key=emb_numbers) \ No newline at end of file diff --git "a/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/utils/video_utils.py" "b/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/utils/video_utils.py" new file mode 100644 index 0000000..e0b05e1 --- /dev/null +++ "b/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/utils/video_utils.py" @@ -0,0 +1,119 @@ +#!/usr/bin/env python +# encoding: utf-8 + +""" +@version: v1.0 +@author: xag +@license: Apache Licence +@contact: xinganguo@gmail.com +@site: http://www.xingag.top +@software: PyCharm +@file: video_utils.py +@time: 2020-02-01 22:32 +@description:公众号:AirPython +""" + +import random + +from moviepy.editor import * + +from utils.file_utils import * +from utils.math_utils import * + + +def gene_random(): + """ + 生成随机数字 + :return: + """ + str = "" + for i in range(6): + ch = chr(random.randrange(ord('0'), ord('9') + 1)) + str += ch + return str + + +def get_audio_from_video(video_raw_clip, output_path): + """ + 从视频中提取音频 + :param video_raw_clip: 视频Clip对象 + :param output_path: 输出音频文件完整路径 + :return: + """ + audio = video_raw_clip.audio + audio.write_audiofile(output_path) + + return output_path + + +def mov2mp4(video_path, output_path): + """ + mov格式转为mp4 + 注意:原视频文件名不能包含空格 + :param video_path: + :param output_path: + :return: + """ + filename = gene_random() + try: + filename = get_file_path_and_name(video_path)[1] + except Exception as e: + pass + + output_path = output_path + filename + ".mp4" + + # 格式转换 + os.system('ffmpeg -i %s -qscale 0 %s' % (video_path, output_path)) + + +def pics_to_video(pics_path, output_path, fps): + """ + 图片转为视频 + pics_to_video('./../gif_temp/', './../video_temp/temp1.mp4', 20) + :param pics_path: + :param output_path: + :return: + """ + image_paths = list(map(lambda x: pics_path + x, os.listdir(pics_path))) + + # 注意:这里必须进行一次排序,保证所有帧的顺序是一致 + image_paths = sort_strings_with_emb_numbers(image_paths) + + # 过滤掉非图片 + image_paths = list(filter(lambda image_path: image_path.endswith('.jpg'), image_paths)) + + # 图片剪辑类 + clip = ImageSequenceClip(image_paths, + fps=fps) + + clip.write_videofile(output_path) + + +def video_with_other_audio(path_video_raw, path_bgm_raw, output): + """ + 视频合成音频(混合音效) + :return: + """ + videoclip = VideoFileClip(path_video_raw) + audioclip = AudioFileClip(path_bgm_raw) + + new_audioclip = CompositeAudioClip([videoclip.audio, audioclip]) + videoclip.audio = new_audioclip + videoclip.write_videofile(output) + + +def video_with_audio(path_video_raw, path_bgm_raw, output): + """ + 视频合成音频 + :return: + """ + videoclip = VideoFileClip(path_video_raw) + audioclip = AudioFileClip(path_bgm_raw) + + # 设置视频音频,并写入到文件中去 + videoclip.set_audio(audioclip).write_videofile(output, + codec='libx264', + audio_codec='aac', + temp_audiofile='temp-audio.m4a', + remove_temp=True + ) diff --git "a/\346\210\252\345\233\276\345\277\253\346\215\267\347\277\273\350\257\221/.idea/misc.xml" "b/\346\210\252\345\233\276\345\277\253\346\215\267\347\277\273\350\257\221/.idea/misc.xml" new file mode 100644 index 0000000..8656114 --- /dev/null +++ "b/\346\210\252\345\233\276\345\277\253\346\215\267\347\277\273\350\257\221/.idea/misc.xml" @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git "a/\346\210\252\345\233\276\345\277\253\346\215\267\347\277\273\350\257\221/.idea/modules.xml" "b/\346\210\252\345\233\276\345\277\253\346\215\267\347\277\273\350\257\221/.idea/modules.xml" new file mode 100644 index 0000000..3da5b59 --- /dev/null +++ "b/\346\210\252\345\233\276\345\277\253\346\215\267\347\277\273\350\257\221/.idea/modules.xml" @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git "a/\346\210\252\345\233\276\345\277\253\346\215\267\347\277\273\350\257\221/.idea/vcs.xml" "b/\346\210\252\345\233\276\345\277\253\346\215\267\347\277\273\350\257\221/.idea/vcs.xml" new file mode 100644 index 0000000..c2365ab --- /dev/null +++ "b/\346\210\252\345\233\276\345\277\253\346\215\267\347\277\273\350\257\221/.idea/vcs.xml" @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git "a/\346\210\252\345\233\276\345\277\253\346\215\267\347\277\273\350\257\221/.idea/workspace.xml" "b/\346\210\252\345\233\276\345\277\253\346\215\267\347\277\273\350\257\221/.idea/workspace.xml" new file mode 100644 index 0000000..f06aa0d --- /dev/null +++ "b/\346\210\252\345\233\276\345\277\253\346\215\267\347\277\273\350\257\221/.idea/workspace.xml" @@ -0,0 +1,273 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +