分段后处理中的弹幕压制
WARNING
弹幕压制对硬件要求较高,硬件性能越高压制越快,硬件性能过低不建议尝试。
下面是一个简单的分段后处理中压制弹幕的 Python 脚本示例,保存到 biliup 运行目录,赋予可执行权限。
- 使用 DanmakuFactory,自行下载或编译,复制到脚本同目录,并赋予可执行权限。
- 弹幕样式设置,请查看 DanmakuFactory 官方文档。
- 非 Termux 使用,请自行设置合适的
-hwaccel参数(或者直接使用auto)和 h264 编码器。
参考命令(查找硬件加速器和编解码器):
bash
ffmpeg -hwaccels # 查看硬件加速器
ffmpeg -codecs | grep h264 # 查看 h264 编解码器 (Linux)
ffmpeg -codecs | findstr h264 # 查看 h264 编解码器 (Windows)- Windows 中建议使用
d3d11va,不在意 CPU 使用率可使用opencl或vulkan硬件加速。 - 测试骁龙 865 使用脚本中的参数压制 1080p 视频的速度可达 2x。
- 注意源视频文件的扩展名以防止文件覆盖。
- 编码参数
-profile和-level最好同时指定,仅指定-profile在部分设备上会出现编码失败。
python
import os
import sys
import glob
import subprocess
import datetime
def is_termux():
return 'com.termux' in os.getenv('PREFIX', '')
def encode():
# 读取标准输入的内容
video = sys.stdin.readline().strip()
xml = sys.stdin.readline().strip()
mp4 = os.path.splitext(video)[0] + '.mp4'
# 避免 Windows 中绝对路径的转义问题
ass = os.path.splitext(os.path.basename(xml))[0] + '.ass'
# 查找当前文件夹 DanmakuFactory 可执行文件
danmaku_file = None
for file in glob.glob(os.path.join(os.getcwd(), 'DanmakuFactory*')):
if os.path.isfile(file):
danmaku_file = file
break
subprocess.run(
f'{danmaku_file} -i {xml} -o {ass} -S 50 -O 230 --ignore-warnings',
shell=True, check=True, stdout=subprocess.DEVNULL
)
print("开始压制时间:", datetime.datetime.now())
subprocess.run(
f'ffmpeg -hwaccel mediacodec -i {video} -vf ass={ass} '
f'-c:v h264_mediacodec -c:a copy -crf 18 -b:v 12M '
f'-profile:v high -level 4.2 -v quiet -y {mp4}',
shell=True, check=True, stdout=subprocess.DEVNULL
)
print("结束压制时间:", datetime.datetime.now())
os.remove(ass)
os.remove(video)
os.remove(xml)
if __name__ == "__main__":
if is_termux():
try:
subprocess.run('termux-wake-lock', shell=True, check=True)
encode()
except Exception as e:
print(f"error: {e}")
sys.exit(1)
finally:
subprocess.run('termux-wake-unlock', shell=True, check=True)
else:
try:
encode()
except Exception as e:
print(f"error: {e}")
sys.exit(1)