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 {
|
||||
console.log("getUserMedia not supported on your browser!");
|
||||
console.log("Audio::init","getUserMedia not supported on your browser!");
|
||||
}
|
||||
|
||||
const visualize = () => {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import {
|
||||
sanitizeTheatreKey
|
||||
sanitizeTheatreKey,
|
||||
arraysEqual,
|
||||
} from './utils.js';
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
const onValuesChangeCallbacks = [];
|
||||
|
||||
// private functions
|
||||
//
|
||||
const onValuesChange = (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 = () => {
|
||||
console.log('find and inject');
|
||||
console.log('AudioLayer::findInjectPanel');
|
||||
const sequencePanel = tp.getSequencePanel();
|
||||
const sequencePanelLeft = tp.getSequencePanelLeft();
|
||||
};
|
||||
|
||||
const setTime = (filename, start, stop) => {
|
||||
|
@ -104,13 +125,33 @@ const AudioLayer = function(tp, audioLayerID, values = false, autoInit = true) {
|
|||
values[filename] = false;
|
||||
props[filename] = tp.core.types.boolean(values[filename]);
|
||||
this.props = props;
|
||||
tp.changeObject(audioLayerID, {
|
||||
dummy: true
|
||||
|
||||
const setDummy = () => {
|
||||
tp.changeObject(audioLayerID, {
|
||||
dummy: true
|
||||
});
|
||||
};
|
||||
|
||||
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();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
tp.changeObject(audioLayerID, this.props);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
setTimeout(() => {
|
||||
tp.changeObject(audioLayerID, this.props);
|
||||
resolve();
|
||||
}, 100);
|
||||
setDummy();
|
||||
});
|
||||
};
|
||||
this.removeFile = (filename) => {
|
||||
|
@ -120,13 +161,26 @@ const AudioLayer = function(tp, audioLayerID, values = false, autoInit = true) {
|
|||
delete values[filename];
|
||||
delete props[filename];
|
||||
this.props = props;
|
||||
tp.changeObject(audioLayerID, {
|
||||
dummy: true
|
||||
const setDummy = () => {
|
||||
tp.changeObject(audioLayerID, {
|
||||
dummy: true
|
||||
});
|
||||
};
|
||||
|
||||
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();
|
||||
}
|
||||
});
|
||||
tp.changeObject(audioLayerID, this.props);
|
||||
}
|
||||
});
|
||||
setTimeout(() => {
|
||||
tp.changeObject(audioLayerID, this.props);
|
||||
resolve();
|
||||
}, 100);
|
||||
setDummy();
|
||||
});
|
||||
};
|
||||
this.setTime = setTime;
|
||||
|
|
|
@ -30,7 +30,7 @@ const AudioPlayer = function() {
|
|||
|
||||
this.addMany = (manyAudioElements) => {
|
||||
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) => {
|
||||
const audioLayer = new AudioLayer(tp, audioLayerID, values, false);
|
||||
audioLayers.push(audioLayer);
|
||||
|
|
|
@ -248,6 +248,14 @@ const Record = function(tp) {
|
|||
if (cPropTitle.indexOf('color.') === 0) {
|
||||
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
|
||||
.getPanelPropTitle(cPropTitle)
|
||||
.parentNode.parentNode
|
||||
|
|
|
@ -23,6 +23,10 @@ const TheatrePlay = function(autoInit = false) {
|
|||
const theatreObjects = {};
|
||||
let theatrePanel = null;
|
||||
let sequencePanelLeft = null;
|
||||
const getSequencePanel = () => {
|
||||
sequencePanelLeft = tp.shadowRoot.querySelector('[data-testid="SequencePanel-Object"]');
|
||||
return sequencePanelLeft;
|
||||
};
|
||||
const getSequencePanelLeft = () => {
|
||||
sequencePanelLeft = tp.shadowRoot.querySelector('[data-testid="SequencePanel-Left"]');
|
||||
return sequencePanelLeft;
|
||||
|
@ -321,6 +325,7 @@ const TheatrePlay = function(autoInit = false) {
|
|||
};
|
||||
this.isSequenced = isSequenced;
|
||||
this.getSequenceButton = getSequenceButton;
|
||||
this.getSequencePanel = getSequencePanel;
|
||||
this.getSequencePanelLeft = getSequencePanelLeft;
|
||||
this.getPanel = getPanel;
|
||||
this.getPanelPropTitle = getPanelPropTitle;
|
||||
|
@ -589,6 +594,28 @@ const TheatrePlay = function(autoInit = false) {
|
|||
audioMapping: audio.getMapping(),
|
||||
};
|
||||
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);
|
||||
};
|
||||
this.saveProject = (projectId = project.address.projectId, vt_project = false, silent = true) => {
|
||||
|
@ -709,12 +736,12 @@ const TheatrePlay = function(autoInit = false) {
|
|||
}) => {
|
||||
set(window.getArtboard().theatreObject.props, artboardProps);
|
||||
});
|
||||
if (project.hasOwnProperty('audioMapping')) {
|
||||
audio.setMapping(project.audioMapping);
|
||||
}
|
||||
if (project.hasOwnProperty('audioSavedMapping')) {
|
||||
audio.setSavedMapping(project.audioSavedMapping);
|
||||
}
|
||||
if (project.hasOwnProperty('audioMapping')) {
|
||||
audio.setMapping(project.audioMapping);
|
||||
}
|
||||
if (project.hasOwnProperty('audioSavedMapping')) {
|
||||
audio.setSavedMapping(project.audioSavedMapping);
|
||||
}
|
||||
|
||||
// load layers
|
||||
const layerPromises = [];
|
||||
|
@ -723,17 +750,48 @@ const TheatrePlay = function(autoInit = false) {
|
|||
.forEach((layerId) => {
|
||||
window.setLoadingTask(`setting up the shapes of ${layerId} to come`, 90);
|
||||
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]));
|
||||
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
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Promise.all(layerPromises).then(() => {
|
||||
}
|
||||
sequencialPromises(layerPromises, () => {
|
||||
window.layerOrder.set(project.layerOrder);
|
||||
this.duration = this.core.val(this.sheet.sequence.pointer.length);
|
||||
if (project.layerOrder.length > 0) {
|
||||
|
|
|
@ -531,6 +531,25 @@ const getNestedProperty = (o, a, verify = false) => {
|
|||
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
|
||||
const rgbaToHexa = (rgba) => {
|
||||
return '#' + (
|
||||
|
@ -610,6 +629,7 @@ export {
|
|||
flattenObject,
|
||||
deFlattenObject,
|
||||
getNestedProperty,
|
||||
findNestedObjectKey,
|
||||
rgbaToHexa,
|
||||
hexaToRgba,
|
||||
getFileExtensionFromMimeType,
|
||||
|
|
Loading…
Reference in a new issue