jenkins 9204773e7d av-test: publish bounded continuity watch and recent observations
Vendor tested Lesavka observer assets and numeric receipt schema from 6b97ceb1. Verified 65 JS tests, 10 service tests, kustomize render and Kubernetes client dry-run. No media upload, capture activation or changes to the homepage and private OCR.
2026-10-22 21:47:13 -05:00

28 lines
1.2 KiB
JavaScript

// Independent cleanup attempts: a broken optional recorder or audio node must
// never keep the camera/microphone open or prevent the remaining owners closing.
const attempt=operation=>{try{operation();}catch{/* Continue releasing other owners. */}};
export function stopTracks(stream) {
if(!stream)return;
for(const track of stream.getTracks())attempt(()=>{track.onended=null;track.stop();});
}
export function releaseCapture(run,preview,finishRecording) {
if(run.released)return;
run.released=true;
attempt(()=>stopTracks(run.stream));
for(const timer of [run.timer,run.setupTimer,run.signalTimer])clearTimeout(timer);
clearInterval(run.updateTimer);
if(run.callback!=null)attempt(()=>preview.cancelVideoFrameCallback(run.callback));
if(run.recording)attempt(finishRecording);
if(run.node) {
run.node.onprocessorerror=null;
run.node.port.onmessage=null;
attempt(()=>run.node.port.postMessage('stop'));
attempt(()=>run.node.disconnect());
}
attempt(()=>run.source?.disconnect());
// A rejected or unresolved AudioContext.close never postpones track release.
attempt(()=>run.context?.close().catch(()=>{}));
}