voice_audio_multi/tools/community_models/soulx_flashhead/render_video.py
Fabio c36510c21e
Some checks failed
Linux Build / Linux cpu (push) Has been cancelled
Linux Build / Linux cpu-clang (push) Has been cancelled
Linux Build / Linux vulkan (push) Has been cancelled
mac-build / macOS CPU (push) Has been cancelled
Nix Build / Nix (cpu) (push) Has been cancelled
Nix Build / Nix (vulkan) (push) Has been cancelled
windows-build / Windows CPU (push) Has been cancelled
Initial import: audio.cpp with Orange Pi documentation
2026-11-04 19:05:22 +01:00

44 lines
2 KiB
Python

#!/usr/bin/env python3
"""Encode audio.cpp's RGB24 video artifacts as an MP4."""
import argparse
import json
from pathlib import Path
import subprocess
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--input', type=Path, required=True, help='CLI artifact directory')
parser.add_argument('--output', type=Path, required=True)
parser.add_argument('--audio', type=Path)
args = parser.parse_args()
files = sorted(args.input.glob('soulx_flashhead_video_*.json'),
key=lambda path: int(path.stem.rsplit('_', 1)[1]))
if not files:
raise ValueError('No FlashHead video artifacts found')
first = json.loads(files[0].read_text())['meta']
args.output.parent.mkdir(parents=True, exist_ok=True)
command = ['ffmpeg', '-v', 'error', '-y', '-f', 'rawvideo', '-pixel_format', 'rgb24',
'-video_size', first['width'] + 'x' + first['height'], '-framerate', first['fps'], '-i', 'pipe:0']
if args.audio:
command += ['-i', str(args.audio), '-c:a', 'aac', '-shortest']
command += ['-c:v', 'libx264', '-crf', '18', '-pix_fmt', 'yuv420p', '-movflags', '+faststart', str(args.output)]
with subprocess.Popen(command, stdin=subprocess.PIPE) as process:
try:
for file in files:
artifact = json.loads(file.read_text())
meta = artifact['meta']
if any(meta[k] != first[k] for k in ('width', 'height', 'fps', 'format')) or meta['format'] != 'rgb24':
raise ValueError('Video artifact formats differ')
payload = bytes.fromhex(artifact['payload_hex'])
if len(payload) != int(meta['width']) * int(meta['height']) * int(meta['frames']) * 3:
raise ValueError('Video artifact byte count does not match its dimensions')
process.stdin.write(payload)
finally:
process.stdin.close()
if process.wait():
raise RuntimeError('FFmpeg video encoding failed')
if __name__ == '__main__':
main()