-
Static tracksI'm following this code sample to use the The code above is loading tracks statically, I mean they are constant and not changing: playlist.load([
{
src: "hello.mp3",
name: "Hello",
// ...
},
]); Dynamic tracksBut I'm fetching tracks by an API and then pass the track URLs to the export default function DawTracks({ ee, voices /* voices are passed as `props` to React component */ }) {
const [toneCtx, setToneCtx] = useState(null);
const container = useCallback(
(node) => {
if (node !== null && toneCtx !== null) {
const playlist = WaveformPlaylist(
{
ac: toneCtx.rawContext,
// ...
},
ee
);
// ...
ee.on('audiorenderingfinished', function (type, data) {
//...
});
playlist
.load(
// Voices/tracks would be loaded here.
// Voices/tracks would be received as React component `props`.
voices.map((voice) => {
return {
src: voice.original_voice_url,
name: voice.title,
};
})
)
.then(function () {
// can do stuff with the playlist.
// Initialize the WAV exporter.
// ...
});
}
},
[ee, toneCtx] // The callback is run only when these dependencies change.
);
return (
<>
<div ref={container}></div>
</>
);
} ProblemThe problem is that my code for dynamic tracks is not stable. Whenever the tracks/voices change as React component Workaround: didn't workA workaround was supposed to be using QuestionWas is the best practice to load voices/tracks dynamically using ReactJS tools? I know this might be more of a React question, but I just thought I'd ask 😄 Thanks. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
UPDATEActually, later we realized this is not a good approach to declare Possible solution?This is what I did and looks like it works. But I'm not sure if this approach is the best practice.
|
Beta Was this translation helpful? Give feedback.
-
More reliable approachDeclare playlist as a React
Expand codeexport default function DawTracks({ ee, voices, /* ... */ }) {
// Playlist should be a `useState` to cause re-render.
// Upon re-render due to playlist change, the device microphone is accessed reliably by a `useEffect`.
const [playlist, setPlaylist] = useState({});
// To create the playlist:
const container = useCallback(
(node) => {
if (node !== null && toneCtx !== null) {
setPlaylist(WaveformPlaylist(
{
// ...
container: node,
// ...
},
ee
));
ee.on('audiorenderingstarting', function (offlineCtx, a) {
// ...
});
ee.on('audiorenderingfinished', function (type, data) {
// ...
});
ee.on('select', /* ... */ );
ee.on('timeupdate', /* ... */ );
}
},
[ee, toneCtx] // The callback is run only when these dependencies change.
);
// To load the voices/tracks (upon voice/track update) and access the device microphone (upon playlist update):
useEffect(() => {
// If playlist is not ready yet, return.
if (playlist &&
Object.keys(playlist).length === 0 &&
Object.getPrototypeOf(playlist) === Object.prototype) {
return;
}
var gotStream = function (stream) {
let userMediaStream = stream;
playlist.initRecorder(userMediaStream);
// ...
};
var logError = function (err) {
console.error(err);
};
playlist
.load(
// Voices of the current media would be loaded here.
// They would be fetched from the database table.
voices.map((voice) => {
return {
src: voice.original_voice_url,
name: voice.title,
start: isNaN(parseFloat(voice.start)) ? 0.0 : voice.start,
};
})
)
.then(function () {
// can do stuff with the playlist.
// After you create the playlist you have to call this function if you want to use recording:
//initialize the WAV exporter.
playlist.initExporter();
if (navigator.mediaDevices) {
navigator.mediaDevices.getUserMedia(constraints).then(gotStream).catch(logError);
} else if (navigator.getUserMedia && 'MediaRecorder' in window) {
navigator.getUserMedia(constraints, gotStream, logError);
}
});
}, [voices, playlist]); // The effect only runs when a re-render is due to these.
return (
<>
<div ref={container}></div>
</>
);
} |
Beta Was this translation helpful? Give feedback.
More reliable approach
Declare playlist as a React
state
then:useCallback
to create the playlist.useEffect
to load the voices/tracks (upon voice/track update) and access the device microphone (upon playlist update).Expand code