Extend JamesDSP with convolution and spatial audio
This commit is contained in:
@@ -37,13 +37,22 @@ async function run(engine){
|
||||
};
|
||||
let page=await context.newPage();attach(page);
|
||||
const boot=async()=>{await page.goto(origin);await page.waitForFunction(()=>typeof data!=='undefined'&&document.querySelector('[aria-label="Car mode"]'));};
|
||||
const inventory=()=>page.evaluate(async({manifest,legacy})=>{
|
||||
const inventory=(includeOptional=false)=>page.evaluate(async({manifest,legacy,includeOptional})=>{
|
||||
const names=await caches.keys(),cache=await caches.open(legacy?names.find(n=>n.startsWith('ytplayer-')&&!['ytplayer-assets','ytplayer-fonts','ytplayer-thumbs'].includes(n)):'ytplayer-assets');
|
||||
const missing=[];for(const [path,file]of Object.entries(manifest.files)){const r=await cache.match(legacy?path:path+'?v='+file.h);if(!r||(!legacy&&r.headers.get('X-Asset-Hash')!==file.h))missing.push(path);}
|
||||
return{total:Object.keys(manifest.files).length,missing};
|
||||
},{manifest,legacy});
|
||||
const optional=new Set(Object.values(manifest.groups||{}).filter(group=>group.offlineOptIn).flatMap(group=>group.files||[]));
|
||||
const expected=Object.entries(manifest.files).filter(([path])=>legacy||includeOptional||!optional.has(path));
|
||||
const missing=[];for(const [path,file]of expected){const r=await cache.match(legacy?path:path+'?v='+file.h);if(!r||(!legacy&&r.headers.get('X-Asset-Hash')!==file.h))missing.push(path);}
|
||||
return{total:expected.length,manifestTotal:Object.keys(manifest.files).length,optionalExcluded:Object.keys(manifest.files).length-expected.length,missing};
|
||||
},{manifest,legacy,includeOptional});
|
||||
const started=Date.now();console.log(engine,'install boot');await boot();console.log(engine,'waiting for worker activation');if(!await poll(()=>page.evaluate(async()=>!!(await navigator.serviceWorker.getRegistration())?.active),30000))throw Error('Worker did not activate: '+JSON.stringify(await page.evaluate(async()=>{const r=await navigator.serviceWorker.getRegistration();return {active:r?.active?.state,waiting:r?.waiting?.state,installing:r?.installing?.state,caches:await caches.keys(),keys:(await(await caches.open('ytplayer-assets')).keys()).map(r=>new URL(r.url).pathname)};})));await page.evaluate(()=>navigator.serviceWorker.ready);console.log(engine,'worker active');await page.evaluate(()=>window.Lazy?.warm());
|
||||
await poll(async()=>!(await inventory()).missing.length,Number(option('--warm-timeout','15000')));
|
||||
if(!legacy){const wasmPath='/vendor/jamesdsp/dsp/jamesdsp.wasm',wasm=manifest.files[wasmPath];if(wasm){const cached=await page.evaluate(async key=>!!await(await caches.open('ytplayer-assets')).match(key),wasmPath+'?v='+wasm.h);if(cached)result.failures.push({kind:'opt-in-wasm-cached-by-default',path:wasmPath});}}
|
||||
if(!legacy){
|
||||
await page.evaluate(()=>{data.settings.jamesDsp={...data.settings.jamesDsp,downloadForOffline:true};persist();reportDspOfflineOptIn();});
|
||||
const dspReady=await poll(async()=>{const inventoryNow=await inventory(true);return !inventoryNow.missing.length;},120000);
|
||||
result.conditions.push({name:'explicit audio-effects offline opt-in completes optional assets',complete:dspReady});
|
||||
if(!dspReady)result.failures.push({kind:'optional-dsp-completion',paths:(await inventory(true)).missing});
|
||||
}
|
||||
console.log(engine,'inventory complete');result.installMs=Date.now()-started;result.inventory=await inventory();result.installWire=proxy.getStats();result.saveData=await page.evaluate(()=>navigator.connection?.saveData);
|
||||
if(result.inventory.missing.length)result.failures.push({kind:'incomplete',paths:result.inventory.missing});
|
||||
// Offline navigation always starts from a controlled document.
|
||||
@@ -108,13 +117,17 @@ async function run(engine){
|
||||
await page.evaluate(async manifest=>{const c=await caches.open('ytplayer-assets');for(const path of Object.keys(manifest.files).filter(p=>manifest.files[p].g!=='core'))await c.delete(path+'?v='+manifest.files[path].h);navigator.serviceWorker.controller.postMessage({type:'COMPLETE_ASSETS'});},manifest);
|
||||
await poll(()=>page.evaluate(async()=>{const c=await caches.open('ytplayer-assets'),s=await(await c.match('/__ytp_asset_state')).json(),r=await c.match('/__ytp_completion/'+s.current.buildTag);return r&&(await r.json()).running;}),5000);
|
||||
await page.close();await other.close();await proxy.setOffline(false);
|
||||
const withoutPage=await poll(async()=>{const {cacheDataEntries:entries}=await cdp.send('CacheStorage.requestEntries',{cacheId,skipCount:0,pageSize:1000});return Object.entries(manifest.files).every(([path,file])=>entries.some(e=>e.requestURL===origin+path+'?v='+file.h&&e.responseHeaders.some(h=>h.name.toLowerCase()==='x-asset-hash'&&h.value===file.h)));});
|
||||
const optionalPaths=new Set(Object.values(manifest.groups||{}).filter(group=>group.offlineOptIn==='jamesDsp').flatMap(group=>group.files||[]));
|
||||
const includeOptional=await page.evaluate(async()=>{const cache=await caches.open('ytplayer-assets'),response=await cache.match('/__ytp_offline_opt_ins');return (await response?.json()||[]).includes('jamesDsp');});
|
||||
const requiredFiles=Object.entries(manifest.files).filter(([path])=>includeOptional||!optionalPaths.has(path));
|
||||
const withoutPage=await poll(async()=>{const {cacheDataEntries:entries}=await cdp.send('CacheStorage.requestEntries',{cacheId,skipCount:0,pageSize:1000});return requiredFiles.every(([path,file])=>entries.some(e=>e.requestURL===origin+path+'?v='+file.h&&e.responseHeaders.some(h=>h.name.toLowerCase()==='x-asset-hash'&&h.value===file.h)));});
|
||||
result.conditions.push({name:'worker completes with every application page closed; passive same-origin inspector only',complete:withoutPage});
|
||||
if(!withoutPage)result.failures.push({kind:'completion-without-page'});
|
||||
await cdp.detach();await inspector.close();
|
||||
}else await other.close();
|
||||
}
|
||||
console.log(engine,JSON.stringify({missing:result.inventory.missing,failures:result.failures,conditions:result.conditions}));
|
||||
result.inventory=await inventory(!legacy);
|
||||
console.log(engine,JSON.stringify({missing:result.inventory.missing,inventory:result.inventory.total,manifestFiles:result.inventory.manifestTotal,failures:result.failures,conditions:result.conditions}));
|
||||
}catch(e){result.failures.push({kind:'harness',error:e.stack});console.log(engine,e.message);}finally{await context?.close();await browser?.close();await proxy?.close();child.kill('SIGTERM');if(child.exitCode===null)await new Promise(r=>child.once('exit',r));}
|
||||
}
|
||||
try{for(const engine of option('--browser','all')==='all'?['chromium','webkit']:[option('--browser')])await run(engine);}finally{writeFileSync(resolve(option('--out',join(repo,'perf/results/offline-complete.json'))),JSON.stringify({results},null,2)+'\n');rmSync(scratch,{recursive:true,force:true});}
|
||||
|
||||
Reference in New Issue
Block a user