add recorded to timeline
dependencies hashes: openFrameworks d78075f4bca6be2a2533c6e51a75cc1f18404501 ofxMsdfgen e14da13d02c4dff04fb69d7923469f606924e6c3 ofxGPUFont d482bb7cbdf6b296fa4ab5abcf73fb5ff8c8b239 ofxVariableLab 0b5f9bdebc1e5550621957e73c040c258ec6317b ofxProfiler a868e34fa1a79189dd4fbdede2938e308535e5e8 theatre 86d3e07f6f2c75fd6e08fca8c97e3617c9e23b18
This commit is contained in:
parent
42c47aa003
commit
18300baf46
9 changed files with 146 additions and 88 deletions
|
@ -107,8 +107,8 @@ const MicrophoneRecorder = function() {
|
|||
this.startListener = (event) => {
|
||||
console.log('microphoneRecorder startl received', event);
|
||||
if (event.detail === record.possibleStates.RECORDING) {
|
||||
console.log('microphoneRecorder startibus');
|
||||
this.start();
|
||||
console.log('microphoneRecorder start', filenameWithoutExtension);
|
||||
window.removeEventListener('record', this.startListener);
|
||||
}
|
||||
};
|
||||
|
@ -116,7 +116,7 @@ const MicrophoneRecorder = function() {
|
|||
this.stopListener = (event) => {
|
||||
console.log('microphoneRecorder stopl received', event);
|
||||
if (event.detail === record.possibleStates.STOPPING_RECORDING) {
|
||||
console.log('microphoneRecorder stopibus');
|
||||
console.log('microphoneRecorder stop', filenameWithoutExtension);
|
||||
this.stop().then((filename) => {
|
||||
// be happy
|
||||
});
|
||||
|
|
|
@ -1,61 +1,35 @@
|
|||
import {
|
||||
sanitizeTheatreKey
|
||||
} from './utils.js';
|
||||
|
||||
const AudioLayer = function(tp, audioLayerID, values = false, autoInit = true) {
|
||||
// private
|
||||
let props = {
|
||||
time: tp.core.types.boolean(false),
|
||||
audioFile: tp.core.types.stringLiteral(
|
||||
'no_audio_file',
|
||||
{
|
||||
no_audio_file: 'no audio file :(',
|
||||
},
|
||||
),
|
||||
};
|
||||
let props = { };
|
||||
if (typeof values === 'string') {
|
||||
const filename = sanitizeTheatreKey(values);
|
||||
values = {};
|
||||
values[filename] = false;
|
||||
}
|
||||
if (typeof values === 'object') {
|
||||
props[Object.keys(values)[0]] = tp.core.types.boolean(false);
|
||||
}
|
||||
|
||||
// private functions
|
||||
//
|
||||
const onValuesChange = (values) => {
|
||||
console.log(values);
|
||||
};
|
||||
|
||||
const updateAudioFiles = () => {
|
||||
console.log('update audio files');
|
||||
return new Promise((resolve) => {
|
||||
moduleFS.readdir(config.fs.idbfsAudioDir).then((files) => {
|
||||
;
|
||||
console.log(files);
|
||||
if (files.length > 0) {
|
||||
const audioFiles = {
|
||||
no_audio_file: 'no audio file :(',
|
||||
};
|
||||
files.forEach((file) => {
|
||||
audioFiles[file] = file;
|
||||
});
|
||||
props.audioFile = tp.core.types.stringLiteral(
|
||||
audioFiles[files[0]],
|
||||
audioFiles
|
||||
);
|
||||
tp.changeObject(this.id(), props);
|
||||
if (typeof this.theatreObject === 'object') {
|
||||
tp.studio.transaction(({
|
||||
set
|
||||
}) => {
|
||||
set(this.theatreObject.props.audioFile, files[0]);
|
||||
});
|
||||
}
|
||||
}
|
||||
resolve(files);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const findInjectPanel = () => {
|
||||
console.log('find and inject');
|
||||
};
|
||||
|
||||
const setTime = (start, stop) => {
|
||||
const keyframes = [
|
||||
{
|
||||
path: ['time'],
|
||||
keyframes: [
|
||||
{
|
||||
const setTime = (filename, start, stop) => {
|
||||
filename = sanitizeTheatreKey(filename);
|
||||
return new Promise((resolve) => {
|
||||
const keyframes = [{
|
||||
path: [filename],
|
||||
keyframes: [{
|
||||
position: -1,
|
||||
value: false,
|
||||
},
|
||||
|
@ -68,28 +42,33 @@ const AudioLayer = function(tp, audioLayerID, values = false, autoInit = true) {
|
|||
value: false,
|
||||
},
|
||||
],
|
||||
}];
|
||||
if (tp.getKeyframes(this, [filename]).length > 0) {
|
||||
tp.studio.transaction(({
|
||||
__experimental_deleteKeyframes
|
||||
}) => {
|
||||
__experimental_deleteKeyframes(this.theatreObject.props[filename]);
|
||||
});
|
||||
}
|
||||
];
|
||||
tp.setKeyframes(this, keyframes);
|
||||
tp.addKeyframes(this, keyframes).then(() => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const init = () => {
|
||||
return new Promise((resolve) => {
|
||||
updateAudioFiles().then((files) => {
|
||||
this.theatreObject = tp.addObject(audioLayerID, this.props, onValuesChange);
|
||||
tp.changeObject(audioLayerID, this.props);
|
||||
tp.studio.transaction(({
|
||||
set
|
||||
}) => {
|
||||
const mergedValues = {...this.theatreObject.value, ...values};
|
||||
console.log({values, mergedValues}, this.props);
|
||||
set(this.theatreObject.props, values ? mergedValues : this.theatreObject.value);
|
||||
});
|
||||
// this has to be a timeout, because theatre is not ready otherwise
|
||||
|
||||
setTime(1,2);
|
||||
resolve();
|
||||
this.theatreObject = tp.addObject(audioLayerID, this.props, onValuesChange);
|
||||
tp.studio.transaction(({
|
||||
set
|
||||
}) => {
|
||||
const mergedValues = {
|
||||
...this.theatreObject.value,
|
||||
...values
|
||||
};
|
||||
set(this.theatreObject.props, values ? mergedValues : this.theatreObject.value);
|
||||
});
|
||||
resolve();
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -101,6 +80,52 @@ const AudioLayer = function(tp, audioLayerID, values = false, autoInit = true) {
|
|||
|
||||
this.findInjectPanel = findInjectPanel;
|
||||
|
||||
this.setFile = (filename) => {
|
||||
filename = sanitizeTheatreKey(filename);
|
||||
const values = {};
|
||||
values[filename] = false;
|
||||
props = {};
|
||||
props[filename] = tp.core.types.boolean(values[filename]);
|
||||
this.props = props;
|
||||
tp.changeObject(audioLayerID, this.props);
|
||||
tp.studio.transaction(({
|
||||
set
|
||||
}) => {
|
||||
set(this.theatreObject.props, values);
|
||||
});
|
||||
};
|
||||
this.addFile = (filename) => {
|
||||
return new Promise((resolve) => {
|
||||
filename = sanitizeTheatreKey(filename);
|
||||
const values = this.theatreObject.value;
|
||||
values[filename] = false;
|
||||
props[filename] = tp.core.types.boolean(values[filename]);
|
||||
this.props = props;
|
||||
tp.changeObject(audioLayerID, {
|
||||
dummy: true
|
||||
});
|
||||
setTimeout(() => {
|
||||
tp.changeObject(audioLayerID, this.props);
|
||||
resolve();
|
||||
}, 100);
|
||||
});
|
||||
};
|
||||
this.removeFile = (filename) => {
|
||||
return new Promise((resolve) => {
|
||||
filename = sanitizeTheatreKey(filename);
|
||||
const values = this.theatreObject.value;
|
||||
delete values[filename];
|
||||
delete props[filename];
|
||||
this.props = props;
|
||||
tp.changeObject(audioLayerID, {
|
||||
dummy: true
|
||||
});
|
||||
setTimeout(() => {
|
||||
tp.changeObject(audioLayerID, this.props);
|
||||
resolve();
|
||||
}, 100);
|
||||
});
|
||||
};
|
||||
this.setTime = setTime;
|
||||
|
||||
this.init = init;
|
||||
|
|
|
@ -37,7 +37,7 @@ const AudioPlayer = function() {
|
|||
} else if(!audioElement.audioDomElement.paused) {
|
||||
audioElement.audioDomElement.pause();
|
||||
audioElement.audioDomElement.currentTime = 0;
|
||||
console.log('paus audioElement ', audioElement.file, audioElement.propTitle, i);
|
||||
console.log('pause audioElement ', audioElement.file, audioElement.propTitle, i);
|
||||
}
|
||||
} else if (!audioElement.audioDomElement.paused) {
|
||||
audioElement.audioDomElement.pause();
|
||||
|
@ -53,9 +53,9 @@ const AudioPlayer = function() {
|
|||
this.update();
|
||||
}, updateInterval_ms);
|
||||
};
|
||||
let hot = false;
|
||||
let time = false;
|
||||
this.listener = (event) => {
|
||||
let hot = false;
|
||||
let time = false;
|
||||
if (event.detail === record.possibleStates.RECORDING) {
|
||||
hot = clone(record.getHot());
|
||||
time = tp.sheet.sequence.position;
|
||||
|
@ -69,13 +69,15 @@ const AudioPlayer = function() {
|
|||
const waitForMicrophoneListener = (event) => {
|
||||
if (event.detail.fileIsRead) {
|
||||
this.add(layerID, propTitle, time, event.detail.filename);
|
||||
addAudioLayer().then((audioLayer) => {
|
||||
m.layer = audioLayer;
|
||||
});
|
||||
window.removeEventListener('microphoneRecorder', waitForMicrophoneListener);
|
||||
addAudioLayerTrack(event.detail.filename, time, tp.sheet.sequence.position);
|
||||
window.removeEventListener(
|
||||
'microphoneRecorder',
|
||||
waitForMicrophoneListener);
|
||||
}
|
||||
};
|
||||
window.addEventListener('microphoneRecorder', waitForMicrophoneListener);
|
||||
window.addEventListener(
|
||||
'microphoneRecorder',
|
||||
waitForMicrophoneListener);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -86,14 +88,12 @@ const AudioPlayer = function() {
|
|||
layerIDs.forEach((layerID) => {
|
||||
const propTitles = Object.keys(hot[layerID]);
|
||||
propTitles.forEach((propTitle) => {
|
||||
const m = audio.getMapping()[layerID][propTitle];
|
||||
const m = audio.getSavedMapping()[layerID][propTitle];
|
||||
if (m.addToTimeline) {
|
||||
if (m.source === 'microphone') {
|
||||
} else {
|
||||
this.add(layerID, propTitle, time, m.source);
|
||||
addAudioLayer().then((audioLayer) => {
|
||||
m.layer = audioLayer;
|
||||
});
|
||||
addAudioLayerTrack(m.source, time, tp.sheet.sequence.position);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -578,12 +578,12 @@ const deleteLayer = (id, saveProject = true) => {
|
|||
}
|
||||
};
|
||||
|
||||
const addAudioLayer = (values = false) => {
|
||||
const addAudioLayer = (filename = false) => {
|
||||
return new Promise((resolve) => {
|
||||
const audioLayerID = (() => {
|
||||
let index = 0;
|
||||
for (let i = 0; i < audioLayers.length; i++) {
|
||||
if (audioLayers.findIndex((audioLayer) => audioLayer.id() !== `audio-${index}`) < 0) {
|
||||
if (audioLayers.findIndex((audioLayer) => audioLayer.id() === `audio-${index}`) < 0) {
|
||||
break;
|
||||
}
|
||||
index++;
|
||||
|
@ -591,7 +591,7 @@ const addAudioLayer = (values = false) => {
|
|||
return `audio-${index}`;
|
||||
})();
|
||||
console.log('adding', audioLayerID);
|
||||
const audioLayer = new AudioLayer(tp, audioLayerID, values, false);
|
||||
const audioLayer = new AudioLayer(tp, audioLayerID, filename, false);
|
||||
layersById[audioLayerID] = audioLayer;
|
||||
audioLayers.push(audioLayer);
|
||||
audioLayer.init().then(() => {
|
||||
|
@ -606,7 +606,7 @@ const addExistingAudioLayer = (audioLayerID, values) => {
|
|||
audioLayers.push(audioLayer);
|
||||
layersById[audioLayerID] = audioLayer;
|
||||
audioLayer.init().then(() => {
|
||||
resolve();
|
||||
resolve(audioLayer);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
@ -623,6 +623,30 @@ const deleteAudioLayer = (audioLayerID) => {
|
|||
//delete audioLayersById[id];
|
||||
};
|
||||
|
||||
const addAudioLayerTrack = (filename, start = 0, end = 1) => {
|
||||
const addTrack = () => {
|
||||
return new Promise((resolve) => {
|
||||
audioLayers[0].addFile(filename).then(() => {
|
||||
audioLayers[0].setTime(filename, start, end).then(() => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
return new Promise((resolve) => {
|
||||
if (audioLayers.length < 1) {
|
||||
addAudioLayer().then((audioLayer) => {
|
||||
addTrack().then(() => {
|
||||
resolve();
|
||||
});
|
||||
});;
|
||||
} else {
|
||||
addTrack().then(() => {
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
// TODO: better function names
|
||||
// because, come on. it may be funny for a second
|
||||
// but tolerance for fun is low when you're grumpy
|
||||
|
@ -650,6 +674,7 @@ window.deleteLayer = deleteLayer;
|
|||
window.addAudioLayer = addAudioLayer;
|
||||
window.addExistingAudioLayer = addExistingAudioLayer;
|
||||
window.deleteAudioLayer = deleteAudioLayer;
|
||||
window.addAudioLayerTrack = addAudioLayerTrack;
|
||||
window.renderFrames = exporter.renderFrames;
|
||||
|
||||
const layer_panel = document.querySelector('#layer_panel');
|
||||
|
|
|
@ -651,7 +651,7 @@ const TheatrePlay = function(autoInit = false) {
|
|||
project = projectJson === false ? core.getProject(projectId) : core.getProject(projectId, {
|
||||
state: projectJson
|
||||
});
|
||||
console.log({project, projectJson});
|
||||
//console.log({project, projectJson});
|
||||
window.setLoadingTask('setting up animation', 10);
|
||||
project.ready.then(() => {
|
||||
this.sheet = project.sheet('mainSheet');
|
||||
|
@ -725,7 +725,7 @@ const TheatrePlay = function(autoInit = false) {
|
|||
window.project_fontsHashMap = project.fontsHashMap;
|
||||
layerPromises.push(window.addExistingLayer(layerId, objects[layerId]));
|
||||
});
|
||||
console.log(clone(objects));
|
||||
//console.log(clone(objects));
|
||||
Object.keys(objects)
|
||||
.filter((e) => e.indexOf('audio-') === 0)
|
||||
.forEach((layerId) => {
|
||||
|
|
|
@ -464,6 +464,9 @@ const sanitizeTheatreKey = (key) => {
|
|||
theatreKey.pop();
|
||||
}
|
||||
theatreKey = theatreKey.join('');
|
||||
if (theatreKey.substr(0,1).match(/^([0-9])$/i)) {
|
||||
theatreKey = `t_${theatreKey}`;
|
||||
}
|
||||
return theatreKey.replace(/[^a-zA-Z0-9_]/g,"");
|
||||
};
|
||||
|
||||
|
|
|
@ -38466,7 +38466,6 @@ Instead found: ${devStringify(butFoundInstead)}` : "";
|
|||
callback: () => {
|
||||
getStudio().transaction(({ stateEditors: stateEditors2 }) => {
|
||||
const propAddress = __spreadProps(__spreadValues({}, obj.address), { pathToProp });
|
||||
console.log({ propConfig, propAddress });
|
||||
stateEditors2.coreByProject.historic.sheetsById.sequence.setPrimitivePropAsSequenced(propAddress, propConfig);
|
||||
});
|
||||
}
|
||||
|
@ -61771,7 +61770,6 @@ Note that it **is okay** to import '@theatre/core' multiple times. But those imp
|
|||
detail: toVT
|
||||
});
|
||||
window.dispatchEvent(event);
|
||||
console.log({ toVT, p: p3 });
|
||||
}
|
||||
sequence2.setPrimitivePropAsSequenced = setPrimitivePropAsSequenced;
|
||||
function setPrimitivePropAsStatic(p3) {
|
||||
|
@ -61840,7 +61838,6 @@ Note that it **is okay** to import '@theatre/core' multiple times. But those imp
|
|||
};
|
||||
tracks.trackData[trackId] = track;
|
||||
tracks.trackIdByPropPath[encodedPropPath] = trackId;
|
||||
console.log({ trackId, encodedPropPath });
|
||||
}
|
||||
}
|
||||
const toVT = {
|
||||
|
@ -62837,15 +62834,23 @@ Note that it **is okay** to import '@theatre/core' multiple times. But those imp
|
|||
trackId,
|
||||
keyframes
|
||||
}));
|
||||
console.log({
|
||||
a: __spreadValues({}, root3.address),
|
||||
objectKey,
|
||||
trackId,
|
||||
keyframes
|
||||
});
|
||||
} else if (propConfig !== void 0) {
|
||||
throw Error("hmmm");
|
||||
}
|
||||
};
|
||||
if (propConfig.type === "compound") {
|
||||
forEachPropDeep(defaultValue, (v6, pathToProp) => {
|
||||
console.log("comp compoumnD");
|
||||
addStaticOrKeyframeProp(v6, pathToProp);
|
||||
}, getPointerParts(prop).path);
|
||||
} else {
|
||||
console.log("singlerer", { defaultValue, path });
|
||||
addStaticOrKeyframeProp(defaultValue, path);
|
||||
}
|
||||
} else {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -7,7 +7,7 @@ cd $DIR
|
|||
|
||||
while true;
|
||||
do
|
||||
echo "$(git ls-files bin/em/variabletime/web)" | entr -d ./reloadbrowser.sh
|
||||
echo "$(git ls-files bin/em/variabletime/web && find "$(pwd)/bin/em/variabletime/web/theatre_modules" -iname "*.js")" | entr -d ./reloadbrowser.sh
|
||||
sleep 1
|
||||
done
|
||||
|
||||
|
|
Loading…
Reference in a new issue