Commit 5296a306 by Иван Кубота

two streams, buggy version

parent 2dde47c8
let content, remoteVideoEl;
const store = window.store = new Store({
conference_id: 'SelfieBarracuda_con',
connection: false
});
const Input = function(cfg, bind) {
cfg.onkeyup = cfg.oninput = cfg.onchange = function() {
store.set(bind, input.value);
};
var input = D.h('input', cfg);
store.sub(bind, function(val) {
input.value = val;
});
return input;
};
const LabeledInput = function(cfg, bind) {
return D.h('label', {},
D.div.apply(D, [{cls: 'label_label'}].concat(cfg.label)),
Input(cfg, bind)
)
}
const isConnected = new Store.Value.Boolean(false);
store.sub('connection', function(val) {
isConnected.set(val)
});
var Select = function(cfg) {
let isOpen = this.isOpen = new Store.Value.Boolean(false);
var table = D.div({cls: 'dropdown-list'}, _=>{
store.sub(cfg.values, function(val) {
if(val){
_(val.map(function(v) {
return D.div({cls: 'dropdown-item', 'data-id': v.value, onclick: function() {
cfg.bind.set(v.value);
isOpen.set(false);
}}, v.text)
}));
}
});
});
var dom = D.div({cls: 'form-field'},
D.div({cls: 'form-field__label'},
D.span({cls: 'form-field__label-text'}, cfg.label),
D.div({cls: ['dropdown-field', {
'dropdown-field--opened': isOpen
}]},
D.h('button', {
cls: 'dropdown-field__toggler',
onclick: () => isOpen.toggle()
},
D.span({cls: D.cls(
"dropdown-field__placeholder", {
"dropdown-field__placeholder--filled": _=>cfg.bind.sub(val=>_(!!(cfg.multivalue ? val && val.length : val && val.name)))
} )},
_ => {
cfg.bind.sub( val => {
if( val ){
var vals = store.get(cfg.values) || [],
theVal = vals.filter(v=>v.value === val)[0];
_(theVal?theVal.text: 'Select')
}else{
_( cfg.placeholder );
}
} );
}
)
),
D.div({cls: 'dropdown-field__tooltip'},
table
)
)
)
);
return dom;
}
var camera1canvas, camera2canvas, single = new Store.Value.Boolean(true);
D.div({cls: 'top-bar', renderTo: document.body},
D.h('img', {src: 'amazon-logo.svg'}),
D.div({cls: 'buttons'},
D.h('button', {cls: ['button secondary', {hidden: Store.NOT(isConnected)}], onclick: ()=>store.set('connection', false)}, 'End session'),
D.h('button', {cls: ['button primary', {hidden: isConnected}], onclick: ()=>store.set('connection', true)}, 'Ready to connect')
),
content = D.div({cls: 'content'},
D.div({cls: 'block'},
D.div({cls: 'header'}, 'Cameras'),
Select({values: 'videoinput', bind: store.bind('videoinput1'), label: 'Camera 1'}),
camera1canvas = D.h('canvas', {
cls: "output_canvas",
width: "640px",
height: "480px",
style: {
/*display: 'none',*/
width: '320px'
}
}),
D.div({},
D.h('button', {cls: 'switch-button', onclick: _=>single.toggle()},
_=>single.hook(val=>_(val?'Duo':'Single'))
),
),
D.div({cls: [{hidden: single}]},
Select({values: 'videoinput', bind: store.bind('videoinput2'), label: 'Camera 2'}),
camera2canvas = D.h('canvas', {
cls: "output_canvas",
width: "640px",
height: "480px",
style: {
/*display: 'none',*/
width: '320px'
}
})
),
),
D.div({cls: 'block'},
D.div({cls: 'header'}, 'Conference info'),
LabeledInput({label: 'Session ID', cls: 'callapp_address input', autocomplete: 'off', value: 'SelfieBarracuda_con'}, 'conference_id'),
),
D.div({cls: ['block', {hidden: Store.NOT(isConnected)}]},
D.div({cls: ['header']}, 'Remote video'),
remoteVideoEl = window.remoteVideoEl = D.div({cls: 'remote-video'})
)
)
);
var streams = {};
var video1 = D.h('video');
var video2 = D.h('video');
var camera1canvasCtx = camera1canvas.getContext('2d');
var camera2canvasCtx = camera2canvas.getContext('2d');
var updateVideos = function() {
camera1canvasCtx.drawImage(video1,0,0);
if(!single.get()){
camera2canvasCtx.drawImage( video2, 0, 0 );
}
requestAnimationFrame(updateVideos);
};
requestAnimationFrame(updateVideos);
store.sub(['videoinput1', 'videoinput2'], async (input1, input2) => {
await Promise.all([input1, input2].map(async function(val, i) {
if(val){
try{
if(val in streams){
stream = streams[val];
}else{
var stream = await navigator.mediaDevices.getUserMedia( {
video: {
deviceId: { exact: val }
}
} );
}
streams[val] = stream;
var video = [video1, video2][i];
video.srcObject = stream;
video.play();
console.log('2', +new Date());
}catch(e){
console.error(e)
}
}
for(var i in streams){
if(i !== input1 && i !== input2){
var stream = streams[i];
stream.getTracks().forEach(function(track) {
track.stop();
});
}
}
}));
});
function gotDevices(deviceInfos) {
// Handles being called several times to update labels. Preserve values.
var devices = {audioinput: [], audiooutput: [], videoinput: []};
for (let i = 0; i !== deviceInfos.length; ++i) {
const deviceInfo = deviceInfos[i];
const option = {value: deviceInfo.deviceId};
if(!(deviceInfo.kind in devices)){
devices[ deviceInfo.kind ] = [];
}
devices[deviceInfo.kind].push(option);
var count = devices[deviceInfo.kind].length;
if (deviceInfo.kind === 'audioinput') {
option.text = deviceInfo.label || `microphone ${count}`;
} else if (deviceInfo.kind === 'audiooutput') {
option.text = deviceInfo.label || `speaker ${count}`;
} else if (deviceInfo.kind === 'videoinput') {
option.text = deviceInfo.label || `camera ${count}`;
} else {
console.log('Some other kind of source/device: ', deviceInfo);
}
}
store.set('videoinput', devices.videoinput);
store.set('videoinput1', devices.videoinput[devices.videoinput.length - 1].value);
store.set('videoinput2', devices.videoinput[devices.videoinput.length - 2].value);
console.log(devices);
/*const values = selectors.map(select => select.value);
selectors.forEach(select => {
while (select.firstChild) {
select.removeChild(select.firstChild);
}
});
for (let i = 0; i !== deviceInfos.length; ++i) {
const deviceInfo = deviceInfos[i];
const option = document.createElement('option');
option.value = deviceInfo.deviceId;
if (deviceInfo.kind === 'audioinput') {
option.text = deviceInfo.label || `microphone ${audioInputSelect.length + 1}`;
audioInputSelect.appendChild(option);
} else if (deviceInfo.kind === 'audiooutput') {
option.text = deviceInfo.label || `speaker ${audioOutputSelect.length + 1}`;
audioOutputSelect.appendChild(option);
} else if (deviceInfo.kind === 'videoinput') {
option.text = deviceInfo.label || `camera ${videoSelect.length + 1}`;
videoSelect.appendChild(option);
} else {
console.log('Some other kind of source/device: ', deviceInfo);
continue;
}
}
selectors.forEach((select, selectorIndex) => {
if (Array.prototype.slice.call(select.childNodes).some(n => n.value === values[selectorIndex])) {
select.value = values[selectorIndex];
}
});*/
}
var handleError = function(e) {
console.log('Error', e)
}
var RTC = function(parent, canvas, devname) {
let callApp;
console.log("init callapp");
if (parent == null) {
console.log("parent was null");
parent = document.body;
}
awrtc.SLog.SetLogLevel(awrtc.SLogLevel.Info);
callApp = new apps.VideoInputApp();
const media = new awrtc.Media();
awrtc.Media.SharedInstance.VideoInput.AddCanvasDevice(canvas, devname, canvas.width / 2, canvas.height / 2, 30);
setInterval(() => {
awrtc.Media.SharedInstance.VideoInput.UpdateFrame(devname);
}, 50);
//apps.VideoInputApp.sVideoDevice = devname;
callApp.sVideoDevice = devname;
callApp.setupUi(parent);
}
store.sub('appLoaded', function(loaded) {
if(!loaded)
return;
let instance = new RTC(document.querySelector("#videoinputapp1"), camera1canvas, 'canvas1');
instance.mUiRemoteVideoParent = remoteVideoEl;
let instance2 = new RTC(document.querySelector("#videoinputapp1"), camera2canvas, 'canvas2');
instance2.mUiRemoteVideoParent = remoteVideoEl;
const selfieSegmentation1 = new SelfieSegmentation( {
locateFile: ( file ) => {
return `https://cdn.jsdelivr.net/npm/@mediapipe/selfie_segmentation/${file}`;
}
} );
selfieSegmentation1.setOptions( {
modelSelection: 1,
} );
selfieSegmentation1.onResults( function(){
window.onResult1.apply( this, arguments )
} );
const selfieSegmentation2 = new SelfieSegmentation( {
locateFile: ( file ) => {
return `https://cdn.jsdelivr.net/npm/@mediapipe/selfie_segmentation/${file}`;
}
} );
selfieSegmentation2.setOptions( {
modelSelection: 1,
} );
selfieSegmentation2.onResults( function(){
window.onResult2.apply( this, arguments )
} );
var segmentation = async function() {
if(video1.videoWidth>10 && store.get('videoinput1')){
//debugger
await selfieSegmentation1.send( { image: video1 } );
//camera1canvasCtx.drawImage(selfieSegmentation1.g.l,0,0)
}
if(single.get() === false && video2.videoWidth>10 && store.get('videoinput2')){
//debugger
await selfieSegmentation2.send( { image: video2 } );
//camera1canvasCtx.drawImage(selfieSegmentation1.g.l,0,0)
}
requestAnimationFrame(segmentation);
};
requestAnimationFrame(segmentation);
});
var resultProcessor = function(canvasElement) {
window.canvasElement =canvasElement;
const segmentations = [false,false,false,false];
let sPointer = 0;
var w = 720, h = 405;
var tmpCanvas = D.h('canvas', {width: w, height: h}),
tmpCtx = tmpCanvas.getContext('2d'),
composedMaskCanvas = D.h('canvas', {width: w, height: h}),
composedMaskCtx = composedMaskCanvas.getContext('2d'),
composedData = composedMaskCtx.getImageData(0,0,w,h),
composedDataData = composedData.data;
const canvasCtx = window.canvasCtx = canvasElement.getContext('2d');
return function(results){
var max = Math.max;
var image = results.segmentationMask;
tmpCtx.clearRect(0,0,w,h);
tmpCtx.drawImage(image,0,0,image.width,image.height,0,0,w,h);
segmentations[(sPointer++)%4] = tmpCtx.getImageData(0,0,w,h).data;
if(sPointer>3){
for(var i = 3, _i = h*w*4; i < _i; i+=4){
//if( ){
composedDataData[ i ] =
composedDataData[ i - 1 ] = segmentations[ 3 ][i] + segmentations[ 2 ][i] + segmentations[ 1 ][i] + segmentations[ 0 ][i]>120?0:255;
//}
}
composedMaskCtx.putImageData(composedData,0,0);
}
canvasCtx.drawImage(
results.image, 0, 0, canvasElement.width, canvasElement.height );
canvasCtx.drawImage( composedMaskCanvas/*results.segmentationMask*/, 0, 0,
canvasElement.width, canvasElement.height );
};
}
window.onResult1 = resultProcessor(
document.getElementsByClassName('output_canvas')[0]
);
window.onResult2 = resultProcessor(
document.getElementsByClassName('output_canvas')[1]
);
//gotDevices([{"deviceId":"default","kind":"audioinput","label":"Default - Microphone (2- Razer Kiyo) (1532:0e03)","groupId":"c9b2965558c8600ceaa11c06017152dc99f8721fef0585ad9432838b46f8f9f7"},{"deviceId":"communications","kind":"audioinput","label":"Communications - Microphone (2- Razer Kiyo) (1532:0e03)","groupId":"c9b2965558c8600ceaa11c06017152dc99f8721fef0585ad9432838b46f8f9f7"},{"deviceId":"1517d03bc4bc8e08292b02b454b79e3a93f39fa14d7c589c47c80d093093ed1e","kind":"audioinput","label":"Microphone (Steam Streaming Microphone)","groupId":"20a28b389c696bd36556474101f44876ee56f686b3717913354b85fa804c8c7a"},{"deviceId":"b963d76466dcc0490a58d9624e987a3e69d689c2529adf66f39efae8fccd031c","kind":"audioinput","label":"Microphone (Razer Kiyo) (1532:0e03)","groupId":"ea58a01565e810e30b4d7873050388edb9dc43a11007253ecc9dabd4201230fd"},{"deviceId":"3a664d8417e7000b78f8619667da3e38280269edb222a74d1375786e9c8e70d3","kind":"audioinput","label":"Mic in at rear panel (Pink) (Realtek(R) Audio)","groupId":"8e1aab63dd80f414dce561f4e368bb484c065834f3941db045ca722f61d254a4"},{"deviceId":"46ac5b427bdd38a095664fe7e817a5e7fb7cd2a7077558e72112ade79f27f3a5","kind":"audioinput","label":"Microphone (2- Razer Kiyo) (1532:0e03)","groupId":"c9b2965558c8600ceaa11c06017152dc99f8721fef0585ad9432838b46f8f9f7"},{"deviceId":"78f07683774a206866fdb098d8cac2cb5afc980ba3e670f85393eb16d5e914b9","kind":"audioinput","label":"Headset Microphone (Oculus Virtual Audio Device)","groupId":"05a90cf47adb203e6eb67353f82529c636dc92833ed13f011042a32a370c44c7"},{"deviceId":"68cb94c20ca0b8f17bbaad703c76cbce402793b5e18ddc89e68f38865ed82478","kind":"videoinput","label":"Intel(R) RealSense(TM) 435 with RGB Module Depth (8086:0b07)","groupId":"eb53f0590ee544f7848664d5e2ac6c8430659c4a34e26edf401b57fd9a8ce83c"},{"deviceId":"943c211869cd4e58039d142e22b98ca0cc53dc4d7f60723c832cf73b52b49d6f","kind":"videoinput","label":"Intel(R) RealSense(TM) 435 with RGB Module RGB (8086:0b07)","groupId":"16dd5ec91babf1e3d461bb5afe04bd4713b0c95d3c538ea6f3515dc5c3aacb9a"},{"deviceId":"0329d90dd74edc8657af0bb0d32652989fb1c162d0c294794cbc7fd76e4cf9a9","kind":"videoinput","label":"USB Video Device (1532:0e03)","groupId":"a5fe4973e22ce5b529b8cccd14ce14ed356709d356c94228cb5c2e77d804f297"},{"deviceId":"426bd00749eecdb8ce1da28ecae7d99e78310cc57aedbdf947e9288f4660ad12","kind":"videoinput","label":"USB Video Device (1532:0e03)","groupId":"1b4fc078561da2a5b19c21531d27485fa6f19368d8440d2740d94809c3b5da84"},{"deviceId":"default","kind":"audiooutput","label":"Default - Speakers (Realtek(R) Audio)","groupId":"8e1aab63dd80f414dce561f4e368bb484c065834f3941db045ca722f61d254a4"},{"deviceId":"communications","kind":"audiooutput","label":"Communications - Headphones (Oculus Virtual Audio Device)","groupId":"05a90cf47adb203e6eb67353f82529c636dc92833ed13f011042a32a370c44c7"},{"deviceId":"7c5103d23dc4e21fb0c436dbf039909bc2c70611a92587da582edd74bbee8460","kind":"audiooutput","label":"PHL BDM3490 (NVIDIA High Definition Audio)","groupId":"731a927b663a4a209a3359d16c1c1f214ded54c07f084f659ff4809e6cf588d5"},{"deviceId":"218fa70f234dbf497b6044345c531d15120f56a49e872e3062a0d9da11f8d158","kind":"audiooutput","label":"Speakers (Steam Streaming Microphone)","groupId":"20a28b389c696bd36556474101f44876ee56f686b3717913354b85fa804c8c7a"},{"deviceId":"11c4193f457b6e9cfa44f88fa6742d8a151ce7dfd8bd71b8fd97d0f5b664a6ec","kind":"audiooutput","label":"DELL U2715H (NVIDIA High Definition Audio)","groupId":"4cd1fd9ed5fe4bb80fe7984a3c60e472548f37e157239e4d901ffe8394af5205"},{"deviceId":"f9893c7a1ce8fd1f229a37d8963f9db9504c03cff47e173bc4f1ab4ee20696db","kind":"audiooutput","label":"Headphones (Oculus Virtual Audio Device)","groupId":"05a90cf47adb203e6eb67353f82529c636dc92833ed13f011042a32a370c44c7"},{"deviceId":"c611d06286b441cb1e3440e9bf09f534d98b4ed2e41528eb9c54cb7e41779c63","kind":"audiooutput","label":"Speakers (Steam Streaming Speakers)","groupId":"4d0e12aa90d61a5867f01beea961e77cb03796fd77a2c8cde7f25ec82b718ee9"},{"deviceId":"e00a5fe0a89b8c5bd2858060265e9b0937249601678974e5f3180f797e99ef9e","kind":"audiooutput","label":"Speakers (Realtek(R) Audio)","groupId":"8e1aab63dd80f414dce561f4e368bb484c065834f3941db045ca722f61d254a4"},{"deviceId":"e29c7603a6e3b56aaf3ffc5535f563dd2bce09ce208722837aecee06eaf358d9","kind":"audiooutput","label":"Realtek Digital Output (Realtek(R) Audio)","groupId":"7ae806bf56274db2fab2c6c03a14eed45022de19176702d33821bb7c8e436e8d"}])
navigator.mediaDevices.enumerateDevices().then(gotDevices).catch(handleError);
/*
canvasCtx.save();
canvasCtx.clearRect(0, 0, canvasElement.width, canvasElement.height);
canvasCtx.drawImage(results.segmentationMask, 0, 0,
canvasElement.width, canvasElement.height);
// Only overwrite existing pixels.
canvasCtx.globalCompositeOperation = 'source-in';
canvasCtx.fillStyle = '#ffffff';
canvasCtx.fillRect(0, 0, canvasElement.width, canvasElement.height);
// Only overwrite missing pixels.
canvasCtx.globalCompositeOperation = 'destination-atop';
canvasCtx.drawImage(
results.image, 0, 0, canvasElement.width, canvasElement.height);
canvasCtx.restore();
}
*/
...@@ -88,7 +88,24 @@ ...@@ -88,7 +88,24 @@
position: absolute; position: absolute;
z-index: 1; z-index: 1;
} }
</style>
.dropdown-field__tooltip {
display: none;
}
.dropdown-field--opened .dropdown-field__tooltip {
display: block;
position: absolute;
background: #fff;
border: 2px solid #6aff00;
}
.dropdown-item {
padding: 4px 12px;
}
.dropdown-item:hover {
background: #6aff00;
cursor: pointer;
}
</style>
</head> </head>
<body> <body>
...@@ -113,227 +130,10 @@ ...@@ -113,227 +130,10 @@
<script> <script src="app.js"></script>
let content, remoteVideoEl;
const store = window.store = new Store({
conference_id: 'SelfieBarracuda_con',
connection: false
});
const Input = function(cfg, bind) {
cfg.onkeyup = cfg.oninput = cfg.onchange = function() {
store.set(bind, input.value);
};
var input = D.h('input', cfg);
store.sub(bind, function(val) {
input.value = val;
});
return input;
};
const LabeledInput = function(cfg, bind) {
return D.h('label', {},
D.div.apply(D, [{cls: 'label_label'}].concat(cfg.label)),
Input(cfg, bind)
)
}
const isConnected = new Store.Value.Boolean(false);
store.sub('connection', function(val) {
isConnected.set(val)
});
D.div({cls: 'top-bar', renderTo: document.body},
D.h('img', {src: 'amazon-logo.svg'}),
D.div({cls: 'buttons'},
D.h('button', {cls: ['button secondary', {hidden: Store.NOT(isConnected)}], onclick: ()=>store.set('connection', false)}, 'End session'),
D.h('button', {cls: ['button primary', {hidden: isConnected}], onclick: ()=>store.set('connection', true)}, 'Ready to connect')
),
content = D.div({cls: 'content'},
D.div({cls: 'block'},
D.div({cls: 'header'}, 'My camera feed'),
D.h('canvas', {
cls: "output_canvas",
width: "1280px",
height: "720px",
style: {
/*display: 'none',*/
width: '320px'
}
})
),
D.div({cls: 'block'},
D.div({cls: 'header'}, 'Conference info'),
LabeledInput({label: 'Session ID', cls: 'callapp_address input', autocomplete: 'off', value: 'SelfieBarracuda_con'}, 'conference_id'),
),
D.div({cls: ['block', {hidden: Store.NOT(isConnected)}]},
D.div({cls: ['header']}, 'Remote video'),
remoteVideoEl = window.remoteVideoEl = D.div({cls: 'remote-video'})
)
)
);
function gotDevices(deviceInfos) {
// Handles being called several times to update labels. Preserve values.
var devices = {audioinput: [], audiooutput: [], videoinput: []};
for (let i = 0; i !== deviceInfos.length; ++i) {
const deviceInfo = deviceInfos[i];
const option = {value: deviceInfo.deviceId};
if(!(deviceInfo.kind in devices)){
devices[ deviceInfo.kind ] = [];
}
devices[deviceInfo.kind].push(option);
var count = devices[deviceInfo.kind].length;
if (deviceInfo.kind === 'audioinput') {
option.text = deviceInfo.label || `microphone ${count}`;
} else if (deviceInfo.kind === 'audiooutput') {
option.text = deviceInfo.label || `speaker ${count}`;
} else if (deviceInfo.kind === 'videoinput') {
option.text = deviceInfo.label || `camera ${count}`;
} else {
console.log('Some other kind of source/device: ', deviceInfo);
}
}
console.log(devices);
/*const values = selectors.map(select => select.value);
selectors.forEach(select => {
while (select.firstChild) {
select.removeChild(select.firstChild);
}
});
for (let i = 0; i !== deviceInfos.length; ++i) {
const deviceInfo = deviceInfos[i];
const option = document.createElement('option');
option.value = deviceInfo.deviceId;
if (deviceInfo.kind === 'audioinput') {
option.text = deviceInfo.label || `microphone ${audioInputSelect.length + 1}`;
audioInputSelect.appendChild(option);
} else if (deviceInfo.kind === 'audiooutput') {
option.text = deviceInfo.label || `speaker ${audioOutputSelect.length + 1}`;
audioOutputSelect.appendChild(option);
} else if (deviceInfo.kind === 'videoinput') {
option.text = deviceInfo.label || `camera ${videoSelect.length + 1}`;
videoSelect.appendChild(option);
} else {
console.log('Some other kind of source/device: ', deviceInfo);
continue;
}
}
selectors.forEach((select, selectorIndex) => {
if (Array.prototype.slice.call(select.childNodes).some(n => n.value === values[selectorIndex])) {
select.value = values[selectorIndex];
}
});*/
}
var handleError = function(e) {
console.log('Error', e)
}
navigator.mediaDevices.enumerateDevices().then(gotDevices).catch(handleError);
const videoElement = document.getElementsByClassName('input_video')[0];
const canvasElement = window.canvasElement =document.getElementsByClassName('output_canvas')[0];
const segmentations = [false,false,false,false];
let sPointer = 0;
var w = 720, h = 405;
var tmpCanvas = D.h('canvas', {width: w, height: h}),
tmpCtx = tmpCanvas.getContext('2d'),
composedMaskCanvas = D.h('canvas', {width: w, height: h}),
composedMaskCtx = composedMaskCanvas.getContext('2d'),
composedData = composedMaskCtx.getImageData(0,0,w,h),
composedDataData = composedData.data;
const canvasCtx = window.canvasCtx = canvasElement.getContext('2d');
window.onResults = function(results){
var max = Math.max;
tmpCtx.clearRect(0,0,w,h);
tmpCtx.drawImage(results.segmentationMask,0,0,w,h,0,0,w,h);
segmentations[(sPointer++)%4] = tmpCtx.getImageData(0,0,w,h).data;
if(sPointer>3){
for(var i = 3, _i = h*w*4; i < _i; i+=4){
//if( ){
composedDataData[ i ] =
composedDataData[ i - 1 ] = segmentations[ 3 ][i] + segmentations[ 2 ][i] + segmentations[ 1 ][i] + segmentations[ 0 ][i]>120?0:255;
//}
}
composedMaskCtx.putImageData(composedData,0,0);
}
canvasCtx.drawImage(
results.image, 0, 0, canvasElement.width, canvasElement.height );
canvasCtx.drawImage( composedMaskCanvas/*results.segmentationMask*/, 0, 0,
canvasElement.width, canvasElement.height );
// Only overwrite missing pixels.
//canvasCtx.globalCompositeOperation = 'source-in';
/*canvasCtx.fillStyle = '#fff';
canvasCtx.fillRect( 0, 0, canvasElement.width, canvasElement.height );*/
};/*
canvasCtx.save();
canvasCtx.clearRect(0, 0, canvasElement.width, canvasElement.height);
canvasCtx.drawImage(results.segmentationMask, 0, 0,
canvasElement.width, canvasElement.height);
// Only overwrite existing pixels.
canvasCtx.globalCompositeOperation = 'source-in';
canvasCtx.fillStyle = '#ffffff';
canvasCtx.fillRect(0, 0, canvasElement.width, canvasElement.height);
// Only overwrite missing pixels.
canvasCtx.globalCompositeOperation = 'destination-atop';
canvasCtx.drawImage(
results.image, 0, 0, canvasElement.width, canvasElement.height);
canvasCtx.restore();
}
*/
const canvas = document.querySelector(".output_canvas");
</script>
<script src="./bundle/apps.js"></script> <script src="./bundle/apps.js"></script>
<script> <script>
let instance =new apps.videoinputapp(document.querySelector("#videoinputapp1"), canvas); store.set('appLoaded', true);
instance.mUiRemoteVideoParent = remoteVideoEl;
var doSegmentation = false;
if(doSegmentation){
const selfieSegmentation = new SelfieSegmentation( {
locateFile: ( file ) => {
return `https://cdn.jsdelivr.net/npm/@mediapipe/selfie_segmentation/${file}`;
}
} );
selfieSegmentation.setOptions( {
modelSelection: 1,
} );
selfieSegmentation.onResults( function(){
window.onResults.apply( this, arguments )
} );
const camera = new Camera(videoElement, {
onFrame: async () => {
await selfieSegmentation.send({image: videoElement});
},
width: w,//1280,
height: h//,720
});
camera.start();
}
D.ext(D('.callapp_button')[0], {onclick: function() { D.ext(D('.callapp_button')[0], {onclick: function() {
}}); }});
......
...@@ -6,7 +6,7 @@ import * as awrtc from "../awrtc/index" ...@@ -6,7 +6,7 @@ import * as awrtc from "../awrtc/index"
const store = window['store']; const store = window['store'];
export class VideoInputApp { export class VideoInputApp {
public static sVideoDevice = null; public sVideoDevice = null;
private mAddress; private mAddress;
private mNetConfig = new awrtc.NetworkConfig(); private mNetConfig = new awrtc.NetworkConfig();
private mCall: awrtc.BrowserWebRtcCall = null; private mCall: awrtc.BrowserWebRtcCall = null;
...@@ -72,8 +72,8 @@ export class VideoInputApp { ...@@ -72,8 +72,8 @@ export class VideoInputApp {
config.IdealWidth = 640; config.IdealWidth = 640;
config.IdealHeight = 480; config.IdealHeight = 480;
config.IdealFps = 30; config.IdealFps = 30;
if (VideoInputApp.sVideoDevice !== null) { if (this.sVideoDevice !== null) {
config.VideoDeviceName = VideoInputApp.sVideoDevice; config.VideoDeviceName = this.sVideoDevice;
} }
//For usage in HTML set FrameUpdates to false and wait for MediaUpdate to //For usage in HTML set FrameUpdates to false and wait for MediaUpdate to
...@@ -361,7 +361,8 @@ export class VideoInputApp { ...@@ -361,7 +361,8 @@ export class VideoInputApp {
} }
export function videoinputapp(parent: HTMLElement, canvas: HTMLCanvasElement) { export default VideoInputApp;
/*function videoinputapp(parent: HTMLElement, canvas: HTMLCanvasElement) {
let callApp: VideoInputApp; let callApp: VideoInputApp;
console.log("init callapp"); console.log("init callapp");
if (parent == null) { if (parent == null) {
...@@ -381,4 +382,4 @@ export function videoinputapp(parent: HTMLElement, canvas: HTMLCanvasElement) { ...@@ -381,4 +382,4 @@ export function videoinputapp(parent: HTMLElement, canvas: HTMLCanvasElement) {
callApp.setupUi(parent); callApp.setupUi(parent);
} }*/
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment