UNPKG

@salutejs/jazz-sdk-electron-plugins

Version:

Jazz SDK electron plugins

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