diff --git a/.DS_Store b/.DS_Store
index 68ab25e..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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ _PyV8
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1595339185159
+
+
+ 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 63da7b4..c2f7236 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,30 @@
-# tools_python
+# Tools Python
+
+## 详细教程
+
+如果想查看详细教程,请关注微信公众号:**AirPython**
+
+
+
+
+
+
+
+## 文章列表
+
+* [制作截图快捷翻译](./截图快捷翻译)
+* [朋友圈防折叠](./朋友圈防折叠/)
+* [批量生成手机号码](./批量生成手机号码)
+* [短视频二次创作](./video_auto/二次剪辑)
+* [使用 Python 制作 GIF 动画视频](./video_auto/制作GIF视频/)
+* [使用 Python 制作一个卡点视频](./video_auto/卡点视频/readme.md)
* [替换 `apk` 的资源并重新打包](./android/replace_apk_resource/readme.md)
* [替换 `apk` 的资源并重新打包全解析](./android/replace_apk_resource_pro/readme.md)
* [`appium` 配合压力测试 `app` 应用](./android/appium_demo/)
* [每天固定时间发送天气、笑话给微信个人和群,并部署到云服务器](./EveryDay/)
-* [使用 Python 制作一个卡点视频](./video_auto/卡点视频/readme.md)
-* [使用 Python 制作 GIF 动画视频](./video_auto/制作GIF视频/)
-
+* [视频特殊处理,保证唯一性](./视频特殊处理.py)
+* [发送邮件的几种方式](./发送邮件)
+* [Python 调用 JS 的 4 种方式](./Python执行JS总结)
+* [批处理脚本](./批处理脚本)
+* [生成九宫格视频+生成九宫格朋友圈图片](./图片视频九宫格/)
diff --git a/raw/qr.jpeg b/raw/qr.jpeg
new file mode 100644
index 0000000..1e66f85
Binary files /dev/null and b/raw/qr.jpeg differ
diff --git a/video_auto/.DS_Store b/video_auto/.DS_Store
index 1e89194..7dd1e34 100644
Binary files a/video_auto/.DS_Store and b/video_auto/.DS_Store differ
diff --git "a/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/.DS_Store" "b/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/.DS_Store"
new file mode 100644
index 0000000..752209c
Binary files /dev/null and "b/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/.DS_Store" differ
diff --git "a/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/.idea/misc.xml" "b/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/.idea/misc.xml"
new file mode 100644
index 0000000..8656114
--- /dev/null
+++ "b/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/.idea/misc.xml"
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/.idea/modules.xml" "b/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/.idea/modules.xml"
new file mode 100644
index 0000000..9a413c3
--- /dev/null
+++ "b/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/.idea/modules.xml"
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/.idea/vcs.xml" "b/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/.idea/vcs.xml"
new file mode 100644
index 0000000..c2365ab
--- /dev/null
+++ "b/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/.idea/vcs.xml"
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/.idea/workspace.xml" "b/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/.idea/workspace.xml"
new file mode 100644
index 0000000..ac07554
--- /dev/null
+++ "b/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/.idea/workspace.xml"
@@ -0,0 +1,839 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ fadein
+ concatenate_videoclips
+ video_clip
+ audio
+ temp.mp
+ video_path
+ get_frame_from_video
+
+
+ $PROJECT_DIR$
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1576575101611
+
+
+ 1576575101611
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/.idea/\350\247\206\351\242\221\345\211\252\350\276\221.iml" "b/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/.idea/\350\247\206\351\242\221\345\211\252\350\276\221.iml"
new file mode 100644
index 0000000..7c9d48f
--- /dev/null
+++ "b/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/.idea/\350\247\206\351\242\221\345\211\252\350\276\221.iml"
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/fonts/.DS_Store" "b/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/fonts/.DS_Store"
new file mode 100644
index 0000000..5008ddf
Binary files /dev/null and "b/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/fonts/.DS_Store" differ
diff --git "a/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/fonts/STHeiti Medium.ttc" "b/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/fonts/STHeiti Medium.ttc"
new file mode 100644
index 0000000..fb746ab
Binary files /dev/null and "b/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/fonts/STHeiti Medium.ttc" differ
diff --git "a/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/source/.DS_Store" "b/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/source/.DS_Store"
new file mode 100644
index 0000000..1c2996e
Binary files /dev/null and "b/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/source/.DS_Store" differ
diff --git "a/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/util/.DS_Store" "b/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/util/.DS_Store"
new file mode 100644
index 0000000..5008ddf
Binary files /dev/null and "b/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/util/.DS_Store" differ
diff --git "a/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/util/file_utils.py" "b/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/util/file_utils.py"
new file mode 100644
index 0000000..de996fc
--- /dev/null
+++ "b/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/util/file_utils.py"
@@ -0,0 +1,36 @@
+#!/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: 2019-12-29 11:30
+@description:TODO
+"""
+
+import os
+
+
+def del_temp_file(path):
+ """
+ 删除目录下的临时文件
+ :param path:
+ :return:
+ """
+ # 删除临时文件
+ g = os.walk(path)
+
+ for path, dir_list, file_list in g:
+ print(path)
+ for file_name in file_list:
+ print(file_name)
+ if file_name.startswith('temp'):
+ os.remove(path + file_name)
+
+
+
diff --git "a/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/util/img_utils.py" "b/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/util/img_utils.py"
new file mode 100644
index 0000000..bfebc39
--- /dev/null
+++ "b/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/util/img_utils.py"
@@ -0,0 +1,55 @@
+#!/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: img_utils.py
+@time: 2019-12-25 14:23
+@description:图片工具类
+"""
+import cv2
+from moviepy.video.VideoClip import ImageClip
+from moviepy.editor import VideoFileClip
+
+
+def one_pic_to_video(image_path, output_video_path, fps, time):
+ """
+ 一张图片合成视频
+ one_pic_to_video('./../source/1.jpeg', './../source/output.mp4', 25, 10)
+ :param path: 图片文件路径
+ :param output_video_path:合成视频的路径
+ :param fps:帧率
+ :param time:时长
+ :return:
+ """
+
+ image_clip = ImageClip(image_path)
+ img_width, img_height = image_clip.w, image_clip.h
+
+ # 总共的帧数
+ frame_num = (int)(fps * time)
+
+ img_size = (int(img_width), int(img_height))
+
+ fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
+
+ video = cv2.VideoWriter(output_video_path, fourcc, fps, img_size)
+
+ for index in range(frame_num):
+ frame = cv2.imread(image_path)
+ # 直接缩放到指定大小
+ frame_suitable = cv2.resize(frame, (img_size[0], img_size[1]), interpolation=cv2.INTER_CUBIC)
+
+ # 把图片写进视频
+ # 重复写入多少次
+ video.write(frame_suitable)
+
+ # 释放资源
+ video.release()
+
+ return VideoFileClip(output_video_path)
diff --git "a/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/util/video_utils.py" "b/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/util/video_utils.py"
new file mode 100644
index 0000000..a6981c2
--- /dev/null
+++ "b/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/util/video_utils.py"
@@ -0,0 +1,99 @@
+#!/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: 2019-12-26 21:58
+@description:视频工具类
+"""
+
+from moviepy.editor import *
+
+
+def time_to_hms(seconds_time):
+ """
+ 时间转为时分秒
+ :param seconds_time: 秒数
+ :return:
+ """
+ m, s = divmod(seconds_time, 60)
+ h, m = divmod(m, 60)
+ return "%02d:%02d:%02d" % (h, m, s)
+
+
+def synthetic_video(video1_clip, video2_clip2):
+ """
+ 合成两段视频,生成视频的宽高以第一段视频为准
+ :param video1_clip:
+ :param video2_clip2:
+ :return:
+ """
+ # 最后生成视频的宽、高
+ width, height = video1_clip.w, video1_clip.h
+
+ # 第二段视频的实际宽、高
+ video_width, video_height = video2_clip2.w, video2_clip2.h
+
+ # 最第二段视频进行缩放
+ video_clip1 = video2_clip2.resize((width, width * video_height / video_width))
+
+ # 合成视频的路径
+ synthetic_video_clip = CompositeVideoClip([video1_clip, video_clip1.set_pos("center")])
+
+ synthetic_video_clip.write_videofile(
+ './source/temp_synthetic_video.mp4')
+
+ return synthetic_video_clip
+
+
+def video_with_text(synthetic_video_clip, desc_text_clip):
+ """
+ 视频中加入文字信息
+ :param synthetic_video_clip:
+ :param param:
+ :return:
+ """
+
+ video_with_text_clip = CompositeVideoClip([synthetic_video_clip, desc_text_clip.set_start(0)])
+ video_with_text_clip.write_videofile(
+ './source/temp_video_with_text.mp4')
+
+ return video_with_text_clip
+
+ # video_with_text_clip.write_videofile(
+ # './source/temp_video_with_text.mp4')
+
+
+def get_frame_from_video(video_name, frame_time, img_path):
+ """
+ 获取视频某个时间的帧图片,保存在本地
+ :param video_name: 视频路径
+ :param frame_time: 截取帧的时间位置(s)
+ :param img_path:生成图片的完整路径
+ :return:
+ """
+ # 秒转为时、分、秒
+ time_pre = time_to_hms(frame_time)
+
+ os.system('ffmpeg -ss %s -i %s -frames:v 1 %s' % (time_pre, video_name, img_path))
+
+
+def generate_text_clip(text_content, font_params, duration):
+ """
+ 产生字幕
+ :return:
+ """
+ # 显示位置
+ position = font_params.get('position')
+ position_text = 'top' if position == 0 else 'bottom'
+
+ return TextClip(text_content, font='./fonts/STHeiti Medium.ttc',
+ fontsize=font_params.get('size'), kerning=font_params.get('kerning'),
+ color=font_params.get('color')).set_position(("center", 150)).set_duration(duration)
+
diff --git "a/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/\344\272\214\346\254\241\345\210\233\344\275\234.py" "b/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/\344\272\214\346\254\241\345\210\233\344\275\234.py"
new file mode 100644
index 0000000..d0f93d6
--- /dev/null
+++ "b/video_auto/\344\272\214\346\254\241\345\211\252\350\276\221/\344\272\214\346\254\241\345\210\233\344\275\234.py"
@@ -0,0 +1,166 @@
+#!/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_rework.py
+@time: 2019-12-25 15:47
+@description:抖音视频二次创作
+"""
+
+from moviepy.video import fx
+
+from util.img_utils import *
+from util.video_utils import *
+from util.file_utils import *
+
+
+class Video_Re(object):
+
+ def __init__(self, video_raw_path, desc):
+ # 原始素材
+ self.video_raw_path = video_raw_path
+
+ # 描述信息
+ self.desc = desc
+
+ # 视频和音频
+ self.video_clip = None
+ self.audio = None
+
+ # 视频的宽、高
+ self.video_width = 0
+ self.video_height = 0
+
+ # 视频的默认帧率、时长
+ self.fps = 25
+ self.time = 10
+
+ # 文字字体属性,包含:字体大小、字体颜色、字体位置,一般是上(0)下(1)
+ self.font_params = {
+ 'size': 50,
+ 'color': 'red',
+ 'kerning': 5,
+ 'position': 0
+ }
+
+ def run(self):
+ # 1、获取视频的属性数据,并裁掉抖音最后加入的素材数据(抖音记录美好生活,一般为3s)
+ self.__pre()
+
+ # 2、获取视频的某一帧,去PS量取视频的左上角、右下角坐标
+ position1, position2 = self.__get_frame(3)
+
+ # 3、对原视频进行一次剪辑,重新产生一个横向的视频
+ croped_video_clip = self.video_crop(position1, position2, './source/temp_source_croped.mp4')
+
+ print(f'视频宽为:{self.video_width},高为:{self.video_height},帧率:{self.fps},时长:{self.time}')
+
+ # 4、一张图片组成背景视频,和视频同帧率、同时长
+ image_video_clip = one_pic_to_video('./source/1.jpeg', './source/temp_img_video.mp4', self.fps, self.time)
+
+ # 5、合成两段视频
+ synthetic_video_clip = synthetic_video(image_video_clip, croped_video_clip)
+
+ # 6、生成描述信息
+ desc_text_clip = generate_text_clip(self.desc, self.font_params, synthetic_video_clip.duration)
+
+ # 7、视频加入描述信息
+ video_with_text_clip = video_with_text(synthetic_video_clip, desc_text_clip)
+
+ # 8、视频加入音频,并删除临时文件
+ self.video_with_audio(video_with_text_clip)
+
+ def video_crop(self, position1, position2, croped_video_path):
+ """
+ 视频裁剪
+ :return:
+ """
+ # 裁剪的坐标,包含左上角x轴和y轴;右下角x轴和y轴
+ clip2 = fx.all.crop(self.video_clip, x1=position1[0], y1=position1[1], x2=position2[0], y2=position2[1])
+
+ # 保存文件
+ clip2.write_videofile(croped_video_path)
+
+ # 时长
+ self.time = clip2.duration
+
+ return clip2
+
+ def __pre(self):
+ """
+ 准备工作
+ :return:
+ """
+ self.video_raw_clip = VideoFileClip(self.video_raw_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.audio = self.video_raw_clip.audio.subclip(0, self.video_raw_clip.duration - 4)
+
+ # 裁剪尾部的视频素材
+ temp_video_clip = self.video_raw_clip.subclip(0, self.video_raw_clip.duration - 4)
+
+ # 生成新的视频,并保存到本地
+ temp_video_clip.set_audio(self.audio)
+
+ video_path = './source/temp_source_video.mp4'
+
+ temp_video_clip.write_videofile(video_path, codec='libx264',
+ audio_codec='aac',
+ temp_audiofile='temp-audio.m4a',
+ remove_temp=True)
+
+ # 重新初始化VideoFileClip,便于后面剪辑
+ self.video_clip = VideoFileClip(video_path)
+
+ def __get_frame(self, time):
+ """
+ 获取视频的某一帧
+ :param time:
+ :return:
+ """
+ # get_frame_from_video(self.path_video_source, time, './output.jpg')
+
+ # 获取要截取视频的左上坐标、右下坐标(328 631)
+ # position1 = (0, 328)
+ # position2 = (self.video_width, 631)
+
+ # 注意:坐标值必须为偶数,不然会裁剪失败
+ position1 = (0, 328)
+ position2 = (self.video_width, 630)
+
+ return position1, position2
+
+ def video_with_audio(self, video_with_text_clip):
+ """
+ 视频合成音频,并删除临时文件
+ :return:
+ """
+ # 设置视频音频,并写入到文件中去
+ video_with_text_clip.set_audio(self.audio).write_videofile("output.mp4",
+ codec='libx264',
+ audio_codec='aac',
+ temp_audiofile='temp-audio.m4a',
+ remove_temp=True
+ )
+ # 删除所有的临时文件
+ del_temp_file("./source/")
+
+
+if __name__ == '__main__':
+ # 原视频文件
+ video_source = './source/source.mp4'
+ desc = '我是描述信息'
+
+ video_re = Video_Re(video_source, desc)
+ video_re.run()
diff --git "a/\344\270\200\351\224\256\345\215\207\347\272\247/.DS_Store" "b/\344\270\200\351\224\256\345\215\207\347\272\247/.DS_Store"
index 5f462e1..4799a52 100644
Binary files "a/\344\270\200\351\224\256\345\215\207\347\272\247/.DS_Store" and "b/\344\270\200\351\224\256\345\215\207\347\272\247/.DS_Store" differ
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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1594295709801
+
+
+ 1594295709801
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/\345\217\221\351\200\201\351\202\256\344\273\266/.idea/\345\217\221\351\200\201\351\202\256\344\273\266.iml" "b/\345\217\221\351\200\201\351\202\256\344\273\266/.idea/\345\217\221\351\200\201\351\202\256\344\273\266.iml"
new file mode 100644
index 0000000..7c9d48f
--- /dev/null
+++ "b/\345\217\221\351\200\201\351\202\256\344\273\266/.idea/\345\217\221\351\200\201\351\202\256\344\273\266.iml"
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/\345\217\221\351\200\201\351\202\256\344\273\266/attachments/report.png" "b/\345\217\221\351\200\201\351\202\256\344\273\266/attachments/report.png"
new file mode 100644
index 0000000..74ae740
Binary files /dev/null and "b/\345\217\221\351\200\201\351\202\256\344\273\266/attachments/report.png" differ
diff --git "a/\345\217\221\351\200\201\351\202\256\344\273\266/email_by_smtplib.py" "b/\345\217\221\351\200\201\351\202\256\344\273\266/email_by_smtplib.py"
new file mode 100644
index 0000000..9fb68d4
--- /dev/null
+++ "b/\345\217\221\351\200\201\351\202\256\344\273\266/email_by_smtplib.py"
@@ -0,0 +1,102 @@
+#!/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: email_by_smtplib.py
+@time: 2020-07-09 21:30
+@description:smtplib发送邮件
+"""
+
+import os
+import smtplib
+from email.mime.multipart import MIMEMultipart
+from email.mime.text import MIMEText
+
+
+class SmtplibObject(object):
+
+ def __init__(self):
+ # 初始化
+ self.smtp = smtplib.SMTP()
+ # 连接邮箱服务器地址
+ self.smtp.connect('smtp.126.com')
+
+ # 加入主题和附件,邮件体
+ self.email_body = MIMEMultipart('mixed')
+
+ # 发件人地址及授权码
+ self.email_from_username = '**@126.com'
+ self.email_from_password = '授权码'
+
+ def send_email(self, email_to_list, email_title, email_content, attchment_path, files):
+ """
+ 发送邮件
+ :return:
+ """
+ # 组成邮件体
+ self.generate_email_body(email_to_list, email_title, email_content, attchment_path, files)
+
+ # 登录邮箱
+ # 参数为账号和密码(授权码)
+ self.smtp.login(self.email_from_username, self.email_from_password)
+
+ # 发送邮件
+ # 注意:此处必须同时指定发件人与收件人,否则会当作垃圾邮件处理掉
+ self.smtp.sendmail(self.email_from_username, email_to_list, self.email_body.as_string())
+
+ def generate_email_body(self, email_to_list, email_title, email_content, attchment_path, files):
+ """
+ 组成邮件体
+ :param email_to_list:收件人列表
+ :param email_title:邮件标题
+ :param email_content:邮件正文内容
+ :param attchment_path:附件的路径
+ :param files:附件文件名列表
+ :return:
+ """
+ self.email_body['Subject'] = email_title
+ self.email_body['From'] = self.email_from_username
+ self.email_body['To'] = ",".join(email_to_list)
+
+ for file in files:
+ file_path = attchment_path + '/' + file
+ if os.path.isfile(file_path):
+ # 构建一个附件对象
+ att = MIMEText(open(file_path, 'rb').read(), 'base64', 'utf-8')
+ att["Content-Type"] = 'application/octet-stream'
+ att.add_header("Content-Disposition", "attachment", filename=("gbk", "", file))
+ self.email_body.attach(att)
+
+ text_plain = MIMEText(email_content, 'plain', 'utf-8')
+ self.email_body.attach(text_plain)
+
+ def exit(self):
+ """
+ 退出服务
+ :return:
+ """
+ self.smtp.quit()
+
+
+if __name__ == '__main__':
+ # 收件人列表
+ email_to_list = ['**@qq.com']
+ email_title = "测试报告"
+ email_content = '这是测试报告具体内容'
+ # 附件路径
+ attchment_path = './attachments/'
+ # 附件文件列表
+ attchment_files = ['report.png', 'config.json']
+
+ # 发送邮件
+ smtplib_object = SmtplibObject()
+ smtplib_object.send_email(email_to_list, email_title, email_content, attchment_path, attchment_files)
+
+ # 退出
+ smtplib_object.exit()
diff --git "a/\345\217\221\351\200\201\351\202\256\344\273\266/email_by_yagmail.py" "b/\345\217\221\351\200\201\351\202\256\344\273\266/email_by_yagmail.py"
new file mode 100644
index 0000000..7552ae3
--- /dev/null
+++ "b/\345\217\221\351\200\201\351\202\256\344\273\266/email_by_yagmail.py"
@@ -0,0 +1,35 @@
+#!/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: email_by_yagmail.py
+@time: 2020-07-09 21:07
+@description:yagmail发送/接受邮件
+"""
+
+# 依赖:pip3 install yagmail
+# 公众号:AirPython
+
+import yagmail
+
+# 连接服务器
+# 用户名、授权码、服务器地址
+yag_server = yagmail.SMTP(user='**@126.com', password='授权码', host='smtp.126.com')
+
+# 发送邮件
+# 发送对象列表
+email_to = ['**@qq.com', ]
+email_title = '测试报告'
+email_content = "这是测试报告的具体内容"
+# 附件列表
+email_attachments = ['./attachments/report.png', ]
+yag_server.send(email_to, email_title, email_content, email_attachments)
+
+# 关闭连接
+yag_server.close()
diff --git "a/\345\217\221\351\200\201\351\202\256\344\273\266/email_by_zmail.py" "b/\345\217\221\351\200\201\351\202\256\344\273\266/email_by_zmail.py"
new file mode 100644
index 0000000..3d5fb5b
--- /dev/null
+++ "b/\345\217\221\351\200\201\351\202\256\344\273\266/email_by_zmail.py"
@@ -0,0 +1,96 @@
+#!/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: email_by_zmail.py
+@time: 2020-07-09 19:57
+@description:zmail发送邮件
+"""
+
+# 依赖
+# pip3 install zmail
+# 公众号:AirPython
+
+import zmail
+
+
+class ZMailObject(object):
+
+ def __init__(self):
+ # 邮箱账号
+ self.username = '**@126.com'
+
+ # 邮箱授权码
+ self.authorization_code = '授权码'
+
+ # 构建一个邮箱服务对象
+ self.server = zmail.server(self.username, self.authorization_code)
+
+ def send_email(self, mail_to, mail_body):
+ """
+ 发送邮件
+ :param mail_to 发送对象
+ :param mail: 发送主题、内容及附件
+ :return:
+ """
+
+ if self.__check_pop_enable() and self.__check_smtp_enable():
+ self.server.send_mail(mail_to, mail_body)
+ else:
+ pass
+
+ def receive_email(self):
+ """
+ 接受邮件
+ :return:
+ """
+ try:
+ # 接受邮件
+ last_mail = self.server.get_latest()
+ # last_mail = self.server.get_mail(2)
+ # zmail.show(last_mail)
+ for k, v in last_mail.items():
+ print(k, v)
+ except Exception as e:
+ # 收件箱为空,则会报错
+ print('接受异常异常')
+
+ def __check_smtp_enable(self):
+ """
+ 检查smtp是否正常
+ :return:
+ """
+ return self.server.smtp_able()
+
+ def __check_pop_enable(self):
+ """
+ 检查pop功能是否正常
+ :return:
+ """
+ return self.server.pop_able()
+
+
+if __name__ == '__main__':
+ zmail_obj = ZMailObject()
+
+ # 发送内容及附件
+ mail_to = '**@qq.com'
+
+ # 邮件主体
+ mail_body = {
+ 'subject': '测试报告',
+ 'content_text': '这是一个测试报告', # 纯文本或者HTML内容
+ 'attachments': ['./attachments/report.png'],
+ }
+
+ # 发送邮件
+ zmail_obj.send_email(mail_to, mail_body)
+
+ # 接受邮件
+ # zmail_obj.receive_email()
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/inspectionProfiles/Project_Default.xml" "b/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/.idea/inspectionProfiles/Project_Default.xml"
new file mode 100644
index 0000000..d962dec
--- /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/inspectionProfiles/Project_Default.xml"
@@ -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/.idea/misc.xml" "b/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/.idea/misc.xml"
new file mode 100644
index 0000000..8656114
--- /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/misc.xml"
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ 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/modules.xml" "b/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/.idea/modules.xml"
new file mode 100644
index 0000000..da76fd2
--- /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/modules.xml"
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ 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/vcs.xml" "b/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/.idea/vcs.xml"
new file mode 100644
index 0000000..c2365ab
--- /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/vcs.xml"
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ 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/workspace.xml" "b/\345\233\276\347\211\207\350\247\206\351\242\221\344\271\235\345\256\253\346\240\274/.idea/workspace.xml"
new file mode 100644
index 0000000..0962a99
--- /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/workspace.xml"
@@ -0,0 +1,573 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1598624346550
+
+
+ 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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1584494973510
+
+
+ 1584494973510
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ 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/\346\210\252\345\233\276\345\277\253\346\215\267\347\277\273\350\257\221.iml" "b/\346\210\252\345\233\276\345\277\253\346\215\267\347\277\273\350\257\221/.idea/\346\210\252\345\233\276\345\277\253\346\215\267\347\277\273\350\257\221.iml"
new file mode 100644
index 0000000..7c9d48f
--- /dev/null
+++ "b/\346\210\252\345\233\276\345\277\253\346\215\267\347\277\273\350\257\221/.idea/\346\210\252\345\233\276\345\277\253\346\215\267\347\277\273\350\257\221.iml"
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ 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/main.py" "b/\346\210\252\345\233\276\345\277\253\346\215\267\347\277\273\350\257\221/main.py"
new file mode 100644
index 0000000..1c3ce28
--- /dev/null
+++ "b/\346\210\252\345\233\276\345\277\253\346\215\267\347\277\273\350\257\221/main.py"
@@ -0,0 +1,74 @@
+#!/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: main.py
+@time: 2020-03-18 09:29
+@description:TODO
+"""
+
+import tkinter.messagebox
+from tkinter import *
+
+import pytesseract
+from PIL import Image
+from PIL import ImageGrab
+from googletrans import Translator
+
+
+def get_clip_image():
+ """
+ 从剪切板获取图片,保存到本地
+ :return:
+ """
+ image_result = None
+ img = ImageGrab.grabclipboard()
+ if img and isinstance(img, Image.Image):
+ print(img.size)
+ print(img.mode)
+ image_result = './temp.png'
+ img.save(image_result)
+ return image_result
+
+
+def image_ocr(image_path):
+ """
+ 识别图像中的英文
+ :return:
+ """
+ # 英文:lang='eng'
+ # 中文:lang='chi_sim'
+ return pytesseract.image_to_string(Image.open(image_path), lang='eng')
+
+
+def trans_eng(content_eng):
+ """
+ 英文-中文
+ :param content:
+ :return:
+ """
+ translator = Translator(service_urls=['translate.google.cn'])
+ return translator.translate(content_eng, src='en', dest='zh-cn').text
+
+
+image_path = get_clip_image()
+
+if image_path:
+ # 获取文本
+ content_eng = image_ocr(image_path).replace("\r", " ").replace("\n", " ")
+
+ # 翻译
+ if content_eng:
+ content_chinese = trans_eng(content_eng)
+ print(content_chinese)
+
+ # 实现主窗口隐藏
+ root = Tk()
+ root.withdraw()
+ tkinter.messagebox.showinfo('翻译结果', content_chinese)
\ 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/trans.py" "b/\346\210\252\345\233\276\345\277\253\346\215\267\347\277\273\350\257\221/trans.py"
new file mode 100644
index 0000000..e412396
--- /dev/null
+++ "b/\346\210\252\345\233\276\345\277\253\346\215\267\347\277\273\350\257\221/trans.py"
@@ -0,0 +1,41 @@
+#!/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: trans.py
+@time: 2020-03-18 21:55
+@description:截屏快速翻译
+"""
+
+import tkinter.messagebox
+from tkinter import *
+
+import pytesseract
+from PIL import Image
+from PIL import ImageGrab
+from googletrans import Translator
+
+# 1、从剪切板获取图片,保存到本地
+img = ImageGrab.grabclipboard()
+if img and isinstance(img, Image.Image):
+ image_result = './temp.png'
+ img.save(image_result)
+
+ # 2、OCR识别
+ content_eng = pytesseract.image_to_string(Image.open(image_result), lang='eng')
+
+ # 3、翻译
+ translator = Translator(service_urls=['translate.google.cn'])
+
+ content_chinese = translator.translate(content_eng, src='en', dest='zh-cn').text
+
+ # 4、显示
+ root = Tk()
+ root.withdraw()
+ tkinter.messagebox.showinfo('翻译结果', content_chinese)
diff --git "a/\346\211\271\345\244\204\347\220\206\350\204\232\346\234\254/del_all_build.bat" "b/\346\211\271\345\244\204\347\220\206\350\204\232\346\234\254/del_all_build.bat"
new file mode 100755
index 0000000..310baeb
--- /dev/null
+++ "b/\346\211\271\345\244\204\347\220\206\350\204\232\346\234\254/del_all_build.bat"
@@ -0,0 +1,12 @@
+@echo off
+:: ´½µ±ǰĿ¼ÏÂ
+cd /d "%~dp0"
+
+:: ɾ³ýbuildÎļþ¼Ð
+echo ¿ªʼɾ³ý
+
+for /r /D %%i in (*build*) do rd /s /q "%%i"
+
+echo ɾ³ýÍê³É
+
+pause
\ No newline at end of file
diff --git "a/\346\211\271\345\244\204\347\220\206\350\204\232\346\234\254/del_system_gc.bat" "b/\346\211\271\345\244\204\347\220\206\350\204\232\346\234\254/del_system_gc.bat"
new file mode 100755
index 0000000..b1ee62c
--- /dev/null
+++ "b/\346\211\271\345\244\204\347\220\206\350\204\232\346\234\254/del_system_gc.bat"
@@ -0,0 +1,28 @@
+@echo off
+:: ÅäÖÃ
+title Alic Feng batTool for Clean
+color 03
+mode con cols=42 lines=20
+
+echo executes cleaning,Please waiting...
+
+::³ÌÐòɾ³ýϵͳÎÞÓÃÎļþ¿ªʼ
+del /f /s /q %systemdrive%\*.tmp 1>nul 2>nul
+del /f /s /q %systemdrive%\*._mp 1>nul 2>nul
+del /f /s /q %systemdrive%\*.log 1>nul 2>nul
+del /f /s /q %systemdrive%\*.gid 1>nul 2>nul
+del /f /s /q %systemdrive%\*.chk 1>nul 2>nul
+del /f /s /q %systemdrive%\*.old 1>nul 2>nul
+del /f /s /q %systemdrive%\recycled\*.* 1>nul 2>nul
+del /f /s /q %windir%\*.bak 1>nul 2>nul
+del /f /s /q %windir%\prefetch\*.* 1>nul 2>nul
+del /f /s /q %windir%\temp\*.* 1>nul 2>nul
+del /f /q %userprofile%\cookies\*.* 1>nul 2>nul
+del /f /q %userprofile%\recent\*.* 1>nul 2>nul
+del /f /s /q "%userprofile%\Local Settings\Temporary Internet Files\*.*" 1>nul 2>nul
+del /f /s /q "%userprofile%\Local Settings\Temp\*.*" 1>nul 2>nul
+del /f /s /q "%userprofile%\recent\*.*" 1>nul 2>nul
+::³ÌÐòɾ³ýϵͳÎÞÓÃÎļþ½áÊø
+
+echo Çå³ýϵͳÍê³É
+echo. & pause
\ No newline at end of file
diff --git "a/\346\211\271\345\244\204\347\220\206\350\204\232\346\234\254/documents_classifying.bat" "b/\346\211\271\345\244\204\347\220\206\350\204\232\346\234\254/documents_classifying.bat"
new file mode 100755
index 0000000..f9dbc5a
--- /dev/null
+++ "b/\346\211\271\345\244\204\347\220\206\350\204\232\346\234\254/documents_classifying.bat"
@@ -0,0 +1,8 @@
+@echo off
+:: 当前目录下的文件进行分类,放到不同的文件夹内
+:: md 用于创建文件夹
+:: %%~xi将%%i解开扩展名,也就是取%%i的扩展名部分
+for %%i in (*) do (md %%~xi
+move *%%~xi %%~xi)
+
+pause
\ No newline at end of file
diff --git "a/\346\211\271\345\244\204\347\220\206\350\204\232\346\234\254/raw/Bat_To_Exe_Converter.exe" "b/\346\211\271\345\244\204\347\220\206\350\204\232\346\234\254/raw/Bat_To_Exe_Converter.exe"
new file mode 100755
index 0000000..1ed4e4a
Binary files /dev/null and "b/\346\211\271\345\244\204\347\220\206\350\204\232\346\234\254/raw/Bat_To_Exe_Converter.exe" differ
diff --git "a/\346\211\271\345\244\204\347\220\206\350\204\232\346\234\254/run_python_loop.bat" "b/\346\211\271\345\244\204\347\220\206\350\204\232\346\234\254/run_python_loop.bat"
new file mode 100755
index 0000000..f5c8d44
--- /dev/null
+++ "b/\346\211\271\345\244\204\347\220\206\350\204\232\346\234\254/run_python_loop.bat"
@@ -0,0 +1,22 @@
+@echo off
+
+title ѭ»·ÔËÐÐPython´úÂë
+
+:: 5·ÖÖÓִÐÐһ´Σ¬µ¥λΪs
+set INTERVAL=300
+
+:: ÌáǰִÐÐһ´Σ¬°ÑִÐÐʱ¼ä´òӡ³öÀ´
+echo ¿ªʼִÐÐ - %time%
+python C:/test.py
+
+:: ʹÓÃtimeout½øÐе¹¼Æʱ
+timeout %INTERVAL%
+
+:: н¨һ¸öÈÎÎñ
+:Task
+echo ¿ªʼִÐÐ - %time%
+python C:/test.py
+timeout %INTERVAL%
+
+:: ʹÓÃgotoÃüÁ¿ªʼÌøתµ½ÉÏÃæµÄÈÎΪʼִÐÐ
+goto Task
\ No newline at end of file
diff --git "a/\346\211\271\345\244\204\347\220\206\350\204\232\346\234\254/\346\217\220\344\272\244\344\273\243\347\240\201/\346\217\220\344\272\244\344\273\243\347\240\201.bat" "b/\346\211\271\345\244\204\347\220\206\350\204\232\346\234\254/\346\217\220\344\272\244\344\273\243\347\240\201/\346\217\220\344\272\244\344\273\243\347\240\201.bat"
new file mode 100755
index 0000000..9607674
--- /dev/null
+++ "b/\346\211\271\345\244\204\347\220\206\350\204\232\346\234\254/\346\217\220\344\272\244\344\273\243\347\240\201/\346\217\220\344\272\244\344\273\243\347\240\201.bat"
@@ -0,0 +1,20 @@
+@echo off
+title �ύ����
+echo �ύ���룬����
+
+:: ����״̬
+git status
+
+:: set���ȴ����룬��ֵ������msg
+set /p commit_msg=�����ύע�ͣ�
+
+:: �ύ�����4������
+git add .
+git commit -m %commit_msg%
+git pull
+git push
+
+echo �ύ�ɹ�
+pause
+
+
diff --git "a/\346\211\271\351\207\217\347\224\237\346\210\220\346\211\213\346\234\272\345\217\267\347\240\201/.DS_Store" "b/\346\211\271\351\207\217\347\224\237\346\210\220\346\211\213\346\234\272\345\217\267\347\240\201/.DS_Store"
new file mode 100644
index 0000000..73fb940
Binary files /dev/null and "b/\346\211\271\351\207\217\347\224\237\346\210\220\346\211\213\346\234\272\345\217\267\347\240\201/.DS_Store" differ
diff --git "a/\346\211\271\351\207\217\347\224\237\346\210\220\346\211\213\346\234\272\345\217\267\347\240\201/generate_area_phone_util.py" "b/\346\211\271\351\207\217\347\224\237\346\210\220\346\211\213\346\234\272\345\217\267\347\240\201/generate_area_phone_util.py"
new file mode 100644
index 0000000..0420c1a
--- /dev/null
+++ "b/\346\211\271\351\207\217\347\224\237\346\210\220\346\211\213\346\234\272\345\217\267\347\240\201/generate_area_phone_util.py"
@@ -0,0 +1,71 @@
+#!/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: generate_area_phone_util.py
+@time: 2020-01-05 20:16
+@description:生成区域的电话号码
+"""
+
+from utils.addr_utils import *
+
+def generate_phones(num, areas):
+ """
+ 生成随机号码
+ :param num:数目
+ :param areas: 区域
+ :return:
+ """
+
+ headers = {
+ 'authority': 'api.uukit.com',
+ 'pragma': 'no-cache',
+ 'cache-control': 'no-cache',
+ 'accept': 'enote_app/json, text/javascript, */*; q=0.01',
+ 'origin': 'https://uutool.cn',
+ 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36',
+ 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
+ 'sec-fetch-site': 'cross-site',
+ 'sec-fetch-mode': 'cors',
+ 'referer': 'https://uutool.cn/phone-generate/',
+ 'accept-encoding': 'gzip, deflate, br',
+ 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8',
+ }
+
+ data = {
+ 'phone_num': num,
+ 'area': areas,
+ 'segment': '133,153,189,180,181,177,173,139,138,137,136,135,134,159,158,157,150,151,152,147,188,187,182,183,184,178,130,131,132,156,155,186,185,145,176'
+ }
+
+ response = requests.post('https://api.uukit.com/phone/generate_batch', headers=headers, data=data)
+
+ phones = json.loads(response.text).get('data').get('rows')
+
+ return phones
+
+
+if __name__ == '__main__':
+ # 手机号码个数
+ num = 100
+
+ # 全国所有城市名称和id编号
+ citys = get_all_citys()
+
+ city_name = input('请输入手机归属地:')
+
+ if city_name not in citys.keys():
+ city_name = '北京'
+
+ # 获取城市id
+ city_id = citys.get(city_name)
+
+ # 请输入要获取手机号码的归属地
+ phones = generate_phones(num, city_id)
+ print(phones)
diff --git "a/\346\211\271\351\207\217\347\224\237\346\210\220\346\211\213\346\234\272\345\217\267\347\240\201/utils/.DS_Store" "b/\346\211\271\351\207\217\347\224\237\346\210\220\346\211\213\346\234\272\345\217\267\347\240\201/utils/.DS_Store"
new file mode 100644
index 0000000..5008ddf
Binary files /dev/null and "b/\346\211\271\351\207\217\347\224\237\346\210\220\346\211\213\346\234\272\345\217\267\347\240\201/utils/.DS_Store" differ
diff --git "a/\346\211\271\351\207\217\347\224\237\346\210\220\346\211\213\346\234\272\345\217\267\347\240\201/utils/addr_utils.py" "b/\346\211\271\351\207\217\347\224\237\346\210\220\346\211\213\346\234\272\345\217\267\347\240\201/utils/addr_utils.py"
new file mode 100644
index 0000000..53dcd5f
--- /dev/null
+++ "b/\346\211\271\351\207\217\347\224\237\346\210\220\346\211\213\346\234\272\345\217\267\347\240\201/utils/addr_utils.py"
@@ -0,0 +1,68 @@
+#!/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: addr_utils.py
+@time: 2020-01-06 22:24
+@description:TODO
+"""
+
+import json
+import re
+
+import requests
+
+
+# 所有的id和城市名称数据
+
+def get_all_citys():
+ """
+ 获取所有的城市数据
+ :return:
+ """
+
+ headers = {
+ 'authority': 'uutool.cn',
+ 'pragma': 'no-cache',
+ 'cache-control': 'no-cache',
+ 'upgrade-insecure-requests': '1',
+ 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36',
+ 'sec-fetch-user': '?1',
+ 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
+ 'sec-fetch-site': 'none',
+ 'sec-fetch-mode': 'navigate',
+ 'accept-encoding': 'gzip, deflate, br',
+ 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8',
+ 'cookie': 'UM_distinctid=16f759fe6bd24b-0322efd0d180d8-1d376b5b-1aeaa0-16f759fe6beb69; CNZZDATA1275106188=191793625-1578225029-https%253A%252F%252Fwww.google.com%252F%7C1578316721',
+ }
+
+ resp = requests.get('https://uutool.cn/phone-generate/', headers=headers).text
+
+ re_rule = r'areaArr:(.+?)segmentArr:'
+
+ # 匹配换行符
+ result_data = re.findall(re_rule, resp, re.S)[0].strip()[:-1]
+
+ result = json.loads(result_data)
+
+ # 获取所有的省份
+ provices = result.keys()
+
+ # 所有的城市
+ citys = {}
+
+ for provice in provices:
+ current_citys = result.get(provice)
+ # citys.extend(current_citys)
+ for item in current_citys:
+ citys[item.get('name')] = item.get('id')
+
+ return citys
+
+# get_all_citys()
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/.DS_Store" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/.DS_Store"
new file mode 100644
index 0000000..ae82168
Binary files /dev/null and "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/.DS_Store" differ
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/.gitignore" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/.gitignore"
new file mode 100644
index 0000000..b3293a4
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/.gitignore"
@@ -0,0 +1,15 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
+.DS_Store
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/.idea/codeStyles/Project.xml" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/.idea/codeStyles/Project.xml"
new file mode 100644
index 0000000..ae78c11
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/.idea/codeStyles/Project.xml"
@@ -0,0 +1,113 @@
+
+
+
+
+
+
+
+
+
+ xmlns:android
+
+ ^$
+
+
+
+
+
+
+
+
+ xmlns:.*
+
+ ^$
+
+
+ BY_NAME
+
+
+
+
+
+
+ .*:id
+
+ http://schemas.android.com/apk/res/android
+
+
+
+
+
+
+
+
+ .*:name
+
+ http://schemas.android.com/apk/res/android
+
+
+
+
+
+
+
+
+ name
+
+ ^$
+
+
+
+
+
+
+
+
+ style
+
+ ^$
+
+
+
+
+
+
+
+
+ .*
+
+ ^$
+
+
+ BY_NAME
+
+
+
+
+
+
+ .*
+
+ http://schemas.android.com/apk/res/android
+
+
+ ANDROID_ATTRIBUTE_ORDER
+
+
+
+
+
+
+ .*
+
+ .*
+
+
+ BY_NAME
+
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/.idea/gradle.xml" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/.idea/gradle.xml"
new file mode 100644
index 0000000..674414f
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/.idea/gradle.xml"
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/.idea/misc.xml" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/.idea/misc.xml"
new file mode 100644
index 0000000..703e5d4
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/.idea/misc.xml"
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/.idea/runConfigurations.xml" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/.idea/runConfigurations.xml"
new file mode 100644
index 0000000..7f68460
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/.idea/runConfigurations.xml"
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/.project" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/.project"
new file mode 100644
index 0000000..aec280f
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/.project"
@@ -0,0 +1,17 @@
+
+
+ NoCollapseInput
+ Project NoCollapseInput created by Buildship.
+
+
+
+
+ org.eclipse.buildship.core.gradleprojectbuilder
+
+
+
+
+
+ org.eclipse.buildship.core.gradleprojectnature
+
+
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/.settings/org.eclipse.buildship.core.prefs" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/.settings/org.eclipse.buildship.core.prefs"
new file mode 100644
index 0000000..e889521
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/.settings/org.eclipse.buildship.core.prefs"
@@ -0,0 +1,2 @@
+connection.project.dir=
+eclipse.preferences.version=1
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/.vscode/settings.json" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/.vscode/settings.json"
new file mode 100644
index 0000000..e0f15db
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/.vscode/settings.json"
@@ -0,0 +1,3 @@
+{
+ "java.configuration.updateBuildConfiguration": "automatic"
+}
\ No newline at end of file
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/.classpath" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/.classpath"
new file mode 100644
index 0000000..eb19361
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/.classpath"
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/.gitignore" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/.gitignore"
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/.gitignore"
@@ -0,0 +1 @@
+/build
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/.project" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/.project"
new file mode 100644
index 0000000..ac485d7
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/.project"
@@ -0,0 +1,23 @@
+
+
+ app
+ Project app created by Buildship.
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.buildship.core.gradleprojectbuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.buildship.core.gradleprojectnature
+
+
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/.settings/org.eclipse.buildship.core.prefs" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/.settings/org.eclipse.buildship.core.prefs"
new file mode 100644
index 0000000..b1886ad
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/.settings/org.eclipse.buildship.core.prefs"
@@ -0,0 +1,2 @@
+connection.project.dir=..
+eclipse.preferences.version=1
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/build.gradle" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/build.gradle"
new file mode 100644
index 0000000..0bf342f
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/build.gradle"
@@ -0,0 +1,44 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 28
+ defaultConfig {
+ applicationId "com.xingag.preventrubbishapp"
+ minSdkVersion 21
+ targetSdkVersion 28
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ javaCompileOptions { annotationProcessorOptions { includeCompileClasspath = true } }
+ }
+
+ buildTypes {
+
+ debug {
+ minifyEnabled false
+ }
+
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility = 1.8
+ targetCompatibility = 1.8
+ }
+
+}
+
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'androidx.appcompat:appcompat:1.0.2'
+ implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.0'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
+ implementation 'com.wuhenzhizao:titlebar:1.1.4'
+ implementation 'com.google.android.material:material:1.0.0'
+ implementation 'com.google.code.gson:gson:2.8.6'
+}
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/proguard-rules.pro" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/proguard-rules.pro"
new file mode 100644
index 0000000..f1b4245
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/proguard-rules.pro"
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/androidTest/java/com/xingag/preventrubbishapp/ExampleInstrumentedTest.java" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/androidTest/java/com/xingag/preventrubbishapp/ExampleInstrumentedTest.java"
new file mode 100644
index 0000000..05797e4
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/androidTest/java/com/xingag/preventrubbishapp/ExampleInstrumentedTest.java"
@@ -0,0 +1,29 @@
+package com.xingag.preventrubbishapp;
+
+import android.content.Context;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest
+{
+ @Test
+ public void useAppContext()
+ {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+
+ assertEquals("com.xingag.preventrubbishapp", appContext.getPackageName());
+ }
+}
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/AndroidManifest.xml" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/AndroidManifest.xml"
new file mode 100644
index 0000000..6546f04
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/AndroidManifest.xml"
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/java/com/xingag/preventrubbishapp/App.java" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/java/com/xingag/preventrubbishapp/App.java"
new file mode 100644
index 0000000..787a3b0
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/java/com/xingag/preventrubbishapp/App.java"
@@ -0,0 +1,24 @@
+package com.xingag.preventrubbishapp;
+
+import android.app.Application;
+import android.content.Context;
+
+public class App extends Application
+{
+ private static App instance = null;
+
+ public static int phone_type = 0;
+
+ public static App getInstance()
+ {
+ return instance;
+ }
+
+ @Override
+ public void onCreate()
+ {
+ super.onCreate();
+ instance = this;
+ phone_type = BuildConfig.phone_type;
+ }
+}
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/java/com/xingag/preventrubbishapp/MainActivity.java" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/java/com/xingag/preventrubbishapp/MainActivity.java"
new file mode 100644
index 0000000..0d00f89
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/java/com/xingag/preventrubbishapp/MainActivity.java"
@@ -0,0 +1,82 @@
+package com.xingag.preventrubbishapp;
+
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.TextView;
+
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+
+import com.xingag.utils.AccessibilityUtil;
+
+public class MainActivity extends AppCompatActivity implements View.OnClickListener
+{
+
+ //包名和服务名称
+ private static final String PACKAGE_NAME = "com.xingag.preventrubbishapp";
+ private static final String SERVICE_NAME = "com.xingag.service.PreventService";
+
+ private AccessibilityUtil accessibilityUtil = null;
+
+ //状态
+ private TextView status_tv = null;
+
+ private Button open_service_btn = null;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ status_tv = findViewById(R.id.status_tv);
+ open_service_btn = findViewById(R.id.open_service_btn);
+ open_service_btn.setOnClickListener(this);
+
+ accessibilityUtil = new AccessibilityUtil(MainActivity.this,
+ PACKAGE_NAME, SERVICE_NAME);
+
+ //设置标题
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null)
+ {
+ actionBar.setTitle("不折叠服务");
+ }
+
+ //判断状态,如果没有开启,就跳到设置界面
+ openAccessibilityMet();
+ }
+
+ public void openAccessibilityMet()
+ {
+ //服务状态
+ boolean status = AccessibilityUtil.isAccessibilitySettingsOn(this, SERVICE_NAME);
+ if (!status)
+ {
+ accessibilityUtil.openSettingDialog();
+ }
+ }
+
+
+ @Override
+ protected void onResume()
+ {
+ super.onResume();
+ //判断服务状态
+ boolean status = AccessibilityUtil.isAccessibilitySettingsOn(this, SERVICE_NAME);
+ status_tv.setText(status ? "开启" : "关闭");
+ }
+
+ @Override
+ public void onClick(View view)
+ {
+ if (view.getId() == R.id.open_service_btn)
+ {
+ accessibilityUtil.openSettingPage();
+ }
+ }
+}
+
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/java/com/xingag/service/BaseService.java" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/java/com/xingag/service/BaseService.java"
new file mode 100644
index 0000000..2bb0f5a
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/java/com/xingag/service/BaseService.java"
@@ -0,0 +1,89 @@
+package com.xingag.service;
+
+import android.accessibilityservice.AccessibilityService;
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
+import android.content.ClipData;
+import android.content.ClipboardManager;
+import android.content.Context;
+import android.os.Build;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+
+import java.util.List;
+
+/***
+ * 无障碍服务的基类
+ */
+
+
+public class BaseService extends AccessibilityService
+{
+
+ @SuppressLint("StaticFieldLeak")
+ private static BaseService mInstance = null;
+
+
+ public static BaseService getInstance()
+ {
+ if (mInstance == null)
+ {
+ mInstance = new BaseService();
+ }
+ return mInstance;
+ }
+
+
+ @Override
+ public void onAccessibilityEvent(AccessibilityEvent event)
+ {
+
+ }
+
+ @Override
+ public void onInterrupt()
+ {
+
+ }
+
+
+ /**
+ * 模拟输入
+ *
+ * @param nodeInfo nodeInfo
+ * @param text text
+ */
+ public void inputText(AccessibilityNodeInfo nodeInfo, String text)
+ {
+ ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
+
+ Log.d("xag", "字符个数为:" + text.length());
+ for (int i = 0; i < text.length(); i++)
+ {
+ String temp = text.substring(0, i + 1);
+ Log.e("xag", "输入一次,输入内容是:" + temp);
+
+ //输入内容
+ Bundle arguments = new Bundle();
+ arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, temp);
+ nodeInfo.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments);
+
+ //下面可以控制输入的速度,这里设置间隔为0.1s
+ try
+ {
+ Thread.sleep(100);
+ } catch (InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+
+}
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/java/com/xingag/service/PreventService.java" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/java/com/xingag/service/PreventService.java"
new file mode 100644
index 0000000..cabf382
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/java/com/xingag/service/PreventService.java"
@@ -0,0 +1,131 @@
+package com.xingag.service;
+
+import android.accessibilityservice.AccessibilityService;
+import android.annotation.TargetApi;
+import android.content.Intent;
+import android.os.Build;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.widget.Toast;
+
+import com.xingag.utils.AppUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PreventService extends BaseService
+{
+ //所有的节点
+ public static List nodes = new ArrayList<>();
+
+ private static final String CLASS_NAME_SNS_UPLOAD = "com.tencent.mm.plugin.sns.ui.SnsUploadUI";
+
+ /**
+ * 连接服务成功后回调该方法
+ */
+ @Override
+ protected void onServiceConnected()
+ {
+ super.onServiceConnected();
+ //缓存中获取数据
+ Toast.makeText(PreventService.this, "连接服务成功",
+ Toast.LENGTH_SHORT).show();
+
+ stopSelf();
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId)
+ {
+ return super.onStartCommand(intent, flags, startId);
+ }
+
+ @Override
+ public void onAccessibilityEvent(AccessibilityEvent event)
+ {
+ //如果是朋友圈发布界面
+ String className = event.getClassName().toString();
+
+ Log.d("xag", "className:" + className);
+
+ if (TextUtils.equals(CLASS_NAME_SNS_UPLOAD, className))
+ {
+ Log.e("xag", "朋友圈发布界面");
+
+ //获取剪切板的内容
+ String content = AppUtil.getClipBoardContent(getApplicationContext());
+
+ if (!TextUtils.isEmpty(content))
+ {
+ Log.d("xag", "剪切板内容是:" + content);
+ inputContent(event, content);
+ } else
+ {
+ Log.d("xag", "剪切板内容为空");
+ }
+ }
+
+ }
+
+
+ /***
+ * 回复消息
+ * @param event
+ */
+ private void inputContent(AccessibilityEvent event, String content)
+ {
+ //获取输入框元素
+ //方式一
+// AccessibilityNodeInfo chat_edit = findViewByID("com.tencent.mm:id/d41");
+
+ //方式二
+ nodes.clear();
+ AppUtil.getAllNodes(getRootInActiveWindow());
+ AccessibilityNodeInfo chat_edit = findNodeInfoByClassName("android.widget.EditText");
+
+ //把文本输入到输入框内
+ inputText(chat_edit, content);
+ }
+
+
+ /***
+ * 通过类名查找元素
+ * @param className
+ * @return
+ */
+ public AccessibilityNodeInfo findNodeInfoByClassName(String className)
+ {
+ for (int i = 0; i < nodes.size(); i++)
+ {
+ //当前节点元素及classname
+ AccessibilityNodeInfo currentNode = nodes.get(i);
+ String tagClassName = currentNode.getClassName().toString();
+
+ Log.d("xag", "tagClassName:" + tagClassName);
+ if (TextUtils.equals(tagClassName, className))
+ {
+ Log.d("xag", "元素找到了");
+ return currentNode;
+ }
+ }
+ Log.d("xag", "元素没找到");
+ return null;
+ }
+
+
+ @Override
+ public void onInterrupt()
+ {
+ Log.d("xag", "无障碍服务被打断");
+ }
+
+
+ @Override
+ public void onDestroy()
+ {
+ super.onDestroy();
+ Log.d("xag", "无障碍服务销毁");
+ }
+}
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/java/com/xingag/utils/AccessibilityUtil.java" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/java/com/xingag/utils/AccessibilityUtil.java"
new file mode 100644
index 0000000..94c0378
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/java/com/xingag/utils/AccessibilityUtil.java"
@@ -0,0 +1,141 @@
+package com.xingag.utils;
+
+import android.app.ActivityManager;
+import android.app.AlertDialog;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.provider.Settings;
+import android.text.TextUtils;
+
+import com.xingag.preventrubbishapp.R;
+
+import java.util.List;
+
+public class AccessibilityUtil
+{
+ private Context mContext;
+ private String locPackageName;
+ private String accessibilityClassAbsolutePath;
+
+ /**
+ * 构造方法
+ *
+ * @param mContext
+ * @param accessibilityClassAbsolutePath
+ */
+ public AccessibilityUtil(Context mContext, String locPackageName,
+ String accessibilityClassAbsolutePath
+ )
+ {
+ this.mContext = mContext;
+ this.locPackageName = locPackageName;
+ this.accessibilityClassAbsolutePath = accessibilityClassAbsolutePath;
+ }
+
+
+ /**
+ * 判断是否有辅助功能权限
+ *
+ * @return 是否开启服务
+ */
+ public static boolean isAccessibilitySettingsOn(Context context, String className)
+ {
+ if (context == null)
+ {
+ return false;
+ }
+ ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+ // 获取正在运行的服务列表
+ List runningServices =
+ activityManager.getRunningServices(300);
+ for (int i = 0; i < runningServices.size(); i++)
+ {
+ ComponentName service = runningServices.get(i).service;
+ if (service.getClassName().equals(className))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean isAccessibilitySettingsOn()
+ {
+ boolean isAccessibilityOn = false;
+ try
+ {
+ int accessibilityEnabled = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED);
+ TextUtils.SimpleStringSplitter mStringColonSplitter = new TextUtils.SimpleStringSplitter(':');
+ if (accessibilityEnabled == 1)
+ {
+ String settingValue = Settings.Secure.getString(mContext.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
+ if (settingValue != null)
+ {
+ TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
+ splitter.setString(settingValue);
+ while (splitter.hasNext())
+ {
+ String accessabilityService = splitter.next();
+ //辅助服务关键路径,格式如"com.corget/com.corget.service.UnAccessibilityService"
+ String service = locPackageName + "/" + accessibilityClassAbsolutePath;
+ if (accessabilityService.equalsIgnoreCase(service))
+ {
+ isAccessibilityOn = true;
+ }
+ }
+ }
+ }
+ } catch (Settings.SettingNotFoundException e)
+ {
+ e.printStackTrace();
+ }
+ return isAccessibilityOn;
+ }
+
+
+ public void openSettingDialog()
+ {
+ AlertDialog.Builder mDialogBuilder = new AlertDialog.Builder(mContext);
+
+ mDialogBuilder.setIcon(R.mipmap.ic_launcher);
+ mDialogBuilder.setTitle("警告");
+ mDialogBuilder.setMessage("防折叠服务没有开启,请先开启服务");
+ mDialogBuilder.setCancelable(false);
+ mDialogBuilder.setPositiveButton("Sure",
+ new DialogInterface.OnClickListener()
+ {
+ @Override
+ public void onClick(DialogInterface dialog, int which)
+ {
+ dialog.dismiss();
+ openSettingPage();
+ }
+ });
+ mDialogBuilder.setNegativeButton("Cancel",
+ new DialogInterface.OnClickListener()
+ {
+ @Override
+ public void onClick(DialogInterface dialog, int which)
+ {
+ dialog.dismiss();
+ }
+ });
+ mDialogBuilder.create().show();
+ }
+
+ /***
+ * 打开设置界面
+ */
+ public void openSettingPage()
+ {
+ Intent startIntent = new Intent(
+ Settings.ACTION_ACCESSIBILITY_SETTINGS);
+ mContext.startActivity(startIntent);
+ mContext.sendBroadcast(new Intent()
+ .setAction("com.xingag.setting.dialog"));
+ }
+
+
+}
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/java/com/xingag/utils/AppUtil.java" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/java/com/xingag/utils/AppUtil.java"
new file mode 100644
index 0000000..74253f2
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/java/com/xingag/utils/AppUtil.java"
@@ -0,0 +1,56 @@
+package com.xingag.utils;
+
+import android.content.ClipData;
+import android.content.ClipboardManager;
+import android.content.Context;
+import android.util.Log;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import com.xingag.service.PreventService;
+
+import static android.content.Context.CLIPBOARD_SERVICE;
+
+
+public class AppUtil
+{
+
+ /***
+ * 获取剪切板上的内容
+ * @return
+ */
+ public static String getClipBoardContent(Context context)
+ {
+ ClipboardManager cm = (ClipboardManager) context.getSystemService(CLIPBOARD_SERVICE);
+ ClipData cd2 = cm.getPrimaryClip();
+ String result = "";
+ try
+ {
+ result = cd2.getItemAt(0).getText().toString();
+ } catch (Exception e)
+ {
+ //pass
+ Log.d("xag", "产生异常了。。。。");
+ }
+ return result;
+ }
+
+ /***
+ * 获取当前页面所有的元素
+ * @param node
+ */
+ public static void getAllNodes(AccessibilityNodeInfo node)
+ {
+ int count = node.getChildCount();
+
+ if (count == 0)
+ {
+ PreventService.nodes.add(node);
+ } else
+ {
+ for (int i = 0; i < count; i++)
+ {
+ getAllNodes(node.getChild(i));
+ }
+ }
+ }
+}
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/drawable-v24/ic_launcher_foreground.xml" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/drawable-v24/ic_launcher_foreground.xml"
new file mode 100644
index 0000000..1f6bb29
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/drawable-v24/ic_launcher_foreground.xml"
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/drawable/btn_bg.xml" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/drawable/btn_bg.xml"
new file mode 100644
index 0000000..1f6bdb7
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/drawable/btn_bg.xml"
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/drawable/ic_launcher_background.xml" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/drawable/ic_launcher_background.xml"
new file mode 100644
index 0000000..0d025f9
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/drawable/ic_launcher_background.xml"
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/layout/activity_main.xml" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/layout/activity_main.xml"
new file mode 100644
index 0000000..143762a
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/layout/activity_main.xml"
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/layout/dialog_bottom_alertmsg.xml" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/layout/dialog_bottom_alertmsg.xml"
new file mode 100755
index 0000000..8632fe4
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/layout/dialog_bottom_alertmsg.xml"
@@ -0,0 +1,33 @@
+
+
+
+
+
+
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/layout/item_app_select.xml" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/layout/item_app_select.xml"
new file mode 100644
index 0000000..cbeef49
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/layout/item_app_select.xml"
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/layout/title_bar.xml" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/layout/title_bar.xml"
new file mode 100644
index 0000000..24c09f2
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/layout/title_bar.xml"
@@ -0,0 +1,10 @@
+
+
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/mipmap-xhdpi/ic_back.png" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/mipmap-xhdpi/ic_back.png"
new file mode 100644
index 0000000..5224963
Binary files /dev/null and "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/mipmap-xhdpi/ic_back.png" differ
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/mipmap-xhdpi/ic_launcher.png" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/mipmap-xhdpi/ic_launcher.png"
new file mode 100644
index 0000000..12c8d77
Binary files /dev/null and "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/mipmap-xhdpi/ic_launcher.png" differ
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/mipmap-xhdpi/ic_sure.png" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/mipmap-xhdpi/ic_sure.png"
new file mode 100644
index 0000000..61fef12
Binary files /dev/null and "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/mipmap-xhdpi/ic_sure.png" differ
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/values/colors.xml" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/values/colors.xml"
new file mode 100644
index 0000000..69b2233
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/values/colors.xml"
@@ -0,0 +1,6 @@
+
+
+ #008577
+ #00574B
+ #D81B60
+
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/values/strings.xml" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/values/strings.xml"
new file mode 100644
index 0000000..348bfa1
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/values/strings.xml"
@@ -0,0 +1,5 @@
+
+ 防折叠
+ 防止折叠服务\n1、防止微信朋友圈粘贴的内容被折叠\n2、操作前,请先开启服务\n3、如果失效,请重启服务
+ 1、防止微信朋友圈粘贴的内容被折叠\n2、操作前,请先开启服务\n3、如果失效,请重启服务
+
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/values/styles.xml" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/values/styles.xml"
new file mode 100644
index 0000000..5885930
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/values/styles.xml"
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/xml/accessibility_settings.xml" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/xml/accessibility_settings.xml"
new file mode 100644
index 0000000..7ec208b
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/main/res/xml/accessibility_settings.xml"
@@ -0,0 +1,9 @@
+
+
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/test/java/com/xingag/preventrubbishapp/ExampleUnitTest.java" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/test/java/com/xingag/preventrubbishapp/ExampleUnitTest.java"
new file mode 100644
index 0000000..d907752
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/app/src/test/java/com/xingag/preventrubbishapp/ExampleUnitTest.java"
@@ -0,0 +1,19 @@
+package com.xingag.preventrubbishapp;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest
+{
+ @Test
+ public void addition_isCorrect()
+ {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/build.gradle" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/build.gradle"
new file mode 100644
index 0000000..cfdb2c0
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/build.gradle"
@@ -0,0 +1,43 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ google()
+ jcenter()
+
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.5.3'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ jcenter()
+ maven { url 'https://jitpack.io' }
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
+
+
+ext {
+
+ compileSdkVersion = 28
+
+ buildToolsVersion = "28.0.2"
+
+ minSdkVersion = 21
+
+ targetSdkVersion = 21
+
+ versionCode = 100
+
+ versionName = "1.0.0"
+}
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/gradle.properties" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/gradle.properties"
new file mode 100644
index 0000000..199d16e
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/gradle.properties"
@@ -0,0 +1,20 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Automatically convert third-party libraries to use AndroidX
+android.enableJetifier=true
+
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/gradle/wrapper/gradle-wrapper.jar" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/gradle/wrapper/gradle-wrapper.jar"
new file mode 100644
index 0000000..f6b961f
Binary files /dev/null and "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/gradle/wrapper/gradle-wrapper.jar" differ
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/gradle/wrapper/gradle-wrapper.properties" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/gradle/wrapper/gradle-wrapper.properties"
new file mode 100644
index 0000000..30845ae
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/gradle/wrapper/gradle-wrapper.properties"
@@ -0,0 +1,6 @@
+#Tue Jan 14 10:52:15 CST 2020
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/gradlew" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/gradlew"
new file mode 100755
index 0000000..cccdd3d
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/gradlew"
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/gradlew.bat" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/gradlew.bat"
new file mode 100644
index 0000000..f955316
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/gradlew.bat"
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/readme.md" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/readme.md"
new file mode 100644
index 0000000..a63bf1a
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/readme.md"
@@ -0,0 +1,2 @@
+# 帮助
+防折叠服务
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/settings.gradle" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/settings.gradle"
new file mode 100644
index 0000000..d336466
--- /dev/null
+++ "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/NoCollapseInput/settings.gradle"
@@ -0,0 +1,2 @@
+include ':app'
+rootProject.name='NoCollapseInput'
diff --git "a/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/\351\230\262\346\212\230\345\217\240\346\234\215\345\212\241.apk" "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/\351\230\262\346\212\230\345\217\240\346\234\215\345\212\241.apk"
new file mode 100644
index 0000000..5556a32
Binary files /dev/null and "b/\346\234\213\345\217\213\345\234\210\351\230\262\346\212\230\345\217\240/\351\230\262\346\212\230\345\217\240\346\234\215\345\212\241.apk" differ
diff --git "a/\350\247\206\351\242\221\347\211\271\346\256\212\345\244\204\347\220\206.py" "b/\350\247\206\351\242\221\347\211\271\346\256\212\345\244\204\347\220\206.py"
new file mode 100644
index 0000000..bac8dcd
--- /dev/null
+++ "b/\350\247\206\351\242\221\347\211\271\346\256\212\345\244\204\347\220\206.py"
@@ -0,0 +1,153 @@
+#!/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-06-15 09:35
+@description:公众号:AirPython
+"""
+
+import hashlib
+
+from moviepy.editor import *
+
+
+def get_file_md5(file_path):
+ """
+ 获取文件的MD5值
+ :param file_path:
+ :return:
+ """
+ with open(file_path, 'rb') as file:
+ temp_md5 = hashlib.md5()
+ temp_md5.update(file.read())
+ hash_code = str(temp_md5.hexdigest()).lower()
+ return hash_code
+
+
+def modify_file_md5(file_path):
+ """
+ 修改文件的md5值
+ :param file_path:
+ :return:
+ """
+ with open(file_path, 'a') as file:
+ file.write("####&&&&")
+
+
+def get_file_md5_2(file_path):
+ """
+ 分段读取,获取文件的md5值
+ :param file_path:
+ :return:
+ """
+ with open(file_path, 'rb') as file:
+ md5_obj = hashlib.md5()
+ while True:
+ buffer = file.read(8096)
+ if not buffer:
+ break
+ md5_obj.update(buffer)
+ hash_code = md5_obj.hexdigest()
+ md5 = str(hash_code).lower()
+ return md5
+
+
+def handle_frame(image_frame):
+ """
+ 处理图片帧
+ :param image_frame:图片帧
+ :return:
+ """
+ image_frame_result = image_frame * 1.2
+ # 如果颜色值超过255,直接设置为255
+ image_frame_result[image_frame_result > 255] = 255
+ return image_frame_result
+
+
+def increase_video_brightness(file_path):
+ """
+ 增加视频整体亮度
+ :param file_path:源视频路径
+ :return:
+ """
+ video = VideoFileClip(file_path)
+ result = video.fl_image(handle_frame)
+
+ file_path_new = "/Users/xingag/Desktop/new.mp4"
+ result.write_videofile(file_path_new)
+
+
+def increase_video_brightness2(file_path):
+ """
+ 增加视频整体亮度2
+ :param file_path:源视频路径
+ :return:
+ """
+ # 调整系数值
+ coefficient_value = 1.2
+
+ video = VideoFileClip(file_path)
+ file_path_new = "/Users/xingag/Desktop/new.mp4"
+ video.fx(vfx.colorx, coefficient_value).write_videofile(file_path_new)
+
+
+def decrease_video_brightness(file_path):
+ """
+ 降低亮度
+ :param file_path:
+ :return:
+ """
+ # 调整系数值
+ coefficient_value = 0.8
+
+ video = VideoFileClip(file_path)
+ file_path_new = "/Users/xingag/Desktop/new.mp4"
+ video.fx(vfx.colorx, coefficient_value).write_videofile(file_path_new)
+
+
+def change_video_bhd(file_path):
+ """
+ 黑白处理
+ :param file_path:
+ :return:
+ """
+ video = VideoFileClip(file_path)
+ file_path_new = "/Users/xingag/Desktop/new.mp4"
+ video.fx(vfx.blackwhite).write_videofile(file_path_new)
+
+
+def change_video_todo(file_path):
+ """
+ 先获取图片帧,单张进行处理,然后合成
+ :param file_path:
+ :return:
+ """
+ pass
+
+
+if __name__ == "__main__":
+ file_path = r'/Users/xingag/Desktop/1.mp4'
+ # print(get_file_md5_2(file_path))
+ # modify_file_md5(file_path)
+ # print(get_file_md5_2(file_path))
+
+ # 2、增加亮度
+ # increase_video_brightness(file_path)
+ # increase_video_brightness2(file_path)
+
+ # 降低亮度
+ # decrease_video_brightness(file_path)
+
+ # 3、饱和度
+ change_video_bhd(file_path)
+
+
+
+# 注意:更多复杂的操作可以参考之前的文章
\ No newline at end of file
diff --git "a/\351\237\263\351\242\221\345\244\204\347\220\206/\351\237\263\351\242\221\345\260\276\351\203\250\345\244\204\347\220\206.py" "b/\351\237\263\351\242\221\345\244\204\347\220\206/\351\237\263\351\242\221\345\260\276\351\203\250\345\244\204\347\220\206.py"
new file mode 100644
index 0000000..d6bd7ef
--- /dev/null
+++ "b/\351\237\263\351\242\221\345\244\204\347\220\206/\351\237\263\351\242\221\345\260\276\351\203\250\345\244\204\347\220\206.py"
@@ -0,0 +1,57 @@
+#!/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
+@time: 2021-01-02 09:59
+@description:TODO
+"""
+
+from pydub import AudioSegment
+from pydub.playback import play
+
+video_path = './raw.mp4'
+
+
+def speed_change(sound, speed=1.0):
+ """
+ 改变音频的速度
+ 参考:https://www.thinbug.com/q/51434897
+ :param sound:
+ :param speed:
+ :return:
+ """
+ sound_with_altered_frame_rate = sound._spawn(sound.raw_data, overrides={
+ "frame_rate": int(sound.frame_rate * speed)
+ })
+ return sound_with_altered_frame_rate.set_frame_rate(sound.frame_rate)
+
+
+# 注意:加载视频不需要指定format
+audio_sgement = AudioSegment.from_file(video_path)
+
+# 截取尾部内容
+audio_end = audio_sgement[70 * 1000:70 * 1000 + 3000]
+
+# 变慢速度,具体根据视频速度去调整
+audio_end2 = speed_change(audio_end, 0.55)
+
+# 合并两段音频
+audio_result = audio_end + audio_end2
+
+# 尾部淡出处理
+audio_result.fade_out(1000)
+
+# 实时播放,方便调试
+# play(audio_result)
+
+# 视频导出
+audio_result.export("result.wav", format='wav')
+
+