-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from zaru/feat
Support windows, multiple video
- Loading branch information
Showing
23 changed files
with
10,015 additions
and
11,309 deletions.
There are no files selected for viewing
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
dist-bodypix-app/ | ||
node_modules/ | ||
.cache/ | ||
|
||
releases/**/*.app | ||
releases/**/*.dmg | ||
releases/mewcam-darwin-x64/ | ||
releases/build/ |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
const {app} = require('electron'); | ||
const log = require('electron-log'); | ||
const {autoUpdater} = require('electron-updater'); | ||
|
||
autoUpdater.logger = log; | ||
autoUpdater.logger.transports.file.level = 'info'; | ||
log.info('App starting...'); | ||
|
||
function sendStatusToWindow(text) { | ||
log.info(text); | ||
} | ||
autoUpdater.on('checking-for-update', () => { | ||
sendStatusToWindow('Checking for update...'); | ||
}); | ||
autoUpdater.on('update-available', (info) => { | ||
sendStatusToWindow('Update available.'); | ||
}); | ||
autoUpdater.on('update-not-available', (info) => { | ||
sendStatusToWindow('Update not available.'); | ||
}); | ||
autoUpdater.on('error', (err) => { | ||
sendStatusToWindow('Error in auto-updater. ' + err); | ||
}); | ||
autoUpdater.on('download-progress', (progressObj) => { | ||
let message = 'Download speed: ' + progressObj.bytesPerSecond; | ||
message = message + ' - Downloaded ' + progressObj.percent + '%'; | ||
message = message + ' (' + progressObj.transferred + '/' + progressObj.total + ')'; | ||
sendStatusToWindow(message); | ||
}); | ||
autoUpdater.on('update-downloaded', (info) => { | ||
sendStatusToWindow('Update downloaded'); | ||
}); | ||
app.on('ready', async () => { | ||
console.log('load auto-update'); | ||
autoUpdater.checkForUpdatesAndNotify(); | ||
}); |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,52 +1,79 @@ | ||
const bodyPix = require('@tensorflow-models/body-pix'); | ||
const VideoManager = require('./video-manager'); | ||
const Settings = require('./settings'); | ||
const settings = new Settings; | ||
|
||
const state = { | ||
deviceId: null, | ||
video: null, | ||
videoWidth: 0, | ||
videoHeight: 0, | ||
changingVideo: false, | ||
ratio() { | ||
return this.videoHeight / this.videoWidth; | ||
}, | ||
tray: null, | ||
}; | ||
|
||
/** | ||
* Main | ||
* @param {string} deviceId | ||
* @return {Promise<void>} | ||
*/ | ||
async function workload() { | ||
async function workload(deviceId) { | ||
_setupResizeGuide(); | ||
await _loadVideo(); | ||
await _loadVideo(deviceId); | ||
|
||
_resizeElement(window.innerWidth, window.innerHeight); | ||
|
||
const net = await bodyPix.load({ | ||
architecture: 'MobileNetV1', | ||
outputStride: 16, | ||
multiplier: 0.5, | ||
quantBytes: 2, | ||
}); | ||
const net = await bodyPix.load(settings.getBodyPixModel()); | ||
|
||
const video = document.getElementById('video'); | ||
const canvas = document.getElementById('canvas'); | ||
const originalCanvas = document.getElementById('original-canvas'); | ||
|
||
async function segmentationFrame() { | ||
const segmentation = await net.segmentPerson(state.video); | ||
|
||
const originalCtx = originalCanvas.getContext('2d'); | ||
const scale = originalCanvas.width / video.videoWidth; | ||
originalCtx.setTransform(scale, 0, 0, scale, 0, 0); | ||
originalCtx.drawImage(state.video, 0, 0); | ||
const imageData = originalCtx.getImageData( | ||
0, 0, originalCanvas.width, originalCanvas.height, | ||
); | ||
_drawToCanvas(canvas, segmentation, imageData); | ||
if (!state.changingVideo) { | ||
const segmentation = await net.segmentPerson(state.video); | ||
|
||
const originalCtx = originalCanvas.getContext('2d'); | ||
const scale = originalCanvas.width / video.videoWidth; | ||
originalCtx.setTransform(scale, 0, 0, scale, 0, 0); | ||
originalCtx.drawImage(state.video, 0, 0); | ||
const imageData = originalCtx.getImageData( | ||
0, 0, originalCanvas.width, originalCanvas.height, | ||
); | ||
_drawToCanvas(canvas, segmentation, imageData); | ||
} | ||
|
||
requestAnimationFrame(segmentationFrame); | ||
} | ||
segmentationFrame(); | ||
} | ||
|
||
/** | ||
* Switch video | ||
* @param {string} deviceId | ||
*/ | ||
function switchVideo(deviceId) { | ||
state.changingVideo = true; | ||
stopExistingVideoCapture(); | ||
_loadVideo(deviceId).then(() => { | ||
state.changingVideo = false; | ||
}); | ||
|
||
settings.setDeviceId(deviceId); | ||
} | ||
|
||
function stopExistingVideoCapture() { | ||
if (state.video && state.video.srcObject) { | ||
state.video.srcObject.getTracks().forEach((track) => { | ||
track.stop(); | ||
}); | ||
state.video.srcObject = null; | ||
} | ||
} | ||
|
||
/** | ||
* Set up video stream | ||
* @return {Promise<void>} | ||
|
@@ -71,6 +98,7 @@ async function _setupStream() { | |
function _getStream() { | ||
const config = { | ||
video: { | ||
deviceId: state.deviceId, | ||
audio: false, | ||
facingMode: 'user', | ||
}, | ||
|
@@ -80,10 +108,12 @@ function _getStream() { | |
|
||
/** | ||
* Load video stream | ||
* @param {string} deviceId | ||
* @return {Promise<void>} | ||
* @private | ||
*/ | ||
async function _loadVideo() { | ||
async function _loadVideo(deviceId) { | ||
state.deviceId = deviceId; | ||
state.video = await _setupStream(); | ||
state.videoWidth = state.video.videoWidth; | ||
state.videoHeight = state.video.videoHeight; | ||
|
@@ -174,4 +204,40 @@ window.addEventListener('resize', () => { | |
}, 500); | ||
}); | ||
|
||
workload(); | ||
/** | ||
* Build tray menu | ||
* @param {MediaDeviceInfo[]} videoList | ||
*/ | ||
function buildTrayMenu(videoList) { | ||
const remote = window.remote; | ||
const {Tray, Menu} = remote; | ||
const icon = window.os.platform() === 'darwin' ? 'TrayIconTemplate.png' : '[email protected]'; | ||
state.tray = new Tray(window.__dirname + `/assets/${icon}`); | ||
|
||
const videoMenu = []; | ||
videoList.forEach((device) => { | ||
videoMenu.push({ | ||
label: device.label, | ||
click() { | ||
switchVideo(device.deviceId); | ||
}, | ||
}); | ||
}); | ||
|
||
const menu = Menu.buildFromTemplate([ | ||
{ | ||
label: 'Select Video', | ||
submenu: videoMenu, | ||
}, | ||
]); | ||
|
||
state.tray.setContextMenu(menu); | ||
} | ||
|
||
const videoManager = new VideoManager; | ||
videoManager.getVideoList().then((list) => { | ||
buildTrayMenu(list); | ||
|
||
const deviceId = settings.getDeviceId() || list[0].deviceId; | ||
workload(deviceId); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
window.remote = require('electron').remote; | ||
window.__dirname = __dirname; | ||
window.os = require('os'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/** | ||
* Settings class | ||
*/ | ||
module.exports = class Settings { | ||
/** | ||
* constructor | ||
*/ | ||
constructor() { | ||
} | ||
|
||
/** | ||
* Set deviceId | ||
* @param {string} deviceId | ||
*/ | ||
setDeviceId(deviceId) { | ||
localStorage.setItem('deviceId', deviceId); | ||
} | ||
|
||
/** | ||
* Get deviceId | ||
* @return {string} | ||
*/ | ||
getDeviceId() { | ||
return localStorage.getItem('deviceId'); | ||
} | ||
|
||
/** | ||
* Set deviceId | ||
* @param {string} key | ||
*/ | ||
setBodyPixModel(key) { | ||
localStorage.setItem('bodyPixModel', key); | ||
} | ||
|
||
/** | ||
* Get deviceId | ||
* @return {string} | ||
*/ | ||
getBodyPixModel() { | ||
const key = localStorage.getItem('bodyPixModel') || 'low'; | ||
return this._bodyPixModelList()[key]; | ||
} | ||
|
||
/** | ||
* BodyPix model list | ||
* @return {{high: object, low: object}} | ||
* @private | ||
*/ | ||
_bodyPixModelList() { | ||
return { | ||
low: { | ||
architecture: 'MobileNetV1', | ||
outputStride: 16, | ||
multiplier: 0.5, | ||
quantBytes: 2, | ||
}, | ||
high: { | ||
architecture: 'ResNet50', | ||
outputStride: 16, | ||
multiplier: 1.0, | ||
quantBytes: 4, | ||
}, | ||
}; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/** | ||
* VideoManager class | ||
*/ | ||
module.exports = class VideoManager { | ||
/** | ||
* constructor | ||
*/ | ||
constructor() { | ||
} | ||
|
||
/** | ||
* Get video list | ||
* @return {Promise<MediaDeviceInfo[]>} | ||
*/ | ||
getVideoList() { | ||
return navigator.mediaDevices.enumerateDevices().then((info) => { | ||
return info.filter((device) => { | ||
return device.kind === 'videoinput'; | ||
}); | ||
}); | ||
} | ||
}; |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.