// A runtime media result and a header result are separate observations. async function inspectTeachingMediaURL(url, timeoutMs = 5000) { const response = await fetch(url, {cache:'no-store'}); const header = {status:response.status, contentType:response.headers.get('content-type'), contentLength:response.headers.get('content-length')}; const media = document.createElement('audio'); media.preload = 'metadata'; media.muted = true; const runtime = await new Promise(resolve => { let timer; const finish = event => { clearTimeout(timer); media.onloadedmetadata = media.onerror = null; resolve({event, duration:Number.isFinite(media.duration) ? media.duration : null, mediaErrorCode:media.error ? media.error.code : null}); }; media.onloadedmetadata = () => finish('loadedmetadata'); media.onerror = () => finish('error'); timer = setTimeout(() => finish('timeout'), timeoutMs); media.src = url; document.body.append(media); media.load(); }); media.removeAttribute('src'); media.load(); media.remove(); return {url, header, runtime, contentListened:false}; }