{"version":3,"file":"WebCamManager.js","sourceRoot":"","sources":["../../../TS/WebCam/WebCamManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAE5E,MAAM,OAAO,kBAAkB;CAI9B;AAED,MAAM,OAAO,aAAa;IAGf,UAAU;QACb,IAAI,CAAC,WAAW,GAAG,eAAe,CAAC;QACnC,MAAM,CAAC,eAAe,CAAC,GAAG,IAAI,CAAC;QAC/B,OAAO,IAAI,CAAC;IAChB,CAAC;IAEM,KAAK,CAAC,0BAA0B;QACnC,IAAI;YACA,IAAI,eAAe,GAAG,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;YACnF,IAAI,cAAc,GAAG,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;YAClF,IAAI,aAAa,GAAG,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;YAClF,IAAI,iBAAiB,GAAG,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;YAEvF,IAAI,WAAW,GAAU,CAAC,iBAAiB,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,CAAC,CAAC;YAE7F,IAAI,SAAgB,CAAC;YAErB,KAAK,IAAI,CAAC,IAAI,WAAW,EAAE;gBACvB,IAAI;oBACA,MAAM,SAAS,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;oBAE7C,IAAI,CAAC,GAAG,IAAI,kBAAkB,EAAE,CAAC;oBACjC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC;oBAC9B,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC;oBAEhC,OAAO,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;iBAC/B;gBAAC,OAAO,CAAC,EAAE;oBACR,SAAS,GAAG,CAAC,CAAC;iBACjB;aACJ;YAED,kCAAkC;YAClC,IAAI,SAAS,IAAI,IAAI,EAAE;gBACnB,OAAO,cAAc,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;aAC1C;SACJ;QAAC,OAAO,CAAC,EAAE;YACR,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAClC;IACL,CAAC;IAEM,KAAK,CAAC,yBAAyB,CAAC,YAA8B,EACjE,QAAgB,EAChB,OAAe,EACf,UAAkB,EAClB,WAAmB,EACnB,WAA8B,EAC9B,UAA4B;QAG5B,IAAI;YACA,IAAI,EAAE,GAAG,IAAI,cAAc,EAAE,CAAC;YAE9B,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC,eAAe,CAAC,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;YAErH,IAAI,EAAE,CAAC,OAAO,EAAE;gBACZ,OAAO,EAAE,CAAC,YAAY,CAAC;aAC1B;YAED,OAAO,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;SAC5B;QAAC,OAAO,CAAC,EAAE;YACR,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAC9B;IACL,CAAC;CACJ;AAED,MAAM,OAAO,cAAc;IAA3B;QA+EY,oCAA+B,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;QAE/C,oBAAe,GAAG,CAAC,GAAwB,EAAE,QAA4B,EAAE,EAAE;YACjF,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAEtE,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,iBAAiB,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,iBAAiB,CAAC,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE;gBAC3M,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;gBAE7G,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBAC/F,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;gBAC7D,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;aACjG;iBAAM;gBACH,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;gBAE7G,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;gBACtE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;gBACxE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC;aAC7G;YAED,IAAI,IAAI,CAAC,WAAW,EAAE;gBAClB,IAAI,CAAC,KAAK,CAAC,yBAAyB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;aAC9D;YAED,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAClD,CAAC,CAAA;IAoKL,CAAC;IAtPU,KAAK,CAAC,eAAe,CAAC,YAA8B,EACvD,QAAgB,EAChB,OAAe,EACf,UAAkB,EAClB,WAAmB,EACnB,WAA8B,EAC9B,UAA4B;QAG5B,IAAI;YACA,IAAI,OAAO,GAAG,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;YAChD,IAAI,YAAY,GAAG,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;YAEpD,IAAI,YAAY,IAAI,IAAI,EAAE;gBACtB,IAAI,CAAC,KAAK,GAAG,YAAiC,CAAC;aAClD;iBACI;gBACD,OAAO,cAAc,CAAC,IAAI,CAAC,yBAAyB,OAAO,YAAY,CAAC,CAAC;aAC5E;YAED,IAAI,OAAO,IAAI,IAAI,EAAE;gBACjB,IAAI,CAAC,kBAAkB,GAAG,YAAY,CAAC;gBAEvC,IAAI,CAAC,MAAM,GAAG,OAA4B,CAAC;gBAC3C,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;gBAE9C,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;gBAC7B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;gBAE/B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;gBAC/B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;gBAE7B,OAAO,cAAc,CAAC,EAAE,CAAC;aAC5B;iBACI;gBACD,OAAO,cAAc,CAAC,IAAI,CAAC,0BAA0B,QAAQ,YAAY,CAAC,CAAC;aAC9E;SAEJ;QAAC,OAAO,CAAC,EAAE;YACR,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAClC;IACL,CAAC;IAEM,KAAK,CAAC,sBAAsB,CAAC,WAA8B,EAAE,UAA4B;QAC5F,IAAI;YACA,IAAI,IAAI,CAAC,WAAW,IAAI,WAAW,IAAI,IAAI,CAAC,UAAU,IAAI,UAAU,EAAE;gBAClE,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;gBACvB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;gBAC/B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;gBAC7B,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;aAC3B;YAED,OAAO,cAAc,CAAC,EAAE,CAAC;SAC5B;QAAC,OAAO,CAAC,EAAE;YACR,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAClC;IACL,CAAC;IA4BM,KAAK,CAAC,WAAW;QACpB,IAAI;YACA,IAAI,IAAI,CAAC,QAAQ,EAAE;gBACf,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;gBAExB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;gBACtB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;gBAExB,OAAO,cAAc,CAAC,EAAE,CAAC;aAC5B;YAED,OAAO,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;SAElC;QAAC,OAAO,CAAC,EAAE;YACR,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAClC;IACL,CAAC;IAEM,KAAK,CAAC,UAAU;QACnB,IAAI;YACA,IAAI,WAAW,GAAG;gBACd,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE;oBACH,KAAK,EAAE,IAAI,CAAC,UAAU;oBACtB,MAAM,EAAE,IAAI,CAAC,WAAW;iBAC3B;aACJ,CAAC;YAEF,IAAI,IAAI,CAAC,UAAU,IAAI,gBAAgB,CAAC,WAAW,EAAE;gBACjD,IAAI,QAAQ,GAAG,SAAS,CAAC,YAAY,CAAC,uBAAuB,EAAE,CAAC;gBAChE,IAAI,QAAQ,CAAC,YAAY,CAAC,EAAE;oBACxB,WAAW,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,aAAa,CAAC;iBACnD;qBAAM;oBACH,IAAI,YAAY,GAAG,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;oBACpD,IAAI,CAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,MAAM,IAAG,CAAC,EAAE;wBAC1B,WAAW,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,EAAE,YAAY,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;qBAC7F;iBACJ;aACJ;YAED,IAAI,IAAI,CAAC,WAAW,EAAE;gBAClB,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;aAC/D;YAED,IAAI,CAAC,WAAW,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;YAE1E,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC;YAExC,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YAExB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;YAE1B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YAExB,4BAA4B;YAC5B,IAAI,CAAC,KAAK,CAAC,yBAAyB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAE3D,OAAO,cAAc,CAAC,EAAE,CAAC;SAC5B;QACD,OAAO,CAAC,EAAE;YACN,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAClC;IACL,CAAC;IAEM,KAAK,CAAC,mBAAmB;QAC5B,IAAI,OAAO,GAAG,EAAE,CAAC;QAEjB,IAAI;YACA,IAAI,CAAC,SAAS,CAAC,YAAY,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,gBAAgB,EAAE;gBACrE,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;gBACjD,OAAO,OAAO,CAAC;aAClB;YAED,IAAI,OAAO,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,gBAAgB,EAAE,CAAC;YAE9D,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,IAAI,YAAY,CAAC,CAAC;SACnE;QACD,OAAO,CAAC,EAAE;YACN,sBAAsB;YACtB,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;SACtD;QAED,OAAO,OAAO,CAAC;IACnB,CAAC;IAEM,KAAK,CAAC,aAAa,CAAC,OAAe;QACtC,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QAEvB,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAErD,OAAO,CAAC,CAAC;IACb,CAAC;IAIM,KAAK,CAAC,kBAAkB;QAC3B,IAAI;YACA,IAAI,IAAI,CAAC,WAAW,EAAE;gBAClB,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBAExC,IAAI,EAAE,CAAC,OAAO,EAAE;oBACZ,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;oBAEzB,OAAO,IAAI,CAAC;iBACf;aACJ;YAED,OAAO,IAAI,CAAC,aAAa,CAAC;SAC7B;QAAC,OAAO,CAAC,EAAE;YACR,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAE9C,OAAO,IAAI,CAAC;SACf;IACL,CAAC;IAEM,iBAAiB;QACpB,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,EAAE;YAC7B,OAAO,IAAI,CAAC,cAAc,CAAC;SAC9B;QAED,OAAO,cAAc,CAAC,EAAE,CAAC;IAC7B,CAAC;IAEM,KAAK,CAAC,iBAAiB;QAC1B,IAAI;YACA,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;YAEvB,IAAI,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAEzF,IAAI,CAAC,aAAa,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAE3D,OAAO,cAAc,CAAC,EAAE,CAAC;SAC5B;QAAC,OAAO,CAAC,EAAE;YACR,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAClC;IACL,CAAC;IAEM,KAAK,CAAC,SAAS;QAClB,IAAI;YACA,IAAI,IAAI,CAAC,WAAW,EAAE;gBAClB,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;gBAEnB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;gBACrB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;aAC5B;YAED,OAAO,cAAc,CAAC,EAAE,CAAC;SAE5B;QAAC,OAAO,CAAC,EAAE;YACR,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;YAEzB,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAClC;IACL,CAAC;IAEM,KAAK,CAAC,YAAY;QACrB,IAAI;YACA,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;SAC1B;QAAC,OAAO,CAAC,EAAE;YACR,sBAAsB;SACzB;IACL,CAAC;CACJ;AAsBD,IAAK,iBAGJ;AAHD,WAAK,iBAAiB;IAClB,iEAAY,CAAA;IACZ,mEAAa,CAAA;AACjB,CAAC,EAHI,iBAAiB,KAAjB,iBAAiB,QAGrB;AAED,IAAK,gBAGJ;AAHD,WAAK,gBAAgB;IACjB,uDAAQ,CAAA;IACR,qEAAe,CAAA;AACnB,CAAC,EAHI,gBAAgB,KAAhB,gBAAgB,QAGpB","sourcesContent":["import { IJSModule } from \"../IJSModule.js\";\r\nimport { JSOpResult, JSOpResultVoid, JSOpResultJSON } from \"../OpResult.js\";\r\n\r\nexport class WebCamCapabilities {\r\n public Width: number;\r\n public Height: number;\r\n public FPS: number;\r\n}\r\n\r\nexport class WebCamManager implements IJSModule {\r\n public serviceName: string;\r\n\r\n public initialize(): boolean {\r\n this.serviceName = 'WebCamManager';\r\n window['WebCamManager'] = this;\r\n return true;\r\n }\r\n\r\n public async getWebCamCapabilitiesAsync(): Promise {\r\n try {\r\n let qvgaConstraints = { video: { width: { exact: 320 }, height: { exact: 240 } } };\r\n let vgaConstraints = { video: { width: { exact: 640 }, height: { exact: 480 } } };\r\n let hdConstraints = { video: { width: { exact: 1280 }, height: { exact: 720 } } };\r\n let fullHdConstraints = { video: { width: { exact: 1920 }, height: { exact: 1080 } } };\r\n\r\n let constraints: any[] = [fullHdConstraints, hdConstraints, vgaConstraints, qvgaConstraints];\r\n\r\n let lastError: Error;\r\n\r\n for (let c of constraints) {\r\n try {\r\n await navigator.mediaDevices.getUserMedia(c);\r\n\r\n let x = new WebCamCapabilities();\r\n x.Width = c.video.width.exact;\r\n x.Height = c.video.height.exact;\r\n\r\n return JSOpResultJSON.OK(x);\r\n } catch (e) {\r\n lastError = e;\r\n }\r\n }\r\n\r\n // no available webcam resolutions\r\n if (lastError != null) {\r\n return JSOpResultJSON.Error(lastError);\r\n }\r\n } catch (e) {\r\n return JSOpResultJSON.Error(e);\r\n }\r\n }\r\n\r\n public async createWebCamInstanceAsync(componentRef: IDotNetReference,\r\n canvasId: string,\r\n videoId: string,\r\n videoWidth: number,\r\n videoHeight: number,\r\n orientation: WebCamOrientation,\r\n facingMode: CameraFacingMode\r\n ): Promise {\r\n\r\n try {\r\n let ci = new WebCamInstance();\r\n\r\n let cr = await ci.initializeAsync(componentRef, canvasId, videoId, videoWidth, videoHeight, orientation, facingMode);\r\n\r\n if (cr.IsNotOK) {\r\n return cr.AsJSOpResult;\r\n }\r\n\r\n return JSOpResult.OK(ci);\r\n } catch (e) {\r\n return JSOpResult.Error(e);\r\n }\r\n }\r\n}\r\n\r\nexport class WebCamInstance {\r\n private canvas: HTMLCanvasElement;\r\n private canvasCtx: CanvasRenderingContext2D;\r\n\r\n private mediaStream: MediaStream;\r\n\r\n private video: HTMLVideoElementX;\r\n\r\n private videoHeight: number;\r\n private videoWidth: number;\r\n\r\n private orientation: WebCamOrientation;\r\n private facingMode: CameraFacingMode;\r\n\r\n private isStreaming: boolean;\r\n private isPaused: boolean;\r\n\r\n private dotNetComponentRef: IDotNetReference;\r\n\r\n private capturedImage: Uint8Array;\r\n\r\n public async initializeAsync(componentRef: IDotNetReference,\r\n canvasId: string,\r\n videoId: string,\r\n videoWidth: number,\r\n videoHeight: number,\r\n orientation: WebCamOrientation,\r\n facingMode: CameraFacingMode\r\n ): Promise {\r\n\r\n try {\r\n let element = document.getElementById(canvasId);\r\n let videoElement = document.getElementById(videoId);\r\n\r\n if (videoElement != null) {\r\n this.video = videoElement as HTMLVideoElementX;\r\n }\r\n else {\r\n return JSOpResultVoid.Fail(`Video element with ID ${videoId} not found`);\r\n }\r\n\r\n if (element != null) {\r\n this.dotNetComponentRef = componentRef;\r\n\r\n this.canvas = element as HTMLCanvasElement;\r\n this.canvasCtx = this.canvas.getContext('2d');\r\n\r\n this.videoWidth = videoWidth;\r\n this.videoHeight = videoHeight;\r\n\r\n this.orientation = orientation;\r\n this.facingMode = facingMode;\r\n\r\n return JSOpResultVoid.OK;\r\n }\r\n else {\r\n return JSOpResultVoid.Fail(`Canvas element with ID ${canvasId} not found`);\r\n }\r\n\r\n } catch (e) {\r\n return JSOpResultVoid.Error(e);\r\n }\r\n }\r\n\r\n public async changeOrientationAsync(orientation: WebCamOrientation, facingMode: CameraFacingMode): Promise {\r\n try {\r\n if (this.orientation != orientation || this.facingMode != facingMode) {\r\n await this.stopAsync();\r\n this.orientation = orientation;\r\n this.facingMode = facingMode;\r\n await this.startAsync();\r\n }\r\n\r\n return JSOpResultVoid.OK;\r\n } catch (e) {\r\n return JSOpResultVoid.Error(e);\r\n }\r\n }\r\n\r\n private rotate90DegreesCounterClockwise = -Math.PI / 2;\r\n\r\n private onFrameReceived = (now: DOMHighResTimeStamp, metadata: VideoFrameMetadata) => {\r\n this.canvasCtx.clearRect(0, 0, this.canvas.width, this.canvas.height);\r\n\r\n if ((this.orientation == WebCamOrientation.Portrait && this.video.videoHeight < this.video.videoWidth) || (this.orientation == WebCamOrientation.Landscape && this.video.videoHeight > this.video.videoWidth)) {\r\n let scale = Math.max(this.canvas.height / this.video.videoWidth, this.canvas.width / this.video.videoHeight);\r\n\r\n this.canvasCtx.setTransform(scale, 0, 0, scale, this.canvas.width / 2, this.canvas.height / 2);\r\n this.canvasCtx.rotate(-this.rotate90DegreesCounterClockwise);\r\n this.canvasCtx.drawImage(this.video, -this.video.videoWidth / 2, -this.video.videoHeight / 2);\r\n } else {\r\n let scale = Math.max(this.canvas.height / this.video.videoHeight, this.canvas.width / this.video.videoWidth);\r\n\r\n let x = (this.canvas.width / 2) - (this.video.videoWidth / 2) * scale;\r\n let y = (this.canvas.height / 2) - (this.video.videoHeight / 2) * scale;\r\n this.canvasCtx.drawImage(this.video, x, y, this.video.videoWidth * scale, this.video.videoHeight * scale);\r\n }\r\n\r\n if (this.isStreaming) {\r\n this.video.requestVideoFrameCallback(this.onFrameReceived);\r\n }\r\n\r\n this.canvasCtx.setTransform(1, 0, 0, 1, 0, 0);\r\n }\r\n\r\n public async resumeAsync(): Promise {\r\n try {\r\n if (this.isPaused) {\r\n await this.video.play();\r\n\r\n this.isPaused = false;\r\n this.isStreaming = true;\r\n\r\n return JSOpResultVoid.OK;\r\n }\r\n\r\n return await this.startAsync();\r\n\r\n } catch (e) {\r\n return JSOpResultVoid.Error(e);\r\n }\r\n }\r\n\r\n public async startAsync(): Promise {\r\n try {\r\n let constraints = {\r\n audio: false,\r\n video: {\r\n width: this.videoWidth,\r\n height: this.videoHeight\r\n }\r\n };\r\n\r\n if (this.facingMode == CameraFacingMode.Environment) {\r\n let supports = navigator.mediaDevices.getSupportedConstraints();\r\n if (supports['facingMode']) {\r\n constraints.video['facingMode'] = 'environment';\r\n } else {\r\n let availCameras = await this.getAvailableCameras();\r\n if (availCameras?.length > 1) {\r\n constraints.video['deviceId'] = { exact: availCameras[availCameras.length - 1].deviceId };\r\n }\r\n }\r\n }\r\n\r\n if (this.mediaStream) {\r\n this.mediaStream.getTracks().forEach(track => track.stop());\r\n }\r\n\r\n this.mediaStream = await navigator.mediaDevices.getUserMedia(constraints);\r\n\r\n this.video.srcObject = this.mediaStream;\r\n\r\n await this.video.play();\r\n\r\n this.capturedImage = null;\r\n\r\n this.isStreaming = true;\r\n\r\n // kick off the capture loop\r\n this.video.requestVideoFrameCallback(this.onFrameReceived);\r\n\r\n return JSOpResultVoid.OK;\r\n }\r\n catch (e) {\r\n return JSOpResultVoid.Error(e);\r\n }\r\n }\r\n\r\n public async getAvailableCameras(): Promise {\r\n let cameras = [];\r\n\r\n try {\r\n if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {\r\n console.log('enumerateDevices() not supported.');\r\n return cameras;\r\n }\r\n\r\n let devices = await navigator.mediaDevices.enumerateDevices();\r\n\r\n cameras = devices.filter(device => device.kind == 'videoinput');\r\n }\r\n catch (e) {\r\n // VM - log somehow...\r\n console.log('getAvailableCameras unhandled error');\r\n }\r\n\r\n return cameras;\r\n }\r\n\r\n public async getImageAsync(quality: number): Promise {\r\n await this.stopAsync();\r\n\r\n let s = this.canvas.toDataURL('image/jpeg', quality);\r\n\r\n return s;\r\n }\r\n\r\n private lastImageError: JSOpResultVoid;\r\n\r\n public async getImageBytesAsync(): Promise {\r\n try {\r\n if (this.isStreaming) {\r\n let cr = await this.captureImageAsync();\r\n\r\n if (cr.IsNotOK) {\r\n this.lastImageError = cr;\r\n\r\n return null;\r\n }\r\n }\r\n\r\n return this.capturedImage;\r\n } catch (e) {\r\n this.lastImageError = JSOpResultVoid.Error(e);\r\n\r\n return null;\r\n }\r\n }\r\n\r\n public getLastImageError(): JSOpResultVoid {\r\n if (this.lastImageError != null) {\r\n return this.lastImageError;\r\n }\r\n\r\n return JSOpResultVoid.OK;\r\n }\r\n\r\n public async captureImageAsync(): Promise {\r\n try {\r\n await this.stopAsync();\r\n\r\n let imageData = this.canvasCtx.getImageData(0, 0, this.canvas.width, this.canvas.height);\r\n\r\n this.capturedImage = new Uint8Array(imageData.data.buffer);\r\n\r\n return JSOpResultVoid.OK;\r\n } catch (e) {\r\n return JSOpResultVoid.Error(e);\r\n }\r\n }\r\n\r\n public async stopAsync(): Promise {\r\n try {\r\n if (this.isStreaming) {\r\n this.video.pause();\r\n\r\n this.isPaused = true;\r\n this.isStreaming = false;\r\n }\r\n\r\n return JSOpResultVoid.OK;\r\n\r\n } catch (e) {\r\n this.isStreaming = false;\r\n\r\n return JSOpResultVoid.Error(e);\r\n }\r\n }\r\n\r\n public async disposeAsync() {\r\n try {\r\n await this.stopAsync();\r\n } catch (e) {\r\n // CJ - what to log...\r\n }\r\n }\r\n}\r\n\r\ninterface VideoFrameMetadata {\r\n presentationTime: DOMHighResTimeStamp;\r\n expectedDisplayTime: DOMHighResTimeStamp;\r\n width: number;\r\n height: number;\r\n mediaTime: number;\r\n presentedFrames: number;\r\n processingDuration?: number;\r\n captureTime?: DOMHighResTimeStamp;\r\n receiveTime?: DOMHighResTimeStamp;\r\n rtpTimestamp?: number;\r\n}\r\n\r\ntype VideoFrameRequestCallbackId = number;\r\n\r\ninterface HTMLVideoElementX extends HTMLVideoElement {\r\n requestVideoFrameCallback(callback: (now: DOMHighResTimeStamp, metadata: VideoFrameMetadata) => any): VideoFrameRequestCallbackId;\r\n cancelVideoFrameCallback(handle: VideoFrameRequestCallbackId): void;\r\n}\r\n\r\nenum WebCamOrientation {\r\n Portrait = 0,\r\n Landscape = 1\r\n}\r\n\r\nenum CameraFacingMode {\r\n User = 0,\r\n Environment = 1\r\n}\r\n"]}