Build 620073canary
Module 423341
13,020 characters · in web.692b1813fcabadaf.jsDependencies
Source Raw
function(e,t,n){"use strict";n.d(t,{A:()=>G,i:()=>w}),n(321073);var i=n(284009),r=n.n(i),a=n(459838),s=n(451988),l=n(439372),o=n(77729),d=n(608960),c=n(952818),u=n(209932),_=n(280450),E=n(309010),A=n(287809),h=n(915725);class I{timeline=[];timelineLength;clipNow;constructor(e=3e5,t){this.timelineLength=e,this.clipNow=t}clear(){this.timeline.length=0}updateLength(e){this.timelineLength=e,this.cull()}add(e){if(0===this.timeline.length||this.timeline[this.timeline.length-1].timestamp<=e.timestamp){this.timeline.push(e),this.cull();return}let t=this.timeline.length;for(let n=this.timeline.length-1;n>=0;n--)if(this.timeline[n].timestamp<=e.timestamp){t=n+1;break}t===this.timeline.length&&this.timeline[0].timestamp>e.timestamp&&(t=0),this.timeline.splice(t,0,e),this.cull()}read(e,t){return this.cull(),this.timeline.filter(n=>n.timestamp>=e&&n.timestamp<=t)}cull(){let e=this.clipNow()-this.timelineLength;for(;this.timeline.length>0&&this.timeline[0].timestamp<e;)this.timeline.shift()}}var f=n(341923),p=n(572164),T=n(831518),m=n(614584),g=n(31048),S=n(997649),N=n(228366),C=n(311043),O=n(174459),R=n(53677),L=n(574206),y=n(652215);function D(e){let t=h.Ay.getActiveClipsSession()?.gameId??null,n=new L.k(e);return N.h.dispatch({type:"CLIPS_SESSION_START",session:n,previousGameId:t}),O.default.track(y.HAw.CLIPS_SESSION_STARTED,{...R.lc(),current_clip_session_id:n.id,application_id:e,application_name:C.A.getGame(e)?.name}),n}async function v(){let e=h.Ay.getActiveClipsSession();null!=e&&(await N.h.dispatch({type:"CLIPS_SESSION_STOP",gameId:e.gameId}),O.default.track(y.HAw.CLIPS_SESSION_ENDED,{...R.lc(),current_clip_session_id:e.id,application_id:e.gameId,application_name:C.A.getGame(e.gameId)?.name,manual_clips_saved:e.manualClipsSaved,candidate_clips_saved:e.candidateClipsSaved,candidate_clips_promoted:e.candidateClipsPromoted}))}var b=n(313465),M=n(799),P=n(696016);function U(e,t){if(e.length<2)return!1;for(let n=e.length-2;n<e.length;n++)if(e[n].value<=t)return!1;return!0}class w extends l.A{timeline;scheduledClips=[];decisionSignals=(0,S.A)();sessionEndTimeout=new s.Ep;currentSessionGameKey=null;pendingSessionGameKey=null;constructor(){super(),this.timeline=new I(Math.max(h.Ay.getSettings().clipsLength,6e4),g.l)}actions={CLIPS_SIGNAL_CREATED:e=>this.handleClipsSignalCreated(e.signal,e.timestamp),CLIPS_ML_DETECTION:e=>this.handleMlDetection(e.detections),SPEAKING:e=>this.handleSpeaking(e),GUILD_SOUNDBOARD_SOUND_PLAY_START:e=>this.handleSoundboardPlayStart(e),GUILD_SOUNDBOARD_SOUND_PLAY_END:e=>this.handleSoundboardPlayEnd(e),RUNNING_GAMES_CHANGE:()=>{this.handleRunningGamesChange().catch(e=>P.nx.error("decider: handleRunningGamesChange failed",e))},VOICE_CHANNEL_SELECT:()=>{this.handleVoiceChannelSelect().catch(e=>P.nx.error("decider: handleVoiceChannelSelect failed",e))},CLIPS_SETTINGS_UPDATE:()=>this.handleSettingsUpdate()};handleClipsSignalCreated(e,t){this.isSignalEnabled(e.type)&&this.process(e,t)}handleMlDetection(e){for(let t of e){let e=this.decisionSignals.audioModelDataPerUser[t.user_id];for(let n of(null==e&&(e={laughterData:[],shoutingData:[],rmsData:[]},this.decisionSignals.audioModelDataPerUser[t.user_id]=e),t.data_points))"laughter"===n.label?(e.laughterData.push({timestamp_ms:n.timestamp_ms,value:n.confidence}),U(e.laughterData,.5)&&this.process({type:P.Gy.LAUGHTER,userId:t.user_id,confidence:n.confidence},n.timestamp_ms)):"shouting"===n.label?(e.shoutingData.push({timestamp_ms:n.timestamp_ms,value:n.confidence}),U(e.shoutingData,.35)&&this.process({type:P.Gy.SHOUTING,userId:t.user_id,confidence:n.confidence},n.timestamp_ms)):"rms"===n.label&&e.rmsData.push({timestamp_ms:n.timestamp_ms,value:n.confidence})}}handleSpeaking(e){if(!(0,p.T)()||e.context!==a.x.DEFAULT)return;let t=h.Ay.isVoiceRecordingAllowedForUser(e.userId);(e.userId===_.default.getId()||t)&&this.process({type:P.Gy.SPEAKING,speakingFlags:e.speakingFlags,userId:e.userId})}handleSoundboardPlayStart(e){if(!(0,p.T)())return;let t=u.A.getSoundById(e.soundId);if(null==t)return;let n=d.A.getGuildEmojis(t.guildId)?.[t.emojiId??""];this.process({type:P.Gy.SOUNDBOARD,playing:!0,soundboardId:e.soundId,emojiId:n?.id,emojiAnimated:n?.animated,emojiName:n?.name??t.emojiName,name:t.name,userId:e.userId})}handleSoundboardPlayEnd(e){if(!(0,p.T)())return;let t=u.A.getSoundById(e.soundId);if(null==t)return;let n=d.A.getGuildEmojis(t.guildId)?.[t.emojiId??""];this.process({type:P.Gy.SOUNDBOARD,playing:!1,soundboardId:e.soundId,emojiId:n?.id,emojiAnimated:n?.animated,emojiName:n?.name,name:t.name,userId:e.userId})}isSignalEnabled(e){switch(e){case P.Gy.DISTRIBUTED:return h.Ay.getSettings().clipSignals.enableDistributedSignals;case P.Gy.GAME_EVENT:return h.Ay.getSettings().clipSignals.enableGameSignals;default:return!0}}calculateAutoclipRequest(e){let t=e-3e4,n=Math.round(t+15e3),i=Math.round(3e4);return{startMs:n-i,endMs:n+i,trimStartMs:t,trimEndMs:e}}adjustTrimForRms(e){let{startMs:t,endMs:n}=e,{trimStartMs:i,trimEndMs:a}=e,s=new Map;for(let e of Object.values(this.decisionSignals.audioModelDataPerUser))for(let i of(0,T.Tv)(e.rmsData,t,n)){r()(i.timestamp_ms%1e3==0,"bad rms data");let e=s.get(i.timestamp_ms)??0;s.set(i.timestamp_ms,e+i.value)}function l(e,t,n){let i=null,r=Number.MAX_VALUE;for(let a=e;a<=t;a+=1e3){let e=s.get(a)??0;(n&&e<r||!n&&e<=r)&&(r=e,i=a,!n&&e<.001&&(i=Math.min(i+2e3,t)))}return i}let o=(0,S.p)(this.decisionSignals.gameEventData,i,a);{let e=o.length>0?Math.min(...o.map(e=>e.timestamp_ms)):null,t=i+5e3;null!=e&&(t=Math.min(t,e-3e3)),i=l(1e3*Math.floor((i-5e3)/1e3),t,!1)??i}{let e=o.length>0?Math.max(...o.map(e=>e.timestamp_ms)):null,t=a-5e3;null!=e&&(t=Math.max(t,e+3e3)),a=l(1e3*Math.ceil(t/1e3),a+5e3,!0)??a}return(i=Math.max(i,t))>=(a=Math.min(a,n))&&(i=e.startMs,a=e.endMs),{startMs:t,endMs:n,trimStartMs:i,trimEndMs:a}}process(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:(0,g.l)();switch(this.timeline.add({signal:e,timestamp:t}),e.type){case P.Gy.MANUAL:case P.Gy.DISTRIBUTED:this.scheduleClip(e);break;case P.Gy.SHOUTING:case P.Gy.LAUGHTER:case P.Gy.GAME_EVENT:{let n=0;if(e.type===P.Gy.GAME_EVENT){if(this.decisionSignals.gameEventData.push({...e,timestamp_ms:t}),1!==e.importance)break;n=Math.max((0,g.l)(),t+1e4)}else n=(0,g.l)()+1e4;if(this.scheduledClips.some(e=>(e.signal.type===P.Gy.GAME_EVENT||e.signal.type===P.Gy.LAUGHTER||e.signal.type===P.Gy.SHOUTING)&&t>=e.request.trimStartMs&&t<=e.request.trimEndMs)){P.nx.info(`decider: suppressing ${e.type} clip \u{2014} timestamp ${t} falls within an existing scheduled candidate's trimmed range`);break}this.scheduleClip(e,this.calculateAutoclipRequest(n),!0,!0)}}}async finalizeActiveSession(){this.unscheduleClip();let e=h.Ay.getActiveClipsSession(),t=this.decisionSignals;this.decisionSignals=(0,S.A)(),await e?.finalize(t)}async clear(){P.nx.info(`decider: clear() called \u{2014} currentSessionGameKey=${this.currentSessionGameKey} currentSessionId=${h.Ay.getActiveClipsSession()?.id} pendingSessionGameKey=${this.pendingSessionGameKey} candidates=${h.Ay.getClipCandidates().length}`),this.sessionEndTimeout.stop(),await this.finalizeActiveSession(),this.currentSessionGameKey=null,this.pendingSessionGameKey=null,await v(),this.timeline.clear()}unscheduleClip(){for(let e of this.scheduledClips)e.timeout.stop();this.scheduledClips=[]}canScheduleClipCandidate(e,t){if(null==t||!(0,f.jJ)(t.gameId)||c.Ay.getVisibleGame()?.isLauncher===!0)return!1;if(null!=E.Ay.getVoiceChannelId())return!0;let n=A.default.getCurrentUser(),i=n?.isStaff()===!0||n?.isStaffPersonal()===!0;return e.type===P.Gy.GAME_EVENT&&i&&(0,T.GC)(t.gameId??void 0)}scheduleClip(e,t){let n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],i=arguments.length>3&&void 0!==arguments[3]&&arguments[3],r=h.Ay.getActiveClipsSession();if(n&&!this.canScheduleClipCandidate(e,r))return;let a=(0,g.l)(),l=t?.endMs!=null?t.endMs:a,o=t?.startMs!=null?t.startMs:l-Number(h.Ay.getSettings().clipsLength),d={startMs:o,endMs:l,trimStartMs:t?.trimStartMs!=null?t.trimStartMs:o,trimEndMs:t?.trimEndMs!=null?t.trimEndMs:l};P.nx.info(`decider: scheduleClip signal=${e.type}, request=${JSON.stringify(t)}`);let c={timeout:new s.Ep,request:d,signal:e};this.scheduledClips.push(c),c.timeout.start(l>a?l-a:0,async()=>{try{let t=i?this.adjustTrimForRms(d):d;P.nx.info(`decider: scheduled timeout fired \u{2014} saving clip (signal=${e.type}, finalRequest=${JSON.stringify(t)})`),await (0,m.yd)({clipMethod:e.type===P.Gy.MANUAL?"manual":"auto",request:t,timeline:[...this.timeline.read(t.startMs,t.endMs)],decision:{signal:e,timestamp:(0,g.l)()},isCandidate:n,session:r,decisionSignals:n?this.decisionSignals:void 0})}finally{let e=this.scheduledClips.indexOf(c);-1!==e&&this.scheduledClips.splice(e,1)}})}async handleVoiceChannelSelect(){await this.clear();let e=c.Ay.getVisibleGame();if(null==e)return;this.currentSessionGameKey=(0,c.Es)(e);let t=D(e.id??null);P.nx.info(`decider: handleVoiceChannelSelect \u{2014} new gaming session id: ${t.id}, for game: ${this.currentSessionGameKey}`)}async handleRunningGamesChange(){let e=c.Ay.getVisibleGame(),t=null!=e?(0,c.Es)(e):null;if(P.nx.info(`decider: handleRunningGamesChange visibleGame=${e?.name??"null"} newPrimaryKey=${t} currentSessionGameKey=${this.currentSessionGameKey} currentSessionId=${h.Ay.getActiveClipsSession()?.id} pendingSessionGameKey=${this.pendingSessionGameKey}`),null===this.currentSessionGameKey){if(null!=t){this.currentSessionGameKey=t;let n=D(e?.id??null);P.nx.info(`decider: handleRunningGamesChange \u{2014} starting session for ${t} (id=${n.id})`)}else P.nx.info(`decider: handleRunningGamesChange \u{2014} not starting session (newPrimaryKey=${t})`);return}if(t===this.currentSessionGameKey){P.nx.info("decider: handleRunningGamesChange \u2014 same primary, cancelling pending end"),this.sessionEndTimeout.stop(),this.pendingSessionGameKey=null;return}if(null===t){P.nx.info("decider: handleRunningGamesChange \u2014 visible game became null, finalizing session immediately"),this.sessionEndTimeout.stop(),await this.finalizeActiveSession(),this.currentSessionGameKey=null,await v(),this.pendingSessionGameKey=null;return}this.pendingSessionGameKey===t?P.nx.info("decider: handleRunningGamesChange \u2014 already debouncing for this key"):(P.nx.info(`decider: handleRunningGamesChange \u{2014} primary game changed from ${this.currentSessionGameKey} to ${t}, debouncing 30000ms`),this.pendingSessionGameKey=t,this.sessionEndTimeout.start(3e4,()=>{this.rotateSession(t,e?.id??null).catch(e=>P.nx.error("decider: sessionEndTimeout failed",e))}))}async rotateSession(e,t){await this.finalizeActiveSession(),this.currentSessionGameKey=e;let n=D(t);this.pendingSessionGameKey=null,P.nx.info(`decider: sessionEndTimeout fired after debounce \u{2014} finalizing previous session, started new session (newPrimaryKey=${e}, id=${n.id})`)}static async debugRerunRanking(e){P.nx.info(`DEBUG RERUN RANKING${null!=e?` (${e})`:""}`);let t=o.A.clips.debugReadStashedClipDeciderData;if(null==t)return;let n=await t(e),i=(0,T.Ly)(n.clipCandidates,n.decisionSignals,n.localUserId,n.gameId);P.nx.info("ranked clips:",i),i.selected.forEach((e,t)=>{P.nx.info(`Clip ${t+1} score ${e.score}, ${o.A.fileManager.basename(e.clip.filepath)}`)})}static async debugRunAutoMontage(e){P.nx.info(`DEBUG RUN AUTO-MONTAGE${null!=e?` (${e})`:""}`);let t=o.A.clips.debugReadStashedClipDeciderData,n=o.A.clips.renderMontageRecipe;if(null==t||null==n)return void P.nx.warn("debugRunAutoMontage: stash read or render bridge unavailable on this host");let i=await t(e),r={clipCandidates:i.clipCandidates,decisionSignals:i.decisionSignals,localUserId:i.localUserId,gameId:i.gameId},a=performance.now(),s=(0,b.HB)(r),l=performance.now()-a;if(null==s)return void P.nx.info(`debugRunAutoMontage: no montage could be built (took ${l.toFixed(1)}ms)`);P.nx.info(`debugRunAutoMontage: montage built in ${l.toFixed(1)}ms \u{2014} type=${s.type} sections=${s.resolved.length} skipped=${s.skipped.length} durationMs=${s.durationMs}`);let d=await (0,M.y)(s,e=>e.filepath),c=o.A.fileManager.dirname(d.inputs[0].path),u=o.A.fileManager.join(c,`automontage_${s.type}_${Date.now()}.mp4`);P.nx.info(`debugRunAutoMontage: rendering \u{2014} output=${u}`);let _=performance.now();await n(JSON.stringify(d),u,""),P.nx.info(`debugRunAutoMontage: video rendered in ${(performance.now()-_).toFixed(1)}ms \u{2014} ${u}`)}debugCreateRankableLaughterClip(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:_.default.getId(),t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1e4,n=(0,g.l)(),i=this.decisionSignals.audioModelDataPerUser[e];if(null!=i){for(let e of i.laughterData)e.timestamp_ms>=n-t&&(e.value=1);for(let e of i.rmsData)e.timestamp_ms>=n-t&&(e.value=.9)}else P.nx.warn("debugCreateRankableLaughterClip: no ML audio samples for the local user yet \u2014 join a VC and wait a moment before invoking");this.process({type:P.Gy.LAUGHTER,userId:e,confidence:1})}handleSettingsUpdate(){this.timeline.updateLength(Math.max(h.Ay.getSettings().clipsLength,6e4))}}let G=new w}