UNPKG

@salutejs/jazz-sdk-electron-plugins

Version:

Jazz SDK electron plugins

2 lines (1 loc) 10.3 kB
import{createEventBus as e,checkElectronVersion as s,createModule as t}from"@salutejs/jazz-sdk-electron/main";import{exec as r}from"child_process";import{systemPreferences as o,desktopCapturer as a,session as n,ipcMain as c,webContents as i,shell as u}from"electron";import{createScope as d}from"nrgy";import{platform as p,loadavg as l,freemem as y,totalmem as m,cpus as g,release as f,arch as h}from"os";import{token as S}from"ditox";import{observe as w}from"nrgy/rxjs";import{pairwise as v,skip as k,tap as b,combineLatest as x,from as A,filter as C,map as L,interval as D,switchMap as M,catchError as I,EMPTY as E}from"rxjs";import{createScope as F}from"rx-effects";const P="jazz-sdk-desktop-capturer-ipc-channel";const z=S({key:"JAZZ_SDK_MAIN_CONTEXT_TOKEN"});const T=t=>{const{electronVersion:r,logger:o,access:n,platform:c}=t,i=d(),u=i.atom(void 0),l=i.atom([]),y=e();i.add(w(l,{sync:!0}).pipe(v(),k(1),b((([e,s])=>{const{added:t,removed:r}=function(e,s){const t=new Map(s.map((e=>[e.id,e]))),r=new Map(e.map((e=>[e.id,e])));for(let s=0;s<e.length;s++)t.delete(e[s].id);for(let e=0;e<s.length;e++)r.delete(s[e].id);return{added:[...t.values()],removed:[...r.values()]}}(e,s);0===t.length&&0===r.length||y({type:"updateSources",payload:{sources:s,added:t,removed:r}})}))).subscribe());const m=p();let g;let f,h,S,F=d();function P(){if(void 0!==f)return f;if("linux"!==m)return f=!1,f;const e=c.getLinuxSessionInfo();return e?(f=void 0!==e.waylandDisplay||(e.xdgSessionType?.toLowerCase().includes("wayland")??!1),f):(f=!1,f)}i.add(x([w(u,{sync:!0}),w(n.screenAccessStatus,{sync:!0}).pipe(C((e=>"granted"===e))),A((async()=>{if("linux"!==m)return!1;if(void 0!==g)return g;const e=c.getLinuxSessionInfo();return g=!!e&&(!(!e.waylandDisplay&&!e.xdgSessionType?.toLowerCase().includes("wayland"))||!(!e.desktopSession?.toLowerCase().includes("plasma")&&!e.xdgSessionType?.toLowerCase().includes("plasma")))})()).pipe(C((e=>!e)))]).pipe(L((e=>e[0]))).subscribe((e=>{if(!e)return F.destroy(),void(F=d());F.add(D(2e3).pipe(M((()=>A(z({types:["screen","window"],images:e.images})))),b((e=>{"failure"!==e.type&&l.set(e.value.sources)})),I((e=>(o.error("Fail get desktop capture sources",e),E)))).subscribe())})));const z=async(e,t=!1)=>{const{types:n,images:c}=e;o.debug("getDesktopCapturerSources with option",JSON.stringify(e));const i=void 0!==h?h:r.major<33||r.major>=38||s(r,">=","37.2.1")||s(r,">=","36.7.1")?(h=!0,h):(h=!P(),h),u=i?c.isEnable?c.thumbnailSize:{width:0,height:0}:void 0;return new Promise((s=>{"darwin"===process.platform&&(S=setTimeout((()=>{s({type:"failure",error:{type:"accessDenied",message:"Access denied"}})}),1e3)),a.getSources({types:n,thumbnailSize:u}).then((e=>{S&&(clearTimeout(S),S=void 0);const r=e.filter((e=>"Gesture Blocking Overlay"!==e.name&&"App Icon Window"!==e.name&&"NVIDIA GeForce Overlay"!==e.name&&!("window"===e.id.split(":")[0]&&"Window"===e.name)));s({type:"success",value:{sources:r.map((e=>({id:e.id,name:e.name,type:e.id.split(":")[0],displayId:e.display_id,image:i&&c.isEnable&&!t?e.thumbnail.toDataURL():void 0})))}})})).catch((t=>{S&&(clearTimeout(S),S=void 0),o.error("Fail getting desktop sources",e,t);const r=t instanceof Error?t.message:"Failed to get sources";s({type:"failure",error:{type:"unknown",message:r}})}))}))};let T=!1;const $=()=>{const e=u();e&&(y({type:"finishProcess",payload:e}),u.set(void 0))};return{processType:u,startProcess:async e=>{if($(),u.set(e),y({type:"startProcess",payload:e}),!T&&!P()){T=!0;const s=await z({types:["screen"],images:e.images.isEnable&&e.images.thumbnailSize.width&&e.images.thumbnailSize.height?e.images:{isEnable:!0,thumbnailSize:{width:1,height:1}}},!e.images.isEnable),t=await z({types:["window"],images:e.images});return"failure"===s.type||"failure"===t.type?"failure"===s.type?s:t:{type:"success",value:{sources:[...s.value.sources,...t.value.sources]}}}return z({types:["screen","window"],images:e.images})},finishProcess:$,getDesktopCapturerSources:z,selectSource:function(e){y({type:"autoSelectSource",payload:e})},setProcessType:e=>{u.set(e)},destroy:()=>{i.destroy()},event$:y.event$}},$={Service:S({key:"DesktopCapturerService"})};async function j(){return t({name:"DesktopCapturerPlugin",imports:{sdkContext:z},factory:_,exports:{service:$.Service}})}function _(e){const{deps:{sdkContext:{logger:s,platform:t,electronVersion:a}}}=e,S=s.getLogger("DesktopCapturer"),w=d(),v=w.add((e=>{const{logger:s}=e,t=d(),r=t.atom("unknown"),a=t.atom("unknown"),n=t.atom("unknown");return{cameraAccessStatus:a,microphoneAccessStatus:r,screenAccessStatus:n,getMediaAccessStatus:e=>{const{type:t}=e;s.debug("getMediaAccessStatus",t);const c="darwin"===process.platform||"win32"===process.platform,i=c?o.getMediaAccessStatus(t):"granted";return c?s.debug("getMediaAccessStatus has status:",i):s.debug("getMediaAccessStatus is unsupported"),"camera"===t?r.set(i):"microphone"===t?a.set(i):"screen"===t&&n.set(i),{status:i}},destroy:()=>{}}})({logger:S})),k=[],b=w.add(T({logger:S,access:v,platform:t,electronVersion:a}));n.defaultSession.setDisplayMediaRequestHandler(((e,s)=>{c.once("jazz-sdk-reply-display-media-stream",(async(e,t)=>{if(!t.source)return s({});let r;if("autoSelectFirstSource"===t.source){S.debug("auto select first source");const t={isEnable:!1};b.setProcessType({frameId:e.frameId,images:t});const o=await b.getDesktopCapturerSources({types:["screen","window"],images:t});if("failure"===o.type||!o.value.sources.length)return s({});r=o.value.sources[0]}else r=t.source;S.debug("Received DisplayMedia stream:",r?.id,"audio:",t.audio),k.some((e=>r.id===e.id))||k.push(r);const o={video:{id:r.id,name:r.name}};t.audio&&(o.audio="loopback"),s(o),"autoSelectFirstSource"===t.source&&b.selectSource({source:r,audio:t.audio??!1})})),e.frame?.send("jazz-sdk-ask-display-media-stream"),S.debug("Ask DisplayMedia stream")}));c.removeHandler(P),c.handle(P,(async(e,s)=>{switch(s.type){case"getDesktopCapturerSources":return L(s.payload);case"askForMediaAccess":return D(s.payload);case"getMediaAccessStatus":return M(s.payload);case"systemSettings":return I(s.payload);case"osInfo":return x();case"capturerSourcesStartProcess":return A(e,s.payload);case"capturerSourcesFinishProcess":return C();default:!function(e){throw new Error(`Unexpected value ${e}`)}(s)}})),w.onDestroy((()=>c.removeHandler(P))),w.add(b.event$.subscribe((e=>{const s=b.processType();s&&i.fromId(s.frameId)?.send("jazz-sdk-capturer-sources-event",e)})));const x=async()=>{S.debug("start getting os info");const e=await t.getLinuxDistributionInfo(),s=t.getLinuxSessionInfo();(e||s)&&S.debug("getting linux distribution info");const r={arch:h(),platform:p(),release:f(),cpus:g(),totalmem:m(),freemem:y(),loadavg:l(),linuxSessionInfo:s,linuxDistributionInfo:e};return S.debug("getting os info"),{type:"osInfo",payload:r}},A=async(e,s)=>({type:"capturerSourcesStartProcess",payload:await b.startProcess({frameId:e.frameId,images:s?.images||{isEnable:!1}})}),C=async()=>(b.finishProcess(),{type:"capturerSourcesFinishProcess"}),L=async e=>({type:"getDesktopCapturerSources",payload:await b.getDesktopCapturerSources(e)}),D=async e=>{const{type:s}=e;return"darwin"===process.platform||"win32"===process.platform?O(s,S):(S.debug("AskForMediaAccess unsupported by OS"),{type:"askForMediaAccess",payload:{status:!0,type:s}})},M=async e=>({type:"getMediaAccessStatus",payload:v.getMediaAccessStatus(e)}),I=async e=>{const{key:s}=e;if("linux"===process.platform)await(async e=>{const{key:s}=e,o=t.getLinuxSessionInfo();if(!o)return;let a="";const n=o.desktopSession?.toLowerCase().includes("gnome")??o.xdgCurrentDesktop?.toLowerCase().includes("gnome")??!1,c=o.desktopSession?.toLowerCase().includes("kde")??o.xdgCurrentDesktop?.toLowerCase().includes("kde")??!1;if(n)a="gnome-control-center privacy";else if(c){const e="systemsettings5 kcmquicklauncher:";switch(s){case"camera-security":a=`${e}//camera`;break;case"microphone-security":a=`${e}//multimedia`;break;case"screen-share-security":a=`${e}//screenssharing`}}a&&await r(a)})(e);else{const e=N(s);e.length>0&&await u.openExternal(e)}return{type:"systemSettings",payload:{key:s}}};return{destroy:()=>{w.destroy()},service:{getLastSelectedSources:()=>k}}}async function O(e,s){return o.askForMediaAccess(e).then((t=>(s.debug("AskForMediaAccess has status",t),{type:"askForMediaAccess",payload:{status:t,type:e}}))).catch((t=>(s.debug("AskForMediaAccess catch error",t),{type:"askForMediaAccess",payload:{status:!1,type:e}})))}function N(e){if("darwin"===process.platform)switch(e){case"microphone-security":return"x-apple.systempreferences:com.apple.preference.security?Privacy_Microphone";case"camera-security":return"x-apple.systempreferences:com.apple.preference.security?Privacy_Camera";case"screen-share-security":return"x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture";default:return"x-apple.systempreferences:"}if("win32"===process.platform)switch(e){case"microphone-security":return"ms-settings:privacy-microphone";case"camera-security":return"ms-settings:privacy-webcam";default:return"ms-settings:"}return""}const R=e=>e.container.resolve($.Service),W={debug:"DEBUG",info:"INFO ",warn:"WARN ",error:"ERROR"};function B(e){const s=function(e){switch(e){case"debug":return console.debug;case"info":return console.log;case"warn":return console.warn;default:return console.error}}(e.level);s&&s(`${W[e.level]} [${e.tag}]`,...e.messages)}async function V(e){return t({imports:{sdkContext:z},factory:s=>function(e){const{deps:{sdkContext:s},options:t={}}=e,r=t.isEnableStdout??!1,o=t.logLevel??"info",a=t.subscribe,{logMessage:n,logLevelWeight:c,getLogBuffer:i}=s.logs,u=F();r&&u.createController((()=>function(e){const{logEvent$:s,logLevel:t,getLogBuffer:r,logLevelWeight:o}=e,a=o.info,n=F(),c=t?o[t]:a;n.handle(s,(e=>{u(e)&&B(e)}));const i=r();function u(e){return o[e.level]>=c}return i.length>0&&i.forEach((e=>{u(e)&&B(e)})),{destroy:n.destroy}}({logEvent$:n.event$,logLevel:o,getLogBuffer:i,logLevelWeight:c})));if(a){u.handle(n.event$,(e=>{a(e)}));const e=i();e.length>0&&e.forEach((e=>{a(e)}))}return{destroy:()=>{u.destroy()}}}({...s,options:e})})}export{$ as DesktopCapturerTokens,j as desktopCapturerPlugin,R as getDesktopCapturerService,N as getSystemSettingsUrl,O as handleAskForMediaAccess,V as logsPlugin};