add recorded to timeline

dependencies hashes:
openFrameworks d78075f4bca6be2a2533c6e51a75cc1f18404501
ofxMsdfgen e14da13d02c4dff04fb69d7923469f606924e6c3
ofxGPUFont d482bb7cbdf6b296fa4ab5abcf73fb5ff8c8b239
ofxVariableLab 0b5f9bdebc1e5550621957e73c040c258ec6317b
ofxProfiler a868e34fa1a79189dd4fbdede2938e308535e5e8
theatre 86d3e07f6f2c75fd6e08fca8c97e3617c9e23b18
This commit is contained in:
themancalledjakob 2024-04-12 16:32:47 +02:00
parent 42c47aa003
commit 18300baf46
9 changed files with 146 additions and 88 deletions

View file

@ -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
});

View file

@ -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,29 +42,34 @@ 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);
const mergedValues = {
...this.theatreObject.value,
...values
};
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();
});
});
};
const remove = () => {
@ -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;

View file

@ -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);
};
this.listener = (event) => {
let hot = false;
let time = false;
this.listener = (event) => {
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);
}
}
});

View file

@ -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');

View file

@ -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) => {

View file

@ -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,"");
};

View file

@ -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

View file

@ -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