Fix loop bug. When selection a video as a projector (need to work on this metaphor) the loops are automatically set. Previous issues were due to id re-use.
Also, (almost) you can choose a light color value that a frame will be overlayed on with a Darken composite mode. This is almost working but is kludgey because the first frame is always coming up black. Will need to make adjustments in the light module.
This commit is contained in:
parent
3493759998
commit
962a7c8213
|
@ -381,16 +381,16 @@ button:focus {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
#seq_loop {
|
#seq_loop_wrap {
|
||||||
width: 40%;
|
width: 40%;
|
||||||
float: left;
|
float: left;
|
||||||
padding: 0 0 0 56px;
|
padding: 0 0 0 56px;
|
||||||
}
|
}
|
||||||
#seq_loop h3 {
|
#seq_loop_wrap h3 {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
margin: 12px 0 3px;
|
margin: 12px 0 3px;
|
||||||
}
|
}
|
||||||
#seq_loop input {
|
#seq_loop_wrap input {
|
||||||
font-family: 'Menlo', monospace;
|
font-family: 'Menlo', monospace;
|
||||||
background: rgba(255, 255, 255, 0.05);
|
background: rgba(255, 255, 255, 0.05);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
<div class="cam_end">Camera end: <span>00000</span></div>
|
<div class="cam_end">Camera end: <span>00000</span></div>
|
||||||
<div class="proj_end">Projector end: <span>00000</span></div>
|
<div class="proj_end">Projector end: <span>00000</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="seq_loop">
|
<div id="seq_loop_wrap">
|
||||||
<h3>LOOPS</h3>
|
<h3>LOOPS</h3>
|
||||||
<input type="number" min="1" id="seq_loop" value="00001" onchange="this.value = gui.fmtZero(this.value, 6); gui.grid.loopChange(this);"/>
|
<input type="number" min="1" id="seq_loop" value="00001" onchange="this.value = gui.fmtZero(this.value, 6); gui.grid.loopChange(this);"/>
|
||||||
<div id="loop_current"></div>
|
<div id="loop_current"></div>
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
.timing{
|
.timing{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#seq_loop{
|
#seq_loop_wrap{
|
||||||
width: 40%;
|
width: 40%;
|
||||||
float: left;
|
float: left;
|
||||||
padding: 0 0 0 56px;
|
padding: 0 0 0 56px;
|
||||||
|
@ -64,9 +64,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#sequencer{
|
|
||||||
|
|
||||||
}
|
|
||||||
#sequence{
|
#sequence{
|
||||||
width: 970px;
|
width: 970px;
|
||||||
padding-bottom: 21px;
|
padding-bottom: 21px;
|
||||||
|
|
|
@ -20,24 +20,32 @@ function padded_frame (i) {
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function frame (state) {
|
async function frame (state, light) {
|
||||||
let frame = state.frame
|
let frame = state.frame
|
||||||
let video = state.path
|
let video = state.path
|
||||||
let w = state.info.width
|
let w = state.info.width
|
||||||
let h = state.info.height
|
let h = state.info.height
|
||||||
let padded = padded_frame(frame)
|
let padded = padded_frame(frame)
|
||||||
let ext = 'tif'
|
let ext = 'tif'
|
||||||
|
let rgb = light.on;
|
||||||
let tmpoutput
|
let tmpoutput
|
||||||
let cmd
|
let cmd
|
||||||
let output
|
let output
|
||||||
|
let cmd2
|
||||||
|
let output2
|
||||||
|
|
||||||
if (system.platform !== 'nix') {
|
if (system.platform !== 'nix') {
|
||||||
ext = 'png'
|
ext = 'png'
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpoutput = path.join(TMPDIR, `export-${padded}.${ext}`)
|
rgb = rgb.map(e => {
|
||||||
|
return parseInt(e);
|
||||||
|
});
|
||||||
|
|
||||||
cmd = `ffmpeg -i "${video}" -vf "select='gte(n\\,${frame})',scale=${w}:${h}" -vframes 1 -compression_algo raw -pix_fmt rgb24 "${tmpoutput}"`
|
tmpoutput = path.join(TMPDIR, `export-${padded}.${ext}`);
|
||||||
|
|
||||||
|
cmd = `ffmpeg -i "${video}" -vf "select='gte(n\\,${frame})',scale=${w}:${h}" -vframes 1 -compression_algo raw -pix_fmt rgb24 "${tmpoutput}"`;
|
||||||
|
cmd2 = `convert "${tmpoutput}" -resize ${w}x${h} -size ${w}x${h} xc:"rgb(${rgb[0]},${rgb[1]},${rgb[2]})" +swap -compose Darken -composite "${tmpoutput}"`;
|
||||||
|
|
||||||
//ffmpeg -i "${video}" -ss 00:00:07.000 -vframes 1 "export-${time}.jpg"
|
//ffmpeg -i "${video}" -ss 00:00:07.000 -vframes 1 "export-${time}.jpg"
|
||||||
//ffmpeg -i "${video}" -compression_algo raw -pix_fmt rgb24 "export-%05d.tiff"
|
//ffmpeg -i "${video}" -compression_algo raw -pix_fmt rgb24 "export-%05d.tiff"
|
||||||
|
@ -49,9 +57,18 @@ async function frame (state) {
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
|
if (output && output.stdout) console.log(`"${output.stdout}"`);
|
||||||
|
|
||||||
if (output) console.log(`"${output}"`);
|
if (rgb[0] !== 255 || rgb[1] !== 255 || rgb[2] !== 255) {
|
||||||
|
try {
|
||||||
|
console.log(cmd2);
|
||||||
|
output2 = await exec(cmd2);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (output2 && output2.stdout) console.log(`"${output2.stdout}"`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function frames (video, obj) {
|
async function frames (video, obj) {
|
||||||
|
|
|
@ -47,7 +47,7 @@ cmd.cam_forward = function (rgb, callback) {
|
||||||
gui.updateState();
|
gui.updateState();
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
light.display(off);
|
light.display(off);
|
||||||
light.set(off, function () {
|
light.set(off, false, function () {
|
||||||
$('#cmd_cam_forward').removeClass('active');
|
$('#cmd_cam_forward').removeClass('active');
|
||||||
if (callback) { callback(ms); }
|
if (callback) { callback(ms); }
|
||||||
});
|
});
|
||||||
|
@ -58,7 +58,7 @@ cmd.cam_forward = function (rgb, callback) {
|
||||||
cam.set(true, function () {
|
cam.set(true, function () {
|
||||||
setTimeout( function () {
|
setTimeout( function () {
|
||||||
light.display(rgb);
|
light.display(rgb);
|
||||||
light.set(rgb, function () {
|
light.set(rgb, true, function () {
|
||||||
setTimeout( function () {
|
setTimeout( function () {
|
||||||
cam.move(res);
|
cam.move(res);
|
||||||
}, mcopy.cfg.arduino.serialDelay);
|
}, mcopy.cfg.arduino.serialDelay);
|
||||||
|
@ -67,7 +67,7 @@ cmd.cam_forward = function (rgb, callback) {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
light.display(rgb);
|
light.display(rgb);
|
||||||
light.set(rgb, function () {
|
light.set(rgb, true, function () {
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
cam.move(res);
|
cam.move(res);
|
||||||
}, mcopy.cfg.arduino.serialDelay);
|
}, mcopy.cfg.arduino.serialDelay);
|
||||||
|
@ -87,7 +87,7 @@ cmd.black_forward = function (callback) {
|
||||||
cam.set(true, function () {
|
cam.set(true, function () {
|
||||||
setTimeout( function () {
|
setTimeout( function () {
|
||||||
light.display(off);
|
light.display(off);
|
||||||
light.set(off, function () {
|
light.set(off, false, function () {
|
||||||
setTimeout( function () {
|
setTimeout( function () {
|
||||||
cam.move(res);
|
cam.move(res);
|
||||||
}, mcopy.cfg.arduino.serialDelay);
|
}, mcopy.cfg.arduino.serialDelay);
|
||||||
|
@ -96,7 +96,7 @@ cmd.black_forward = function (callback) {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
light.display(off);
|
light.display(off);
|
||||||
light.set(off, function () {
|
light.set(off, false, function () {
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
cam.move(res);
|
cam.move(res);
|
||||||
}, mcopy.cfg.arduino.serialDelay);
|
}, mcopy.cfg.arduino.serialDelay);
|
||||||
|
@ -109,7 +109,7 @@ cmd.cam_backward = function (rgb, callback) {
|
||||||
var res = function (ms) {
|
var res = function (ms) {
|
||||||
gui.updateState();
|
gui.updateState();
|
||||||
light.display(off);
|
light.display(off);
|
||||||
light.set(off, function () {
|
light.set(off, false, function () {
|
||||||
$('#cmd_cam_backward').removeClass('active');
|
$('#cmd_cam_backward').removeClass('active');
|
||||||
if (callback) { callback(ms); }
|
if (callback) { callback(ms); }
|
||||||
});
|
});
|
||||||
|
@ -119,7 +119,7 @@ cmd.cam_backward = function (rgb, callback) {
|
||||||
cam.set(false, function () {
|
cam.set(false, function () {
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
light.display(rgb);
|
light.display(rgb);
|
||||||
light.set(rgb, function () {
|
light.set(rgb, true, function () {
|
||||||
cam.move(res);
|
cam.move(res);
|
||||||
});
|
});
|
||||||
}, mcopy.cfg.arduino.serialDelay);
|
}, mcopy.cfg.arduino.serialDelay);
|
||||||
|
@ -127,7 +127,7 @@ cmd.cam_backward = function (rgb, callback) {
|
||||||
} else {
|
} else {
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
light.display(rgb);
|
light.display(rgb);
|
||||||
light.set(rgb, function () {
|
light.set(rgb, true, function () {
|
||||||
cam.move(res);
|
cam.move(res);
|
||||||
});
|
});
|
||||||
}, mcopy.cfg.arduino.serialDelay);
|
}, mcopy.cfg.arduino.serialDelay);
|
||||||
|
@ -146,7 +146,7 @@ cmd.black_backward = function (callback) {
|
||||||
cam.set(false, function () {
|
cam.set(false, function () {
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
light.display(off);
|
light.display(off);
|
||||||
light.set(off, function () {
|
light.set(off, false, function () {
|
||||||
cam.move(res);
|
cam.move(res);
|
||||||
});
|
});
|
||||||
}, mcopy.cfg.arduino.serialDelay);
|
}, mcopy.cfg.arduino.serialDelay);
|
||||||
|
@ -154,7 +154,7 @@ cmd.black_backward = function (callback) {
|
||||||
} else {
|
} else {
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
light.display(off);
|
light.display(off);
|
||||||
light.set(off, function () {
|
light.set(off, false, function () {
|
||||||
cam.move(res);
|
cam.move(res);
|
||||||
});
|
});
|
||||||
}, mcopy.cfg.arduino.serialDelay);
|
}, mcopy.cfg.arduino.serialDelay);
|
||||||
|
|
|
@ -191,6 +191,7 @@ devices.digital = function () {
|
||||||
devices.digitalCb = function (evt, args) {
|
devices.digitalCb = function (evt, args) {
|
||||||
'use strict';
|
'use strict';
|
||||||
let state;
|
let state;
|
||||||
|
let color = [255,255,255];
|
||||||
gui.spinner(false);
|
gui.spinner(false);
|
||||||
gui.overlay(false);
|
gui.overlay(false);
|
||||||
if (args.valid && args.valid === true) {
|
if (args.valid && args.valid === true) {
|
||||||
|
@ -201,9 +202,12 @@ devices.digitalCb = function (evt, args) {
|
||||||
gui.notify('DEVICES', `Using video ${state.fileName}`);
|
gui.notify('DEVICES', `Using video ${state.fileName}`);
|
||||||
|
|
||||||
mcopy.state.sequence.arr = ['PF', 'CF'];
|
mcopy.state.sequence.arr = ['PF', 'CF'];
|
||||||
|
gui.grid.setLight(1, color);
|
||||||
gui.grid.state(0);
|
gui.grid.state(0);
|
||||||
gui.grid.state(1);
|
gui.grid.state(1);
|
||||||
|
|
||||||
|
$('#seq_loop').val(`${state.frames}`).trigger('change');
|
||||||
|
|
||||||
gui.updateState();
|
gui.updateState();
|
||||||
} else {
|
} else {
|
||||||
$('#projector_type_digital').prop('checked', 'checked');
|
$('#projector_type_digital').prop('checked', 'checked');
|
||||||
|
|
|
@ -111,7 +111,7 @@ light.colorPickers = function () {
|
||||||
light.kelvin.init();
|
light.kelvin.init();
|
||||||
//light.cmy.init();
|
//light.cmy.init();
|
||||||
};
|
};
|
||||||
light.set = function (rgb, callback) { //rgb = [0,0,0]
|
light.set = function (rgb, on, callback) { //rgb = [0,0,0]
|
||||||
'use strict';
|
'use strict';
|
||||||
var obj;
|
var obj;
|
||||||
|
|
||||||
|
@ -121,8 +121,9 @@ light.set = function (rgb, callback) { //rgb = [0,0,0]
|
||||||
}
|
}
|
||||||
|
|
||||||
obj = {
|
obj = {
|
||||||
rgb : rgb,
|
rgb,
|
||||||
id : uuid.v4()
|
id : uuid.v4(),
|
||||||
|
on
|
||||||
};
|
};
|
||||||
ipcRenderer.sendSync('light', obj);
|
ipcRenderer.sendSync('light', obj);
|
||||||
|
|
||||||
|
|
47
app/main.js
47
app/main.js
|
@ -21,6 +21,7 @@ const settings = require('settings')
|
||||||
const system = require('system')
|
const system = require('system')
|
||||||
const Server = require('server')
|
const Server = require('server')
|
||||||
const Intval = require('intval')
|
const Intval = require('intval')
|
||||||
|
const delay = require('delay')
|
||||||
|
|
||||||
const mcopy = {}
|
const mcopy = {}
|
||||||
const log = {}
|
const log = {}
|
||||||
|
@ -44,12 +45,6 @@ let display
|
||||||
let ffmpeg
|
let ffmpeg
|
||||||
let ffprobe
|
let ffprobe
|
||||||
|
|
||||||
async function delay (ms) {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
return setTimeout(resolve, ms)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
mcopy.cfg = require('./data/cfg.json')
|
mcopy.cfg = require('./data/cfg.json')
|
||||||
mcopy.settings = {}
|
mcopy.settings = {}
|
||||||
|
|
||||||
|
@ -367,13 +362,18 @@ var createWindow = function () {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
light.state = {
|
||||||
|
color : [0, 0, 0],
|
||||||
|
on : [0, 0, 0]
|
||||||
|
}
|
||||||
|
|
||||||
light.init = function () {
|
light.init = function () {
|
||||||
light.listen()
|
light.listen()
|
||||||
}
|
}
|
||||||
light.listen = function () {
|
light.listen = function () {
|
||||||
ipcMain.on('light', async (event, arg) => {
|
ipcMain.on('light', async (event, arg) => {
|
||||||
try {
|
try {
|
||||||
await light.set(arg.rgb, arg.id)
|
await light.set(arg.rgb, arg.id, arg.on)
|
||||||
}catch (err) {
|
}catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
return reject(err)
|
return reject(err)
|
||||||
|
@ -381,9 +381,12 @@ light.listen = function () {
|
||||||
event.returnValue = true
|
event.returnValue = true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
light.set = async function (rgb, id) {
|
light.set = async function (rgb, id, on) {
|
||||||
const str = rgb.join(',');
|
const str = rgb.join(',');
|
||||||
let ms
|
let ms
|
||||||
|
light.state.color = rgb;
|
||||||
|
if (on) light.state.on = rgb;
|
||||||
|
console.dir(light.state)
|
||||||
try {
|
try {
|
||||||
ms = arduino.send('light', mcopy.cfg.arduino.cmd.light)
|
ms = arduino.send('light', mcopy.cfg.arduino.cmd.light)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -518,7 +521,7 @@ proj.connectDigital = async function (evt, arg) {
|
||||||
dig.state.frames = frames;
|
dig.state.frames = frames;
|
||||||
dig.state.info = info;
|
dig.state.info = info;
|
||||||
|
|
||||||
console.dir(dig.state);
|
//console.dir(dig.state);
|
||||||
|
|
||||||
log.info(`Opened ${dig.state.fileName}`, 'DIGITAL', true, true);
|
log.info(`Opened ${dig.state.fileName}`, 'DIGITAL', true, true);
|
||||||
log.info(`Frames : ${frames}`, 'DIGITAL', true, true);
|
log.info(`Frames : ${frames}`, 'DIGITAL', true, true);
|
||||||
|
@ -563,7 +566,7 @@ dig.move = async function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await ffmpeg.frame(dig.state)
|
await ffmpeg.frame(dig.state, light.state)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
}
|
}
|
||||||
|
@ -659,7 +662,6 @@ cam.connectIntval = async function (event, arg) {
|
||||||
return resolve(false)
|
return resolve(false)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cam.listen = function () {
|
cam.listen = function () {
|
||||||
|
@ -784,9 +786,9 @@ transfer.listen = function () {
|
||||||
var init = async function () {
|
var init = async function () {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
SYSTEM = await system();
|
SYSTEM = await system()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
createWindow()
|
createWindow()
|
||||||
|
@ -799,25 +801,26 @@ var init = async function () {
|
||||||
dev.init()
|
dev.init()
|
||||||
seq.init()
|
seq.init()
|
||||||
|
|
||||||
|
//capture = require('capture')(SYSTEM) //redundant
|
||||||
//capture = require('capture')(SYSTEM); //redundant
|
display = require('display')(SYSTEM)
|
||||||
display = require('display')(SYSTEM);
|
ffmpeg = require('ffmpeg')(SYSTEM)
|
||||||
ffmpeg = require('ffmpeg')(SYSTEM);
|
ffprobe = require('ffprobe')(SYSTEM)
|
||||||
ffprobe = require('ffprobe')(SYSTEM);
|
|
||||||
|
|
||||||
|
|
||||||
//transfer.init()
|
//transfer.init()
|
||||||
//capture.init()
|
//capture.init()
|
||||||
|
|
||||||
arduino = require('./lib/arduino')(mcopy.cfg, ee)
|
arduino = require('./lib/arduino')(mcopy.cfg, ee)
|
||||||
mscript = require('./lib/mscript')
|
mscript = require('./lib/mscript')
|
||||||
|
|
||||||
|
|
||||||
settings.restore()
|
settings.restore()
|
||||||
mcopy.settings = settings.all()
|
mcopy.settings = settings.all()
|
||||||
|
|
||||||
await delay(2000)
|
await delay(2000)
|
||||||
await dev.enumerate()
|
try {
|
||||||
|
await dev.enumerate()
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
app.on('ready', init)
|
app.on('ready', init)
|
||||||
|
@ -837,4 +840,4 @@ app.on('activate', () => {
|
||||||
mcopy.relaunch = function () {
|
mcopy.relaunch = function () {
|
||||||
app.relaunch({args: process.argv.slice(1).concat(['--relaunch'])})
|
app.relaunch({args: process.argv.slice(1).concat(['--relaunch'])})
|
||||||
app.exit(0)
|
app.exit(0)
|
||||||
}
|
}
|
Loading…
Reference in New Issue