save and load audioLayer and audioPlayer
dependencies hashes: openFrameworks d78075f4bca6be2a2533c6e51a75cc1f18404501 ofxMsdfgen e14da13d02c4dff04fb69d7923469f606924e6c3 ofxGPUFont d482bb7cbdf6b296fa4ab5abcf73fb5ff8c8b239 ofxVariableLab 0b5f9bdebc1e5550621957e73c040c258ec6317b ofxProfiler a868e34fa1a79189dd4fbdede2938e308535e5e8 theatre c60e63f5be4466e21b6bf06f6580f6100687306b
This commit is contained in:
parent
ef308f61b2
commit
8075cf2b16
7 changed files with 172 additions and 32 deletions
|
@ -1162,7 +1162,7 @@ const Audio = function(tp, record) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.log("getUserMedia not supported on your browser!");
|
console.log("Audio::init","getUserMedia not supported on your browser!");
|
||||||
}
|
}
|
||||||
|
|
||||||
const visualize = () => {
|
const visualize = () => {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import {
|
import {
|
||||||
sanitizeTheatreKey
|
sanitizeTheatreKey,
|
||||||
|
arraysEqual,
|
||||||
} from './utils.js';
|
} from './utils.js';
|
||||||
|
|
||||||
const AudioLayer = function(tp, audioLayerID, values = false, autoInit = true) {
|
const AudioLayer = function(tp, audioLayerID, values = false, autoInit = true) {
|
||||||
|
@ -14,14 +15,34 @@ const AudioLayer = function(tp, audioLayerID, values = false, autoInit = true) {
|
||||||
props[Object.keys(values)[0]] = tp.core.types.boolean(false);
|
props[Object.keys(values)[0]] = tp.core.types.boolean(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onValuesChangeCallbacks = [];
|
||||||
|
|
||||||
// private functions
|
// private functions
|
||||||
//
|
//
|
||||||
const onValuesChange = (values) => {
|
const onValuesChange = (values) => {
|
||||||
console.log(values);
|
console.log(values);
|
||||||
|
const n_callbacks = onValuesChangeCallbacks.length;
|
||||||
|
const successes = [];
|
||||||
|
if (n_callbacks > 0) {
|
||||||
|
for (let i = 0; i < n_callbacks; i++) {
|
||||||
|
if (typeof onValuesChangeCallbacks[i] === 'function') {
|
||||||
|
if(onValuesChangeCallbacks[i](values)) {
|
||||||
|
successes.unshift(i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log('AudioLayer::onValuesChange', 'holy shit, the callback is not a function');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
successes.forEach((i) => {
|
||||||
|
onValuesChangeCallbacks.splice(i, 1);
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const findInjectPanel = () => {
|
const findInjectPanel = () => {
|
||||||
console.log('find and inject');
|
console.log('AudioLayer::findInjectPanel');
|
||||||
|
const sequencePanel = tp.getSequencePanel();
|
||||||
|
const sequencePanelLeft = tp.getSequencePanelLeft();
|
||||||
};
|
};
|
||||||
|
|
||||||
const setTime = (filename, start, stop) => {
|
const setTime = (filename, start, stop) => {
|
||||||
|
@ -104,13 +125,33 @@ const AudioLayer = function(tp, audioLayerID, values = false, autoInit = true) {
|
||||||
values[filename] = false;
|
values[filename] = false;
|
||||||
props[filename] = tp.core.types.boolean(values[filename]);
|
props[filename] = tp.core.types.boolean(values[filename]);
|
||||||
this.props = props;
|
this.props = props;
|
||||||
|
|
||||||
|
const setDummy = () => {
|
||||||
tp.changeObject(audioLayerID, {
|
tp.changeObject(audioLayerID, {
|
||||||
dummy: true
|
dummy: true
|
||||||
});
|
});
|
||||||
setTimeout(() => {
|
};
|
||||||
tp.changeObject(audioLayerID, this.props);
|
|
||||||
|
onValuesChangeCallbacks.push((changedValues) => {
|
||||||
|
if (changedValues.dummy) {
|
||||||
|
// NOTE: any idea how to avoid this ugly nesting?
|
||||||
|
onValuesChangeCallbacks.push((againChangedValues) => {
|
||||||
|
const expectedValueKeys = Object.keys(values);
|
||||||
|
const givenValueKeys = Object.keys(againChangedValues);
|
||||||
|
if (arraysEqual(expectedValueKeys, givenValueKeys)) {
|
||||||
resolve();
|
resolve();
|
||||||
}, 100);
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tp.changeObject(audioLayerID, this.props);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setDummy();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
this.removeFile = (filename) => {
|
this.removeFile = (filename) => {
|
||||||
|
@ -120,13 +161,26 @@ const AudioLayer = function(tp, audioLayerID, values = false, autoInit = true) {
|
||||||
delete values[filename];
|
delete values[filename];
|
||||||
delete props[filename];
|
delete props[filename];
|
||||||
this.props = props;
|
this.props = props;
|
||||||
|
const setDummy = () => {
|
||||||
tp.changeObject(audioLayerID, {
|
tp.changeObject(audioLayerID, {
|
||||||
dummy: true
|
dummy: true
|
||||||
});
|
});
|
||||||
setTimeout(() => {
|
};
|
||||||
tp.changeObject(audioLayerID, this.props);
|
|
||||||
|
onValuesChangeCallbacks.push((changedValues) => {
|
||||||
|
if (changedValues.dummy) {
|
||||||
|
// NOTE: any idea how to avoid this ugly nesting?
|
||||||
|
onValuesChangeCallbacks.push((againChangedValues) => {
|
||||||
|
const expectedValueKeys = Object.keys(values);
|
||||||
|
const givenValueKeys = Object.keys(againChangedValues);
|
||||||
|
if (arraysEqual(expectedValueKeys, givenValueKeys)) {
|
||||||
resolve();
|
resolve();
|
||||||
}, 100);
|
}
|
||||||
|
});
|
||||||
|
tp.changeObject(audioLayerID, this.props);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setDummy();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
this.setTime = setTime;
|
this.setTime = setTime;
|
||||||
|
|
|
@ -30,7 +30,7 @@ const AudioPlayer = function() {
|
||||||
|
|
||||||
this.addMany = (manyAudioElements) => {
|
this.addMany = (manyAudioElements) => {
|
||||||
manyAudioElements.forEach((e) => {
|
manyAudioElements.forEach((e) => {
|
||||||
this.add(e.audioID, e.layerID, e.propTitle, e.file);
|
this.add(e.audioID, e.layerID, e.propTitle, e.file, e.startTime);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -604,7 +604,7 @@ const addAudioLayer = (filename = false) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const addExistingAudioLayer = (audioLayerID, values) => {
|
const addExistingAudioLayer = (audioLayerID, values = false) => {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
const audioLayer = new AudioLayer(tp, audioLayerID, values, false);
|
const audioLayer = new AudioLayer(tp, audioLayerID, values, false);
|
||||||
audioLayers.push(audioLayer);
|
audioLayers.push(audioLayer);
|
||||||
|
|
|
@ -248,6 +248,14 @@ const Record = function(tp) {
|
||||||
if (cPropTitle.indexOf('color.') === 0) {
|
if (cPropTitle.indexOf('color.') === 0) {
|
||||||
cPropTitle = 'color';
|
cPropTitle = 'color';
|
||||||
}
|
}
|
||||||
|
const propTitleDom = tp.getPanelPropTitle(cPropTitle);
|
||||||
|
if (propTitleDom === null) {
|
||||||
|
// whoops, probably currently transitioning,
|
||||||
|
// so it will not be necessary to remove the class
|
||||||
|
// when it will be recreated on demand,
|
||||||
|
// it won't have the class anyways.
|
||||||
|
return;
|
||||||
|
}
|
||||||
const button = tp
|
const button = tp
|
||||||
.getPanelPropTitle(cPropTitle)
|
.getPanelPropTitle(cPropTitle)
|
||||||
.parentNode.parentNode
|
.parentNode.parentNode
|
||||||
|
|
|
@ -23,6 +23,10 @@ const TheatrePlay = function(autoInit = false) {
|
||||||
const theatreObjects = {};
|
const theatreObjects = {};
|
||||||
let theatrePanel = null;
|
let theatrePanel = null;
|
||||||
let sequencePanelLeft = null;
|
let sequencePanelLeft = null;
|
||||||
|
const getSequencePanel = () => {
|
||||||
|
sequencePanelLeft = tp.shadowRoot.querySelector('[data-testid="SequencePanel-Object"]');
|
||||||
|
return sequencePanelLeft;
|
||||||
|
};
|
||||||
const getSequencePanelLeft = () => {
|
const getSequencePanelLeft = () => {
|
||||||
sequencePanelLeft = tp.shadowRoot.querySelector('[data-testid="SequencePanel-Left"]');
|
sequencePanelLeft = tp.shadowRoot.querySelector('[data-testid="SequencePanel-Left"]');
|
||||||
return sequencePanelLeft;
|
return sequencePanelLeft;
|
||||||
|
@ -321,6 +325,7 @@ const TheatrePlay = function(autoInit = false) {
|
||||||
};
|
};
|
||||||
this.isSequenced = isSequenced;
|
this.isSequenced = isSequenced;
|
||||||
this.getSequenceButton = getSequenceButton;
|
this.getSequenceButton = getSequenceButton;
|
||||||
|
this.getSequencePanel = getSequencePanel;
|
||||||
this.getSequencePanelLeft = getSequencePanelLeft;
|
this.getSequencePanelLeft = getSequencePanelLeft;
|
||||||
this.getPanel = getPanel;
|
this.getPanel = getPanel;
|
||||||
this.getPanelPropTitle = getPanelPropTitle;
|
this.getPanelPropTitle = getPanelPropTitle;
|
||||||
|
@ -589,6 +594,28 @@ const TheatrePlay = function(autoInit = false) {
|
||||||
audioMapping: audio.getMapping(),
|
audioMapping: audio.getMapping(),
|
||||||
};
|
};
|
||||||
const theatre = tp.studio.createContentOfSaveFile(currentProjectId);
|
const theatre = tp.studio.createContentOfSaveFile(currentProjectId);
|
||||||
|
// yeaaaah we don't want to fuck with theatre's saveFile stuff
|
||||||
|
// let's do this ourselves
|
||||||
|
const audioLayers = getAudioLayers();
|
||||||
|
if (audioLayers.length > 0) {
|
||||||
|
vt_params['audioLayers'] = {};
|
||||||
|
audioLayers.forEach((audioLayer) => {
|
||||||
|
vt_params['audioLayers'][audioLayer.id()] = getKeyframes(audioLayer);
|
||||||
|
});
|
||||||
|
const audioPlayerElements = audio
|
||||||
|
.audioPlayer
|
||||||
|
.audioElements
|
||||||
|
.map((e) => {
|
||||||
|
return {
|
||||||
|
audioID: e.audioID,
|
||||||
|
layerID: e.layerID,
|
||||||
|
propTitle: e.propTitle,
|
||||||
|
file: e.file,
|
||||||
|
startTime: e.startTime
|
||||||
|
};
|
||||||
|
});
|
||||||
|
vt_params['audioPlayerElements'] = audioPlayerElements;
|
||||||
|
}
|
||||||
return this.theatre2variableTime(theatre, vt_params);
|
return this.theatre2variableTime(theatre, vt_params);
|
||||||
};
|
};
|
||||||
this.saveProject = (projectId = project.address.projectId, vt_project = false, silent = true) => {
|
this.saveProject = (projectId = project.address.projectId, vt_project = false, silent = true) => {
|
||||||
|
@ -723,17 +750,48 @@ const TheatrePlay = function(autoInit = false) {
|
||||||
.forEach((layerId) => {
|
.forEach((layerId) => {
|
||||||
window.setLoadingTask(`setting up the shapes of ${layerId} to come`, 90);
|
window.setLoadingTask(`setting up the shapes of ${layerId} to come`, 90);
|
||||||
window.project_fontsHashMap = project.fontsHashMap;
|
window.project_fontsHashMap = project.fontsHashMap;
|
||||||
layerPromises.push(window.addExistingLayer(layerId, objects[layerId]));
|
//layerPromises.push(window.addExistingLayer(layerId, objects[layerId]));
|
||||||
|
layerPromises.push(() => {
|
||||||
|
return new Promise((r) => {
|
||||||
|
window.addExistingLayer(layerId, objects[layerId]).then(() => {
|
||||||
|
r();
|
||||||
});
|
});
|
||||||
//console.log(clone(objects));
|
|
||||||
Object.keys(objects)
|
|
||||||
.filter((e) => e.indexOf('audio-') === 0)
|
|
||||||
.forEach((layerId) => {
|
|
||||||
window.setLoadingTask(`setting up the sounds of ${layerId} to come`, 90);
|
|
||||||
window.project_fontsHashMap = project.fontsHashMap;
|
|
||||||
layerPromises.push(window.addExistingAudioLayer(layerId, objects[layerId]));
|
|
||||||
});
|
});
|
||||||
Promise.all(layerPromises).then(() => {
|
});
|
||||||
|
});
|
||||||
|
if (typeof project['audioPlayerElements'] === 'object') {
|
||||||
|
audio.audioPlayer.addMany(project['audioPlayerElements']);
|
||||||
|
}
|
||||||
|
if (typeof project['audioLayers'] === 'object') {
|
||||||
|
const audioLayerIDs = Object.keys(project['audioLayers']);
|
||||||
|
audioLayerIDs.forEach((audioLayerID) => {
|
||||||
|
layerPromises.push(() => {
|
||||||
|
window.setLoadingTask(`setting up the sounds of ${audioLayerID} to come`, 90);
|
||||||
|
return new Promise((r) => {
|
||||||
|
window.addExistingAudioLayer(audioLayerID).then((audioLayer) => {
|
||||||
|
const promises = [];
|
||||||
|
project['audioLayers'][audioLayerID].forEach((keyframeCombo) => {
|
||||||
|
const filename = keyframeCombo.path.join('');
|
||||||
|
promises.push(() => {
|
||||||
|
return new Promise((rr) => {
|
||||||
|
audioLayer.addFile(filename)
|
||||||
|
.then(() => {
|
||||||
|
rr(); // resolve
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
sequencialPromises(promises, () => {
|
||||||
|
tp.addKeyframes(audioLayer, project['audioLayers'][audioLayerID]);
|
||||||
|
r(); // resolve
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
sequencialPromises(layerPromises, () => {
|
||||||
window.layerOrder.set(project.layerOrder);
|
window.layerOrder.set(project.layerOrder);
|
||||||
this.duration = this.core.val(this.sheet.sequence.pointer.length);
|
this.duration = this.core.val(this.sheet.sequence.pointer.length);
|
||||||
if (project.layerOrder.length > 0) {
|
if (project.layerOrder.length > 0) {
|
||||||
|
|
|
@ -531,6 +531,25 @@ const getNestedProperty = (o, a, verify = false) => {
|
||||||
return o[b[0]];
|
return o[b[0]];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const findNestedObjectKey = (o, k, exact = true, history = [], result = []) => {
|
||||||
|
const oks = Object.keys(o);
|
||||||
|
for (let i = 0; i < oks.length; i++) {
|
||||||
|
if (k === oks[i] || (!exact && oks[i].indexOf(k) >= 0)) {
|
||||||
|
history.push(oks[i]);
|
||||||
|
result.push({found: o[oks[i]], history});
|
||||||
|
}
|
||||||
|
if (typeof o[oks[i]] === 'object') {
|
||||||
|
const ok = Object.keys(o[oks[i]]);
|
||||||
|
const ok_history = clone(history);
|
||||||
|
ok_history.push(oks[i]);
|
||||||
|
findNestedObjectKey(o[oks[i]], k, exact, ok_history, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (history.length === 0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// NOTE: all input values are range 0-1
|
// NOTE: all input values are range 0-1
|
||||||
const rgbaToHexa = (rgba) => {
|
const rgbaToHexa = (rgba) => {
|
||||||
return '#' + (
|
return '#' + (
|
||||||
|
@ -610,6 +629,7 @@ export {
|
||||||
flattenObject,
|
flattenObject,
|
||||||
deFlattenObject,
|
deFlattenObject,
|
||||||
getNestedProperty,
|
getNestedProperty,
|
||||||
|
findNestedObjectKey,
|
||||||
rgbaToHexa,
|
rgbaToHexa,
|
||||||
hexaToRgba,
|
hexaToRgba,
|
||||||
getFileExtensionFromMimeType,
|
getFileExtensionFromMimeType,
|
||||||
|
|
Loading…
Reference in a new issue