avtb 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
avtb-0.0.1/PKG-INFO ADDED
@@ -0,0 +1,88 @@
1
+ Metadata-Version: 2.4
2
+ Name: avtb
3
+ Version: 0.0.1
4
+ Summary: Just handy python wrappers to call ffmpeg/video2x executables :)
5
+ Home-page: https://gitee.com/kahsolt/avtb
6
+ Author: Kahsolt
7
+ Author-email: kahsolt@qq.com
8
+ License: MIT
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Environment :: Console
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Natural Language :: English
13
+ Classifier: Programming Language :: Python
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Topic :: Multimedia
16
+ Classifier: Topic :: Multimedia :: Sound/Audio
17
+ Classifier: Topic :: Multimedia :: Video
18
+ Classifier: Topic :: Utilities
19
+ Requires-Python: >=3.10.0
20
+ Description-Content-Type: text/markdown
21
+ Dynamic: author
22
+ Dynamic: author-email
23
+ Dynamic: classifier
24
+ Dynamic: description
25
+ Dynamic: description-content-type
26
+ Dynamic: home-page
27
+ Dynamic: license
28
+ Dynamic: requires-python
29
+ Dynamic: summary
30
+
31
+
32
+ ### Audio/Video ToolBox (avtb)
33
+
34
+ Just handy python wrappers to call ffmpeg/video2x executables :)
35
+
36
+ ----
37
+
38
+ ### Install
39
+
40
+ ```shell
41
+ # install from PyPI
42
+ pip install avtb
43
+
44
+ # or install as local repo
45
+ git clone https://gitee.com/kahsolt/avtb.git
46
+ cd avtb
47
+ pip install -e .
48
+
49
+ # download ffmpeg & video2x, add to PATH
50
+ # ffmpeg: https://ffmpeg.org/download.html
51
+ # video2x: https://docs.video2x.org/installing/windows-qt6.html
52
+ ```
53
+
54
+ ### Usage
55
+
56
+ ⚪ Use via command line
57
+
58
+ ```shell
59
+ # benchmark with ffmepg
60
+ python -m avtb.benchmark.ffmpeg_encoder -I 1080p.mp4 -C libx264
61
+ python -m avtb.benchmark.ffmpeg_encoder -I 1080p.mp4 -C h264_nvenc
62
+ python -m avtb.benchmark.ffmpeg_encoder -I 1080p.mp4 -C h264_amf
63
+
64
+ # benchmark with video2x
65
+ python -m avtb.benchmark.video2x -S 720p.mp4 -F 1080p.mp4 -C libx264 --x2_only
66
+ python -m avtb.benchmark.video2x -S 720p.mp4 -F 1080p.mp4 -C h264_nvenc --x2_only
67
+
68
+ # batch video super-resolution
69
+ python -m avtb.tools.video_sr -I src/ -O out/ -P realcugan -M models-se -S 1080p
70
+ # video quality assessment
71
+ python -m avtb.tools.vmaf original.mp4 compressed.mp4
72
+ # merge ass subtitle (JP + CN)
73
+ python -m avtb.tools.ass_merge jp.ass cn.ass -O merged.ass
74
+ ```
75
+
76
+ ⚪ Use via API
77
+
78
+ ```python
79
+ from avtb import *
80
+
81
+ print(get_ffmpeg_version())
82
+
83
+ run_ffmpeg_libx264('fin.mp4', 'fpout.mp4', preset='slower', crf=23)
84
+ metrics = run_ffmpeg_evaluate('fin.mp4', 'fpout.mp4')
85
+ print(metrics)
86
+
87
+ run_video2x_realesrgan('lowres.mp4', 'hires.mp4', model='realesr-animevideov3', factor=2)
88
+ ```
avtb-0.0.1/README.md ADDED
@@ -0,0 +1,57 @@
1
+ ### Audio/Video ToolBox (avtb)
2
+
3
+ Just handy python wrappers to call ffmpeg/video2x executables :)
4
+
5
+ ----
6
+
7
+ ### Install
8
+
9
+ ```shell
10
+ # install from PyPI
11
+ pip install avtb
12
+
13
+ # or install as local repo
14
+ git clone https://gitee.com/kahsolt/avtb.git
15
+ cd avtb
16
+ pip install -e .
17
+
18
+ # download ffmpeg & video2x, add to PATH
19
+ # ffmpeg: https://ffmpeg.org/download.html
20
+ # video2x: https://docs.video2x.org/installing/windows-qt6.html
21
+ ```
22
+
23
+ ### Usage
24
+
25
+ ⚪ Use via command line
26
+
27
+ ```shell
28
+ # benchmark with ffmepg
29
+ python -m avtb.benchmark.ffmpeg_encoder -I 1080p.mp4 -C libx264
30
+ python -m avtb.benchmark.ffmpeg_encoder -I 1080p.mp4 -C h264_nvenc
31
+ python -m avtb.benchmark.ffmpeg_encoder -I 1080p.mp4 -C h264_amf
32
+
33
+ # benchmark with video2x
34
+ python -m avtb.benchmark.video2x -S 720p.mp4 -F 1080p.mp4 -C libx264 --x2_only
35
+ python -m avtb.benchmark.video2x -S 720p.mp4 -F 1080p.mp4 -C h264_nvenc --x2_only
36
+
37
+ # batch video super-resolution
38
+ python -m avtb.tools.video_sr -I src/ -O out/ -P realcugan -M models-se -S 1080p
39
+ # video quality assessment
40
+ python -m avtb.tools.vmaf original.mp4 compressed.mp4
41
+ # merge ass subtitle (JP + CN)
42
+ python -m avtb.tools.ass_merge jp.ass cn.ass -O merged.ass
43
+ ```
44
+
45
+ ⚪ Use via API
46
+
47
+ ```python
48
+ from avtb import *
49
+
50
+ print(get_ffmpeg_version())
51
+
52
+ run_ffmpeg_libx264('fin.mp4', 'fpout.mp4', preset='slower', crf=23)
53
+ metrics = run_ffmpeg_evaluate('fin.mp4', 'fpout.mp4')
54
+ print(metrics)
55
+
56
+ run_video2x_realesrgan('lowres.mp4', 'hires.mp4', model='realesr-animevideov3', factor=2)
57
+ ```
@@ -0,0 +1,5 @@
1
+ from avtb.utils import *
2
+ from avtb.device import *
3
+
4
+ from avtb.engines.ffmpeg import *
5
+ from avtb.engines.video2x import *
@@ -0,0 +1,159 @@
1
+ #!/usr/bin/env python3
2
+ # Author: Armit
3
+ # Create Time: 2026/09/15
4
+
5
+ # 穷举指定编码器的配置参数,并绘制质量-体积-速度参考图
6
+ # libx264: 用于最终成品导出,以取得最高质量+最大压缩,速度x1.5/x4
7
+ # h264_nvenc: 用于素材预处理,质量与libx264极其相近,文件略大10%,速度x7
8
+ # h264_amf: 用于快速预览,质量垃圾,体积大,速度x4;纯废物
9
+
10
+ import json
11
+ import shutil
12
+ from pathlib import Path
13
+ from pprint import pprint
14
+ from datetime import datetime
15
+ from time import perf_counter
16
+ from dataclasses import asdict
17
+ from argparse import ArgumentParser
18
+ from traceback import print_exc
19
+ from typing import Callable
20
+
21
+ from avtb.engines.ffprobe import get_video_info
22
+ from avtb.engines.ffmpeg import run_ffmpeg_libx264, run_ffmpeg_h264_nvenc, run_ffmpeg_h264_amf
23
+ from avtb.engines.ffmpeg import get_ffmpeg_version, run_ffmpeg_evaluate
24
+ from avtb.engines.ffmpeg_out_parser import parse_bench_stats
25
+ from avtb.utils import TMP_PATH, DATA_PATH, HOSTNAME
26
+
27
+ ENCODERS = [
28
+ # h264
29
+ 'libx264',
30
+ 'h264_nvenc',
31
+ 'h264_amf',
32
+ # h265
33
+ 'libx265',
34
+ 'hevc_nvenc',
35
+ 'hevc_amf',
36
+ # av1
37
+ 'av1_nvenc',
38
+ 'av1_amf',
39
+ # vp8
40
+ 'libvpx',
41
+ # vp9
42
+ 'libvpx_vp9',
43
+ ]
44
+
45
+
46
+ def iter_libx264_cfgs():
47
+ for preset in ['faster', 'fast', 'medium', 'slow', 'slower', 'veryslow']:
48
+ for crf in list(range(13, 51+1, 2)):
49
+ cfgs = (preset, crf)
50
+ runcmd_gen = lambda fpi, fpo: run_ffmpeg_libx264(fpi, fpo, preset=preset, crf=crf, benchmark=True)
51
+ yield cfgs, runcmd_gen
52
+
53
+ def iter_h264_nvenc_cfgs():
54
+ for preset in ['medium', 'slow', 'p4', 'p5', 'p6', 'p7']:
55
+ for cq in list(range(17, 51+1, 2)):
56
+ cfgs = (preset, cq)
57
+ runcmd_gen = lambda fpi, fpo: run_ffmpeg_h264_nvenc(fpi, fpo, preset=preset, cq=cq, benchmark=True)
58
+ yield cfgs, runcmd_gen
59
+
60
+ def iter_h264_amf_cfgs():
61
+ for preset in ['balanced', 'quality']:
62
+ for qvbr_quality_level in [0] + list(range(1, 51+1, 2)):
63
+ cfgs = (preset, qvbr_quality_level)
64
+ runcmd_gen = lambda fpi, fpo: run_ffmpeg_h264_amf(fpi, fpo, preset=preset, qvbr_quality_level=qvbr_quality_level, benchmark=True)
65
+ yield cfgs, runcmd_gen
66
+
67
+
68
+ def run_xcode_and_eval(fpi:Path, fpo:Path, cfgs:tuple, runcmd_gen:Callable):
69
+ ts_start = perf_counter()
70
+ p = runcmd_gen(fpi, fpo)
71
+ ts_end = perf_counter()
72
+ timecost = ts_end - ts_start
73
+
74
+ bench_stats = parse_bench_stats(p)
75
+
76
+ vinfo_fpi = get_video_info(fpi)
77
+ vinfo_fpo = get_video_info(fpo)
78
+ metrics = run_ffmpeg_evaluate(fpi, fpo, fast_mode=args.fast_eval)
79
+ metrics = asdict(metrics)
80
+ metrics['bitr'] = vinfo_fpo.bit_rate / vinfo_fpi.bit_rate
81
+ metrics['zipr'] = vinfo_fpo.fsize / vinfo_fpi.fsize
82
+
83
+ Path(fpo).unlink(missing_ok=True)
84
+
85
+ return {
86
+ 'cfgs': cfgs,
87
+ 'timecost': timecost,
88
+ 'metrics': metrics,
89
+ 'bench_stats': bench_stats,
90
+ }
91
+
92
+ def run(args):
93
+ ffmpeg_ver = get_ffmpeg_version()
94
+
95
+ # 测试文件拷贝到临时目录(内存盘)
96
+ fp = args.input
97
+ fpi = TMP_PATH / f'benchmark_ffmpeg_encoder{fp.suffix}'
98
+ if fpi.exists(): fpi.unlink()
99
+ shutil.copyfile(fp, fpi)
100
+ fpo = fpi.with_name('benchmark_ffmpeg_encoder-xcode.mp4')
101
+ fpo.unlink(missing_ok=True)
102
+
103
+ # 枚举各种参数
104
+ iter_cfgs = globals()[f'iter_{args.encoder}_cfgs']
105
+ n_cases = len(list(iter_cfgs()))
106
+ records: list[dict] = []
107
+ try:
108
+ for i_case, (cfgs, runcmd_gen) in enumerate(iter_cfgs(), start=1):
109
+ print(f'\n[{i_case} / {n_cases}]')
110
+ try:
111
+ ts_start = perf_counter()
112
+ res = run_xcode_and_eval(fpi, fpo, cfgs, runcmd_gen)
113
+ ts_end = perf_counter()
114
+ pprint(res)
115
+ print(f'>> ts: {ts_end - ts_start:.3f}s')
116
+ records.append(res)
117
+ except Exception as e:
118
+ print(f'>> failed: {e}')
119
+ except KeyboardInterrupt:
120
+ print('Exit by Ctrl+C')
121
+ except:
122
+ print_exc()
123
+
124
+ # 删除临时文件
125
+ fpi.unlink(missing_ok=True)
126
+
127
+ # 保存测试数据
128
+ if records:
129
+ args.output.mkdir(exist_ok=True)
130
+ fpout: Path = args.output / 'benchmark_ffmpeg_encoder.json'
131
+ if fpout.exists():
132
+ with open(fpout, 'r', encoding='utf-8') as fh:
133
+ runs = json.load(fh)
134
+ else:
135
+ runs = []
136
+ runs.append({
137
+ 'ts': str(datetime.now()),
138
+ 'host': HOSTNAME,
139
+ 'ffmepg': ffmpeg_ver,
140
+ 'encoder': args.encoder,
141
+ 'input': args.input.name,
142
+ 'records': records,
143
+ })
144
+ with open(fpout, 'w', encoding='utf-8') as fh:
145
+ json.dump(runs, fh, ensure_ascii=False, indent=2)
146
+ print(f'>> save file: {fpout}')
147
+
148
+
149
+ if __name__ == '__main__':
150
+ parser = ArgumentParser()
151
+ parser.add_argument('-I', '--input', default=DATA_PATH / '1080p_AMV-90s.mp4', type=Path)
152
+ parser.add_argument('-O', '--output', default='./log', type=Path)
153
+ parser.add_argument('-C', '--encoder', default='libx264', choices=ENCODERS)
154
+ parser.add_argument('--fast_eval', action='store_true', help='fast metric eval, skip vmaf')
155
+ args = parser.parse_args()
156
+
157
+ assert args.input.is_file()
158
+
159
+ run(args)