[Python,Pandas]交流群 164142295
前阵子下载了很多电影,造成磁盘空间严重不足,为了节约小钱钱于是萌生了将H264电影压缩成HEVC的念头。
本程序在Win10中开发,并通过测试。
接下来是几点说明:
1. 这段代码用到pymediainfo库,具体安装请自行百度。
2. 关于控制视频质量的参数。函数 bit_rate_control 返回输出视频的码率,如果原始视频码率低于1800kbps,则输出体积大约是原视频的70%大小。码率超过 20000kbps 如果,则输出文件约为原视频的20%(一般来说,细节损失还可以接受)。经过大量实践1080P 30fps的影片大约需要 2500kbps - 3000kbps 以保证不会出现大量马赛克。
3. 主函数中 encoder 的说明,
- hevc_nvenc, 网上文章说是NVIDIA CUDA加速,笔者没测试过
- hevc_mf,NVIDIA显卡的硬件加速选项,在笔者笔记本的NVIDIA显卡测试过,可以使用
- hevc_amf ,AMD显卡硬件加速使用的参数,由于笔者使用AMD,所以为代码默认
- hevc_qsv, Intel显卡硬件加速使用的参数
- libx265, 软件编码使用的参数,压缩速度比硬件加速慢上好多倍
4. preset 参数,请参考文章 (55条消息) x265的编码参数preset级别对性能的影响_wu_qz的博客-优快云博客_-preset superfast
https://blog.youkuaiyun.com/Wu_qz/article/details/89499415选项如下,
- ultrafast
- superfast
- veryfast
- faster
- fast
- medium
- slow
- slower
- veryslow
- placebo'
5. Resource.txt存放需要转码文件的绝对路径,用换行符隔开
6. 程序会根据文件质量大致估算需要的码率进行压缩
7. 本程序生成ffmpeg命令,并保存在D:\BatchConvert.bat,不会自动转码。需要手动执行,这点很重要。
接下来是代码
from pathlib import Path
from pymediainfo import MediaInfo
import json
def bit_rate_control(in_bitrate):
x1, y1 = 1800, 0.7
x2, y2 = 20000, 0.2
if x1 <= in_bitrate <= x2:
return (in_bitrate - x1) * (y2 - y1) / (x2 - x1) + y1
if in_bitrate <= x1:
return y1
if in_bitrate >= x2:
return y2
def is_hevc(input_str: str):
input_str = input_str.lower()
is_hevc_array = (1 if 'x265' in input_str else 0,
1 if 'x.265' in input_str else 0,
1 if 'h265' in input_str else 0,
1 if 'h.265' in input_str else 0,
1 if 'hevc' in input_str else 0)
return any(is_hevc_array)
class VideoAnalysis:
def __init__(self, file_path: Path):
self.f = file_path
self.f_size = self.f.stat().st_size / 1024
self.media_info = MediaInfo.parse(input_file)
self.data = self.media_info.to_json()
self.data = json.loads(self.data)['tracks']
def get_height(self):
return int(self.data[1]['height'])
def get_fps(self):
return float(self.data[1]['frame_rate'])
def get_bit_rate(self):
br = self.actual_bit_rate_cal()
return int(br * bit_rate_control(br))
def get_duration(self):
data = self.data[0]
return data['other_duration'][2]
def actual_bit_rate_cal(self):
data = self.data[0]
in_str = data['other_duration'][3].split('.')[0]
in_str = in_str.split(':')
in_str = [int(i) for i in in_str]
duration = in_str[0] * 3600 + in_str[1] * 60 + in_str[2]
return round(self.f_size * 8 / duration, 2)
def partition(idx, input_file):
input_file = Path(input_file)
if is_hevc(str(input_file.name)) or not input_file.is_file() or 'bat' in str(input_file):
return None
fa = VideoAnalysis(input_file)
file_name = input_file.stem.lower()
new_file_name: str = input_file.stem
try:
bit_rate = fa.get_bit_rate()
except KeyError:
bit_rate = 2560
if bit_rate <= 2500:
print('Pass', idx, bit_rate, input_file)
return
file_name = new_file_name.replace('264', 'HEVC') if (
'h264' in file_name or 'x264' in file_name
or 'h.264' in file_name) else f'{new_file_name}_HEVC'
new_suffix = 'mkv' if input_file.suffix == 'mkv' else 'mp4'
paras = f'-preset {preset} -map 0 -c:v {encoder} -x265-params "crf={crf}:psy-rd=1" -b:v {bit_rate}k'
output_file = fr'D:\HEVC\{file_name.replace(" ", "")}.{new_suffix}'
cmd = fr'ffmpeg -threads 4 -i "{input_file}" {paras} "{output_file}"'
rem = fr'Rem "BitRate {fa.actual_bit_rate_cal()} kbps, {fa.get_height()}P , {fa.get_fps()} FPS , ' \
fr'{fa.get_duration()} ,{input_file.name}"'
return rem, cmd
if __name__ == '__main__':
# 这个txt文件存放需要转码文件的绝对路径,用换行符隔开
root_f = Path(r'D:\256G\Repositories\RFM\EXTData\Resource.txt')
fs = root_f.read_text(encoding='UTF-8').split('\n')
# 'ultrafast,superfast,veryfast,faster,fast,medium,slow,slower,veryslow,placebo'
preset = 'slower'
# encoder='hevc_nvenc hevc_mf hevc_amf hevc_qsv libx265 vp9_qsv'
encoder = 'hevc_amf'
pass_num = 2
batch_contents = []
# lower is better , range 0-50
crf = 12
for idx, input_file in enumerate(fs):
print(idx, input_file)
try:
if ret := partition(idx, input_file):
batch_contents.extend(ret)
except KeyError:
print(f'{idx} KeyError ! {input_file}')
continue
Path(r'D:\BatchConvert.bat'). \
write_text('\n'.join(batch_contents), encoding='gb18030')

该博客分享了如何使用Python结合pymediainfo库生成ffmpeg命令,将H264视频压缩为HEVC格式。在Win10环境下开发并测试,介绍了不同编码器选项如hevc_nvenc、hevc_mf等,并提到了码率控制与预设参数对视频质量的影响。转换后的ffmpeg命令保存为批处理文件,需要手动执行。
1万+

被折叠的 条评论
为什么被折叠?



