-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
123 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -127,3 +127,8 @@ dmypy.json | |
|
||
# Pyre type checker | ||
.pyre/ | ||
.idea/ | ||
/build | ||
/dist | ||
*.spec | ||
test* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,21 @@ | ||
# videoSplitter | ||
视频切分工具 | ||
|
||
借助`ffmpeg`和`ffprobe`,把视频分为两半。 | ||
|
||
## 使用说明(exe) | ||
|
||
1. 在[Releases](https://github.com/zhimengsub/videoSplitter/releases)中下载最新版本可执行文件 | ||
|
||
2. 把`videoSplitter.exe`与`ffmpeg.exe`、`ffprobe.exe`放入同一目录下(或将`ffmpeg.exe`、`ffprobe.exe`所在目录添加入PATH) | ||
|
||
3. 把待处理视频拖放到`videoSplitter.exe`上即可,或使用命令行执行`videoSplitter.exe <视频文件路径>` | ||
|
||
## 使用说明(py) | ||
|
||
1. 安装[Python](https://www.python.org/downloads/)(注意3.9及以上版本不再支持win7) | ||
|
||
1. 下载本仓库代码到本地 | ||
|
||
2. 把`videoSplitter.py`与`ffmpeg.exe`、`ffprobe.exe`放入同一目录下(或将`ffmpeg.exe`、`ffprobe.exe`所在目录添加入PATH) | ||
|
||
3. 把待处理视频拖放到`videoSplitter.py`上即可,或使用命令行执行`python videoSplitter.py <视频文件路径>` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import argparse | ||
import os | ||
import sys | ||
import subprocess | ||
import traceback | ||
|
||
VER = 'v0.2' | ||
desc = '把视频分割为两半 by 谢耳朵 ' + VER | ||
|
||
BASE = os.path.dirname(__file__ if not hasattr(sys, 'frozen') else sys.executable) | ||
os.chdir(BASE) | ||
ffprobe = 'ffprobe' | ||
ffmpeg = 'ffmpeg' | ||
|
||
def initparser(): | ||
parser = argparse.ArgumentParser(description=desc) | ||
parser.add_argument('input', help='待分割视频') | ||
parser.add_argument('-q', '--quit', action='store_true', help='结束后不暂停程序直接退出,方便命令行调用。不加该参数程序结束时会暂停。') | ||
return parser | ||
|
||
def mkOutfilenames(infile: str): | ||
infile = os.path.abspath(infile) | ||
path, suf = os.path.splitext(infile) | ||
dirname, name = os.path.split(path) | ||
out1 = os.path.join(dirname, name+'_1'+suf) | ||
out2 = os.path.join(dirname, name+'_2'+suf) | ||
return out1, out2 | ||
|
||
def getLength(infile: str) -> float: | ||
'''return secs in float''' | ||
# def t2s(t): | ||
# h, m, s = t.strip().split(":") | ||
# return int(h) * 3600 + int(m) * 60 + int(s) | ||
out = subprocess.check_output([ffprobe, '-v', 'error', '-select_streams', 'v:0', '-show_entries', 'stream=duration', '-of', 'default=noprint_wrappers=1:nokey=1', infile]).decode('utf8') | ||
#! 就算文件不存在返回码也是0,但输出为空 | ||
if out: | ||
return float(out.strip()) | ||
return -1 | ||
|
||
# res = re.search(r'Duration: ([\d:]+)', out) | ||
# if not res or not res[1]: | ||
# raise Exception('\n错误:获取视频时长失败,正则匹配错误!') | ||
# duration = res[1] # 00:25:25 | ||
# secs = t2s(duration) | ||
# return secs | ||
|
||
def dosplit(first, mid, infile, outfile): | ||
if first: | ||
res = subprocess.run(["ffmpeg", '-t', str(mid), '-i', infile, '-c', 'copy', '-y', outfile], capture_output=True) | ||
else: | ||
res = subprocess.run(["ffmpeg", '-ss', str(mid), '-i', infile, '-c', 'copy', '-y', outfile], capture_output=True) | ||
#! 就算正常运行 输出也在stderr里 | ||
if res.returncode != 0: | ||
print(res.stderr.decode('utf8')) | ||
print('错误:切割失败,请检查报错信息!') | ||
return False | ||
return True | ||
|
||
def splitVideo(infile: str): | ||
try: | ||
secs = getLength(infile) | ||
assert secs >= 0 | ||
print('视频时长', secs, '秒') | ||
except (AssertionError, Exception): | ||
raise Exception('\n错误:获取视频时长失败!') | ||
|
||
mid = secs//2 | ||
outfile1, outfile2 = mkOutfilenames(infile) | ||
|
||
print('\n切分前半部分...') | ||
#print(cmd) | ||
res = dosplit(True, mid, infile, outfile1) # first half | ||
if not res: return '', '' | ||
|
||
print('\n切分后半部分...') | ||
res = dosplit(False, mid, infile, outfile2) # second half | ||
# subprocess.check_output([*cmd.split(' ')]) | ||
if not res: return '', '' | ||
|
||
return outfile1, outfile2 | ||
|
||
def main(): | ||
parser = initparser() | ||
args = parser.parse_args() | ||
try: | ||
out1, out2 = splitVideo(args.input) | ||
if out1 and out2: | ||
print('\n成功!已输出至', out1, out2, sep='\n') | ||
except Exception as err: | ||
print('\n发生未预料错误!\n') | ||
traceback.print_exc() | ||
finally: | ||
if not args.quit: | ||
print() | ||
os.system('pause') | ||
|
||
if __name__ == '__main__': | ||
main() |