Jump to and play audio issue
January 29, 2018 12:00 AM
On some of my pages, I have a question where the user can click on a button to get a hint and feedback when they've answered the question. The audio contains both the page text, answer and hint. (I have to do this to comply with accessibility, so we can avoid the pros and cons of audio that reads the text on the screen :) )
I use JavaScript to set the currentTime with events to pause the audio at the appropriate time (i.e., pause before the answer audio, pause again before the hint audio). The first button works fine, but the second does not UNLESS the second button is selected AFTER the first pause. If I pull the second pause event from the audio, it also works, but the audio would then read the answer part AND the hint part.
I've attached a sample that has both the JS, the audio with events and buttons. I did try to use the .play() in the JS and that had no effect.
Discussion (16)
I'm completely stumped. I've set the JS to check the current time and if the current time = 0, only jump to the specified time, otherwise, jump to the specified time and play. This works beautifully UNTIL I add the pause event, no matter WHAT time the event occurs.
I was even able to add an event listener to pause the audio without an event and it still doesn't work. The pause works great, but it won't resume play when hitting either button.
Other than splitting my audio into multiple files (ugly on some pages where I have several options), I'm not sure where else to go.
undefined
Hi Jason,
I am not 100% sure this causes your issue, but it might. MP3 encoded audio needs to be decoded before play, and depending on the way its encoded. Variable bitrate versus Constant bitrate that might cause issues with MP3. Also i do know going to an exact time is tough, because time in HTML5 audio is notoriously inprecise. I might have some solutions for you, because i encountered this before and got that fixed for that project. Gonna mock up a sample for that...
Check these articles:
https://stackoverflow.com/questions/25468063/html5-audio-currenttime-attribute-inaccurate
http://terrillthompson.com/blog/624
2 options you can try. I am working ( when time allows ) on a sample to check this myself. Use a external javascript library for play/pause/jumptotime functionality. Often they are way more robust then internal functionality. One you could try is Buzz (http://buzz.jaysalvat.com/demo/) a older demo of it in Lectora (11) you find here (http://community.trivantis.com/shared-content/fade-audio-in-lectora/) Other popular audio libraries are Howler.js and SoundJS.
Second option i think might help. In combo with the external libraries probably. Use Wav and/or Ogg as audio type. Mp3 is compressed, these formats are not.
Regards,
Math
Ok, so in the end, I think I found a stupidly simple solution:
- At .10 of the audio, set a variable (playing) to 1
- At 25 and 35 seconds, set an event to run an action group.
- In the action group, play the audio if "playing" = 1, otherwise, pause.
- On the buttons, set the current time using JavaScript.
I'm a little disappointed in myself for not making this far easier than it actually ends up being. I'll need to do some further testing, but think this will cover that vast majority of ways the user will be accessing audio.
@JasonADal Hi Jason, Not directly concerning this topic i got a few questions for you. Can you contact me at my mail-adress info@mathnotermans.nl
Kind regards,
Math
Don't be disappointed. True research is different from entering a term and click "Find". There's no way around accepting that it's not always the first experiment that solves an issue. Actually it's the next attempts that make the developer, not the first.
Absolutely true, Tim - I wouldn't have come up with the solution to make updating the JS to jump to the right time easier than changing the target and time for any media. It's the experimenting and learning that I'm definitely excited about!
Well, it appears I hit a new snag in the solution I came up when there is more than one "section" of audio.
Section 1 = Page information
Section 2 = Feedback for the question
Section 3 = A hint for the learner
I can get the pause to occur at the end of section 2, but if I have that event, the audio will not start after the jump to section 3 if the audio reaches the pause point for section 1. So I'm back to being somewhat flummoxed.
With regard to the currently running contest:
I love Lectoras audio player.
http://community.trivantis.com/contest/love-from-to/
Tim, that setup is FANTASTIC! That may be dinner and a drink when we meet!
I did take it a step further with some adaptations. My courses allow learners to auto start the audio, captions only, or audio and captions on each page. The jump/interval piece still worked beautifully, but I couldn't get the audio to stop at the beginning of the first interval (i.e. stop at 4 seconds, since the first interval started there in your example).
Instead, I used timeupdate with a series of "if" statements to mark the pause points and the play points. It's a bit ugly, especially if there are more than a couple of intervals, but it works whether the audio auto starts or the learner starts it manually. There may be a cleaner way to do it so I might take some time to see if I can further combine the solutions.
The other ugly part is that to get the pause, I had to use "undefined==". My suspicion is that it's related to the nature of variable rate MP3s and how they are very rarely going to hit the EXACT value for seconds.
undefined
Tim, thanks again for the help and great explanation. I didn't find anything that remotely suggested I could use decimal values on the times! Can you go beyond 10ths of a second?
If I'm reading it correctly, it sounds like the missing link was using the custom variables and Lectora functions where I needed to use the RunJS and the "PlayFromTo" function.
What's your take on using variables to define the intervals, then using the variable in the function? I tried a few variations of a value for the variable, but was only able to get it work myself with two separate variables to identify the start time and end time. I tried no quotes and quotes around (0,24.5) then the same, but without the parentheses. I was trying to see if there was a way to more quickly add the intervals and update the initial "pause" and the intervals onClick.
Here's a new version. I've added a page with explanations. The function I wrote was supposed to be the "cleaner way to do it" ;-)
The custom player is more or less a copy of Lectoras with Lectora controlling (only) the original. The playFromTo function sets the current time to a value and uses an event listener for timeupdate to pause at the end. So it's the same approach you've been using. The function and all event listener refer to the custom player. If you use a Lectora action the original will come up.
I believe using variables should be more effort as you'd have to modify the variables before calling the function instead of directly calling it with the values.
If you wanted to use variables you'd have to make sure the values a are seconds, e.g. 67.4 (I think you can use more digits after the dot). If you're using Lectora variables you'll have to turn the values into numbers as Lectora variables are always strings.
You could use variables for the arguments:
playFromTo(Number(VarStart.getValue()),Number(VarEnd.getValue()));
Or you could modify the function to get the values and remove the arguments.
It sounds like the variables idea is way more of a hassle - I've used an excel spreadsheet before something like this, where one cell is the "static", then others are the "variable" so that I can just enter the values, copy and paste - sometimes much faster than trying to highlight and change (where I find myself accidentally deleting parentheses a lot).
Also, I made a tweak to the player behavior when clicking the play/pause button. In testing, the audio always reset to "begin" if the user paused the audio. I can see this easily becoming an annoyance for some of my users. So instead, I added the below so that if the pause occurs in the middle of the segment, it pauses then resumes where it left off. If the audio reaches the end of the segment and the user clicks "play", then it resets the "begin" time and replays the segment.
// allows user to pause and resume without resetting timeif (player.CurrentTime undefined
}else{
// returns player to 0:00 if at end of segment
if(begin undefined
The only caveat with this is that if the user wants to pause and restart the audio, they'd have to use the slider, but that's the case with any audio, as the player does not have a restart button or function that I've found.
Thanks to all three of you for this great conversation. As you may remember, members of this group + Darrel Somoza put together (to help in my work) a player to play from point A to point B (it is in 2 parts and seems quite simple) - and it works just fine except that the stop point can be a bit variable. I will check this version out.
Thank you all so much!
Andrew
Math's response really set the stage for getting this to work and speaks to your comment on variable stop points, especially for MP3s. I noticed that MP3s are rarely, if ever an exact number to anything less than 3 places after the decimal. If you want to check it out, use Inspect Element on the time rail and scroll up to the span class for "mejs-time-total mejs-time-slider" The only thing that's on an exact time is "aria-valuetext".
undefined
Discussions have been disabled for this post