Forum Discussion
Have Closed Captions generate as a variable
Hello Nedim . I hope you're well. 🤚 I’m interested in this possibility (having subtitles in a text variable to display them in speech bubbles, for example). I tried to do it (as it seems you managed to do) with the AI assistant, but of course, neither it nor I succeeded! I did, however, guide it by showing it the ‘right’ method using the last sentence of your last paragraph (and after creating a text variable and setting ‘Player.DisplayCaptions’ to TRUE). Do you have any more tips to help me assist the Assistant? Please.
Also, I haven’t managed to correctly retrieve “currenttime” and “totaltime” as in your example, which could be useful. I’ve made several requests to the Assistant, created similar SL variables and tried to retrieve the existing values (in the Player??), but I’ve had just as many failures in getting it right.
Finally, do you think it’s possible NOT to display the subtitles if they’re correctly entered into a Storyline variable that’s already displayed??
Thanks in advance. Looking forward to your brilliant replies. Thierry
Now, regarding the code for the current time and total duration. I didn’t investigate deeply enough to confirm which player variables (if any) store these values as displayed on the timeline. Instead, I relied on the aria-valuetext attribute of the <input type="range"> element (see the HTML snippet below). I used a MutationObserver (again) in JavaScript to watch for changes to this attribute and extract the displayed time from it. That was enough for me, as I was satisfied with the result and didn’t need to chase variables.
HTML
<input tabindex="0" type="range" aria-hidden="true" aria-label="slide progress" data-ref="progressBar" data-tabindex="0" max="30667" step="100" aria-valuemin="0" aria-valuemax="30667" aria-valuenow="18900" aria-valuetext="0:18 / 0:30 played">
JS
const progress = document.querySelector('[data-ref="progressBar"]');
const observer = new MutationObserver((mutations) => {
for (const mutation of mutations) {
if (mutation.type === "attributes" && mutation.attributeName === "aria-valuetext") {
let text = progress.getAttribute("aria-valuetext");
text = text.replace(" played", "");
setVar("TimeDisplay", text);
}
}
});
observer.observe(progress, {
attributes: true,
attributeFilter: ["aria-valuetext"]
});
Why MutationObserver in both scripts and what is it?
MutationObserver is a JavaScript API that watches for changes in the DOM and runs a callback when something updates. In both scripts (including the Captions script), I use it to listen for specific attribute changes, in this case, aria-valuetext on the progress bar, and extract the current and total time when it updates. I chose this instead of something like setInterval because it runs only when the value actually changes, rather than executing every few milliseconds unnecessarily.
The biggest benefit of both scripts is that these hidden Storyline engine values can now be fully customized and styled, since they are extracted into a custom variable and displayed in a single text box or a shape.