48 lines
2.8 KiB
Python
48 lines
2.8 KiB
Python
"""Rebuild through the hardened generator; keep this run's source/output audit."""
|
|||
|
|
import json
|
||
|
|
from datetime import datetime, timezone
|
||
|
|
from pathlib import Path
|
||
|
|
import subprocess
|
||
|
|
import sys
|
||
|
|
|
||
|
|
ROOT = Path(__file__).resolve().parents[4]
|
||
|
|
sys.path.insert(0, str(ROOT / 'scripts'))
|
||
|
|
import ambience_audio as audio
|
||
|
|
|
||
|
|
EVIDENCE = Path(__file__).resolve().parent
|
||
|
|
plan_path = ROOT / '.agent/AMBIENCE-SOURCES-v0.2.3.json'
|
||
|
|
plan_bytes = plan_path.read_bytes()
|
||
|
|
plan = json.loads(plan_bytes)
|
||
|
|
source_directory = Path('/tmp/findword-ambience-sources')
|
||
|
|
records = []
|
||
|
|
for asset in plan['assets']:
|
||
|
|
path = audio.source_path(source_directory, asset['environmentId'])
|
||
|
|
probe = json.loads(subprocess.check_output(['ffprobe', '-v', 'error', '-show_entries', 'format=duration', '-of', 'json', str(path)], text=True))
|
||
|
|
record = {'environmentId': asset['environmentId'], 'sha256': audio.digest(path), 'bytes': path.stat().st_size,
|
||
|
|
'directMediaDurationSeconds': float(probe['format']['duration']), 'selectedSegmentStartSeconds': asset['selectedSegmentStartSeconds']}
|
||
|
|
assert record['sha256'] == asset['expectedSourceSha256']
|
||
|
|
assert record['bytes'] == asset['sourceBytes']
|
||
|
|
assert record['directMediaDurationSeconds'] == asset['directMediaDurationSeconds']
|
||
|
|
records.append(record)
|
||
|
|
print('All eight source SHA-256, byte counts and direct-media durations match before conversion.', flush=True)
|
||
|
|
manifest = audio.generate(plan, source_directory, ROOT / 'public/ambience')
|
||
|
|
assert plan_path.read_bytes() == plan_bytes
|
||
|
|
assert plan == json.loads(plan_bytes)
|
||
|
|
audio.validate_bundle(ROOT / 'public/ambience', plan)
|
||
|
|
record = {'completedAtUtc': datetime.now(timezone.utc).isoformat(), 'method': 'ambience_audio.generate: source preflight, full staged bundle validation, atomic directory exchange',
|
||
|
|
'allSourcesMatchedBeforeConversion': True, 'planUnmodified': True, 'sources': records, 'manifestSha256': audio.digest(ROOT / 'public/ambience/manifest.json'),
|
||
|
|
'toolVersions': manifest['toolVersions'], 'outputs': [{k: e[k] for k in ('environmentId', 'selectedSegmentStartSeconds', 'sha256', 'bytes', 'duration', 'rms', 'peak', 'conversion')} for e in manifest['files']]}
|
||
|
|
with (EVIDENCE / 'regeneration.json').open('x') as stream:
|
||
|
|
stream.write(json.dumps(record, ensure_ascii=False, indent=2) + '\n')
|
||
|
|
baseline = json.loads((EVIDENCE / 'baseline.json').read_text())
|
||
|
|
changed = []
|
||
|
|
for name, before in baseline['wavSha256'].items():
|
||
|
|
after = audio.digest(ROOT / name)
|
||
|
|
if name in ('public/ambience/market.wav', 'public/ambience/cafe.wav'):
|
||
|
|
assert after != before
|
||
|
|
changed.append(name)
|
||
|
|
else:
|
||
|
|
assert after == before, name
|
||
|
|
print('Preserved 101 voice WAVs and six ambience WAVs including mall; changed only market and cafe.', flush=True)
|
||
|
|
print(json.dumps(record, ensure_ascii=False, indent=2))
|