Forum Discussion
Have Closed Captions generate as a variable
I am working on a project, where I have a character who is talking to the user and going into scenarios. Rather than create caption shapes and then typing all of the speaking points out and matching it to the audio on the slide, I was hoping to have/create a variable where the created closed captions could be shown in a text field or wherever else I want on the page rather than the standard top or bottom of the page. This way I could modify the way they look, where they are located, and reduce the time it takes to create conversation scenarios by not having duplicate work.
13 Replies
- NedimCommunity Member
As Phil mentioned, the recommended approach is to create your own custom text variable in Storyline and then extract the captions directly from the caption container in real time as they appear.
At the moment, there isn’t a built-in Storyline variable that exposes caption text (as far as I know). However, you can ensure captions are enabled either through the player settings or by using a trigger such as “Set Player.DisplayCaptions to True” when the timeline starts.
From there, the remaining part can be handled with JavaScript. By observing the caption container in the DOM, you can capture the caption text whenever it appears or changes and pass it into a Storyline variable.
Here’s an example:
- ThierryEMMANUELCommunity Member
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
- NedimCommunity Member
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.
- BrettAmstutzCommunity Member
I'll be honest, I don't know how I would do that. Any suggestions on where to start?
- PhilMayorSuper Hero
But you would also have to create the mechanism to update it.
- PhilMayorSuper Hero
You would have to create it.
- BrettAmstutzCommunity Member
Does this variable exist? Or is it able to be created?
- PhilMayorSuper Hero
No reason why that wouldn't work