main
John Lauer Release 0.1.27: native rule preservation, router and evidence gates, measured external work and reviewed component over… da373cf
"""Validate encoded frames, since native webviews may never dispatch visibilitychange."""
import json,subprocess

def assess(timestamps,elapsed):
    points=sorted(float(t) for t in timestamps)
    if elapsed < 1 or len(points)<3:return {'accepted':False,'reason':'too few encoded frames to review'}
    span=points[-1]-points[0]
    gap=max((b-a for a,b in zip(points,points[1:])),default=0)
    reasons=[]
    if len(points)/elapsed<2:reasons.append('fewer than two encoded frames per recorded second')
    if span<elapsed*.7:reasons.append('encoded duration covers less than 70 percent of the recording')
    if gap>2:reasons.append('encoded frames have a gap longer than two seconds')
    return {'accepted':not reasons,'reason':'; '.join(reasons),'frames':len(points),'encodedSpanSeconds':span,'elapsedSeconds':elapsed,'maxFrameGapSeconds':gap}

def check(path,elapsed):
    try:
        p=subprocess.run(['ffprobe','-v','error','-select_streams','v:0','-show_entries','frame=best_effort_timestamp_time','-of','json',str(path)],capture_output=True,text=True,timeout=60,check=True)
        return assess([f['best_effort_timestamp_time'] for f in json.loads(p.stdout)['frames'] if 'best_effort_timestamp_time' in f],float(elapsed))
    except Exception as e:return {'accepted':False,'reason':'encoded frame validation failed: '+str(e)}