Events in Audio/Video files again

I know it is possible to start playing an audio file and then setting an event which will trigger a stop action (so as to stop the playback). This means that I can play from the beginning of the file until a specific point in the file. I have already done this and it works fine.

My question is as follows. Can I start playing from a specific Events point that is NOT the beginning of the file and then stop at a second Events point? My suspicion is that this can probably not happen as the player is not set up for random access but, rather, encounters instructions in the form of events *as it plays*. I hope someone can tell me that I am wrong... :(

cheers and thanks

andrew

Discussion (37)

Sort of on the lines of what Sergey suggest above but a little different (both should work ).

var myplayer =$('#audio48Media')["0"]; // Replace audio48Media with your elements HTML Name

myplayer.setCurrentTime(64); // Starting Point

myplayer.play(); // Start the audio

$('#audio48Media')["0"].addEventListener('timeupdate', function(e) { // Add event Listener so you can track current time

var currentTime = myplayer.currentTime;

if(currentTime >=78){ // This is the stop time

myplayer.stop();

}}, false);

You only need one media player on the page and you can add as many buttons (or any other trigger) with as many start and stop times as you wish. Only one file to load and you can have all your talking points.

Enjoy.

Normal Lectora actions are Play, Pause, Stop and Toggle Play/Pause. So you cannot jump to a random place in a file. If you could jump to a random place in a file, your Event 2 would just need to be set to "Pause". Okay, let's build a "jump to a random place" function :)

In Lectora 16.1.x with the new awesome MediaElement player, it is as easy as running one line of code in a Run Javascript action: "mejs.players.mep_0.setCurrentTime(20)". If you have more than one media player on the page, you might need to change mep_0 to mep_1, mep_2 and so on. And "20" is the time on the playhead in seconds. You can also enter decimals e.g. "20.4"

Here's a feature request (ping @support) - "Jump to a point in time" action for audio/video elements.

Also, if you share the actual purpose of what you are trying to build, it'd be easier to suggest an efficient way of building this ;)

OK... could not help myself. Brought down a slightly newer version of jquery and published Darrel's solution. Worked just great. I will try Sergey's solution when I get a chance.

Many thanks to all three of you. You have made my evening (and probably my next few months too).

gnight again

As a sidenote to Darrel's sample.... $('# is a JQuery selector, so you do need JQuery too...

Thank you all so much. It is getting very late here in Thailand. Will try and have a look tomorrow morning. I am basically trying to construct (find actually) an audio/video player which will go from point A to point B without the need for a streaming server. The reason for this is to avoid creating a lot of small files (saving both time and space) and also to have the possibility of determining A and B programmatically. This is for use in language learning, specifically listening comprehension. I was able to do this fairly simple with early versions of Toolbook. I was even able to do it by sending control characters from a standard terminal to videodisc players and, would you believe it, random access cassette recorders (he said revealing that he is a dinosaur in years). Now, with "modern technology" it is more complicated... but of course things are way ahead in other areas...

The Lectora 16 player may actually be able to do this inside a nice quick development environment.

goodnight for now

undefined

Good Morning/Evening everyone,

I have a question for Darrel. Why are there sync points in the audio file? I don't see what they are supposed to do (except maybe deal with a potential OnDonePlaying problem).

Cheers

Andrew

Thanks Math, I use it so often I forget to mention it. Here's the code with no jQuery (actually a better solution unless you need it for other stuff - less bloat).

var myplayer = document.getElementById("audio48Media");

myplayer.player.setCurrentTime(64);

myplayer.play();

myplayer.addEventListener('timeupdate', function(e) {

var currentTime = myplayer.currentTime;

console.log(currentTime);

if(currentTime >=78){

myplayer.stop();

}

}, false);

'Nite Andrew.

Andrew, this can be rectified. I have been quite busy. I'll take a look at it and get back to you. This has to do with the rate in which the timeupdate is fired.

Thank you so much Darrel. Very useful to know. There is no hurry at all - so please do not go to any trouble over this - I am just so glad to see the player can do random access.

Actually, I thought it had something to do with the OS or the sampling rate of files or... as this has been happening to me since Toolbook days and I basically thought it was probably impossible to fix.

Thanks again,

Good question. They have no meaning and I left them there accidentally. I initially added them because I wanted to see what would happen if I used JavaScript to select the start point of the audio and a Lectora sync point to try to stop it but it didn't work. I would up having to to use the timeupdate MediaElement method which works wonderfully. I guess the forgotten sync points also answer your other post (happy accident). I seem to have no issues saving sync points. Well Andrew, it's evening for me so this will be my final post for now. I'd like to hear how you make out using this. I think it's a great idea to have one audio file and pull from it what you need. You should be able to pull off something similar to what you used to do in ToolBook (I still kinda miss it).

AND it works with video too (mp4 at least).

There is a small problem (that I can live with) but thought I would ask anyway: the starting point for the clip seems to be found quite accurately (so far) but the ending point sometimes "slides" a bit. i.e. it stops a bit beyond the point requested (very occasionally a bit before) - and it is also a bit inconsistent - sometimes it it ok, sometimes not for no apparent reason. Maybe it has to do with the way that

"myplayer.addEventListener('timeupdate', function(e)"

updates the time and how these two lines work:

if(currentTime >=32.33){

myplayer.stop();

So here is what I am wondering. Would I get better results with AVI and WAV files which are "rawer" in terms of data OR would it be possible to calculate position in terms of frame (frame boundaries) rather than time? Problem is that as soon as you compress the raw data, that information disappears and you are basically left only with time (at least that is what I understand). Is there some way that I can get "frame accuracy" or its equivalent (milliseconds would be good) as I work with languages and milliseconds do count. The other problem of course is that uncompressed files are huge.

Any further thoughts? Thank you!

The "jump to time" feature is in our list of enhancements for the media player. We have plans to keep updating and releasing new features for the HTML5 player as we move through the Fall. I made sure to tag the request with a link to this thread so that are developers are aware of the customer interest in this feature.

Hello @support and thanks for the information.

Yes I am aware that the entire file is sent. However, there are still substantial space savings if one can use the master file rather than uploading the master file AND having to make countless clips from the master file

Good news about the milliseconds.

Thank you,,,

Following up on Darrel's message...

The simplest way I can describe it is to say that it should be possible to play precisely from point A to point B in an audio or video file. That will save space and download/upload time as well as development time.

It should also be possible to set these points programmatically i.e. in JavaScript (or whatever) - and it should not be necessary to prepare everything in advance - the students/program should be able to set these points at will (actually as necessary).

Also, please provide some reasonable granularity in the time intervals e.g. 1 millisecond or something like that. 1-second intervals are far too imprecise for sophisticated work. 1-byte precision would be great....

Sorry if this sounds like a lot, but such facilities are really important if we are to make some high quality contributions to areas like language/culture education (my area) especially in hugely expanding markets like the ASEAN community (and also contribute in interesting ways to research in those fields). I currently have many PhD students who already occupy important roles in Asian universities who can use this in their study and, of course, in their future professional lives.

Thanks!

undefined

Any files included with a Lectora title will include the full file. If you have an MP4 in your title then the entire video will be included regardless of any controls you have set to only play a portion of it.

Because we already have the Event Timings feature, any new features like a "Jump to Time" would probably be incorporated with this existing interface. So it would include millisecond timings.

Make sure when you add the "Jump to Time" feature that it includes the ability to stop before the end.

Thank you.

Darrel

Interesting followup.

If I have TWO buttons to access the same audio file (at different times, and whether using the jquery version or not), This is what happens:

(a) Button 1 is supposed to play from 5 seconds to 7 seconds

(b) Button 2 is supposed to play from 3 seconds to 10 seconds.

If I click in Button 2, it correctly plays from 3 - 10. It will do so repeatedly. If I click on Button 1, it will also play correctly from 5 - 7 seconds.

If I then want to click Button 2 again, it will start at the correct point (3 seconds) but will always stop at 7 seconds (as in Button 1) and NOT at 10 seconds (the correct stopping point).

It makes no difference whether I set the end point manually or with a variable. It seems to remember the ending point no matter what I do.

if(currentTime >=10){ // It does not matter what I do this condition does not work. I could change 10 to 3 or 100.

myplayer.stop();

}

If I refresh the page then everything is re-initialised. I have tried creating a new player (myplayer2) and also played with the name of the time variable. Nothing seems to work. I wonder if there is some function to reinitialise the whole system.

This is puzzling me ... I will keep investigating, In the meantime, any expert ideas would be welcome. I tried to attach a zip file using Darrel's initial programming and different cuepoints - but it was to big for some reason.

It's as if the following line

if(currentTime >=10){

was changed internally (and invisibly) to

if(currentTime >=7){

So strange...

undefined

Fantastic! I have now tried this with three buttons and passing variables to the player from Lectora as well as hardcoding.

Thank you Tim (and of course Darrel, Sergey and Math - such a great team - you have all been wonderful to me over many months now)! I am beyond words...  I have literally been waiting for years for an integrated solution (provided by Lectora and you) and must have asked dozens/hundreds of people...

Hi Tim

Thanks so much ... sounds ingenious. That way only one instance of the player is ever created. I will see how that works here.

And no... the "sliding" occurred in Lectora 16... actually I tried out Darrel's code in Lectora 12 and it did not seem to work.

Will let you know how things develop - thanks again

Andrew

Hi,

I could make Darrels code work for two buttons playing overlapping parts of an audio:

1. Created a Lectora variable "audio_stop"

2. Added an action to the page to set up the player and event listener:

On: Show

Action: Run javascript

Javascript:

myplayer = document.getElementById("audio48Mediaundefined

3. Add an action to the button to set stop timing

On: Click

Action: Modify variable

Target: audio_stop

Type: Set equal to

Value: 10 (the time to stop)

4. Add an action to the button to set start timing and play

On: Click

Action: Run javascript

Javascript:

myplayer.setCurrentTime(5);

myplayer.play();

This worked for both buttons on all clicks.

With regard to "the ending point sliding a little": you wrote in another thread that you're still on Lectora v12 and thus working with JW Player. As far as I know the JW Player doesn't know milliseconds but only responds in .1 second steps. If you try to stop at .15 it will actually stop either at .1 or .2.

Tim

FYI, Tim's adaptation of Darrel's coding also works with multiple players on the same page (well two anyway) each accessing a different audio file. While it's great that this works, I wonder what is the explanation of the problem I encountered. The only explanation I can come up with is that in Tim's coding, players are declared only once each (on page show) whereas the way I had it, a player was declared each time a button was pressed.

That might be the issue Andrew ;-)

Instantation of an element should always be done only once. Then you can change or update any content at any action or at any time, but if you declare the same object again, you need to redo all the actions to check whether its setup properly again too. When for what reason you need to instantiate/declare something again , you need to make sure to kill/remove the old object, else you can run into trouble ( as probably happened ) because the scripts target the wrong object. Your issue might be something like that...having the wrong scope..

I'll check the quote thing. I always say not to copy and paste from the forum because I always run into quote issues, maybe I failed to follow my own suggestion. 

Also, there is a timerRate option that has a default of 250. This determines how often the timeUpdate fires. I tried to adjust this but I was not successful in getting a noticeable change. Again, I think it has to do with the way Lectora implements mediaelement (Sorry, easy to blame them, it's probably just me.) I found THIS on github. We'll conquer this, I'm sure of it.

I think the best solution will be to implement your own import of mediaelement.js like it doesn't exist in Lecotra and work from there. Like you said, FULL control without side effects.

Fold.it - uh oh, like I need another distraction...lol. That's pretty cool, Thanks for sharing it I'll be checking it out.

Hey gang. I've been quite busy all of a sudden. Tim, thank you for picking this up. Your solution looks elegant. I haven't had much time to play with this but I'm still having the same issue I had before; it takes two clicks of the second audio button to play. I see there was a typo on your onload page code Varaudiostop.getValue() should be Varaudio_stop.getValue(). Missing the underscore, no biggie unless someone is trying to follow along that doesn't usually write scripts.

Unless I'm doing something wrong (extremely possible) I'm not getting Andrews results.

I used and recommended mediaelement.js when Lectora was still using JSPlayer because I like to have full control using the API. I think some of the issues we're running into is the way Trivantis is implementing the code. As soon as I have the time I'll add mediaelement.js using an HTML header script and build it independent of Lectora as a test - unless one of you beat me to it. 

One player instance should be able to handle this adding and removing event listeners as required.

Teamwork is awesome.

Maybe two issues.

Yes - the first issue was the typo (from Tim - which I forgot to report in my euphoria) but I also noticed something else...

Darrel, when you sent out your code, I noticed you were using a combination of different types of quote marks, e.g. a "grave" accent etc. In order to make your code work I had to replace your quotes with (in my case) standard single quotes and then it was ok. Could that be the reason for your double-clicking issue?

I have just managed to get the clips to repeat X times using setTimeout and doing a very primitive time calculation to set the limits of the timeout. It is all scavenged code (of course :) ). Does it work, yes. Is it the correct way to code, certainly not. The real problem is that I could not find a way of emulating the Lectora "On Done Playing" action (especially as the code is split). Anyway, I prefer JS as it leaves me more in control. Just need to set up and communicate Lectora variables to JS (which is no great hardship). I am happy to share my code but you will laugh a lot.

And yes teamwork is awesome. It is the way of the 21st century... I think of it as community intelligence... look at some of the great crowdsourcing successes, e.g. http://fold.it

cheers

I also discovered something else. If you use the speaker icon to represent the sound, it will not play. You must use the controller display for the sound. I have not tried to use an "invisible" display. Actually, if you have more than one sound on the page, it seems that ALL sounds need to be represented in this way. In order to hide the players at runtime you can make them initially hidden

I have another question but will ask in a separate message.

Hi,

thanks for correcting my typo.

The forum will change the format of quotes ' ", unless it is marked as code:

myplayer = document.getElementById("audio48Mediaundefined

Tim

code.jpg

undefined

See if this works for you. I bypassed Lectora's player altogether. I'm sure the code could be better written but this get the job done. I'm going to work on getting the timeupdate response better as well.

For interest: A quote about foldit:

Understanding how proteins fold themselves into configurations that allow them to do their work provides a recent example of discovery’s unanticipated payoffs. Delving into them prodded the development of massive supercomputers. Solving their structure exposed the cause of degenerative brain diseases such as mad cow disease— work that won Horwich and Hartl a Lasker Award, second in prestige only to the Nobel Prize. Most surprisingly, the method created for solving the problem of protein folding spurred a transformation in scientific methods: citizen science. It was not a team of university researchers but a web game that cracked the problem of understanding the rules that govern how proteins fold. In the game Foldit, players come up with optimal shapes based on key protein features. Played by about a quarter of a million enthusiasts at home, motivated simply by achieving the highest posted scores, gamers delivered a groundbreaking, accurate three-dimensional image of an AIDS-causing monkey virus enzyme that had eluded scientists for 15 years. It took them all of 10 weeks. Most had no formal science background or advanced education.

Thanks Darrel

It seems to work fine. Will take a deeper look when I can. Off to Vietnam tomorrow.

cheers

BTW - current accuracy is not that bad - it is accurate to within (perhaps) 10 ms (anyway much better than a whole second) but it does not hold that accuracy - often it plays a little longer than it is meant to.

Hello again everyone

It has been a little while since I was able to do much with this great posting. I am trying to use it in a listening lesson. As I said in my posts of May 30/31, the JS provided finds the beginning of the segment to play easily while it "slides" at the end. i.e. it does not stop where it is meant to stop but extends a bit beyond (sometimes a lot). Unfortunately, this is now becoming a bit problematic. Are there any solutions that you know of? @Darrel was suggesting that it may have something to do with timeupdate. but, to tell you the truth, I do not know where to begin with this. Any clues/help would be great.

Thanks to everyone

Andrew

Thanks Darrel. Of course, once the accuracy is increased then that creates other possibilities. I am really really sorry that I do not have the JS skills/knowledge to even begin considering writing a solution at this stage.

BTW, I noticed that some browsers seem to be better than others. I have just upgraded to Win10 (not sure how good that is yet) but using Edge as a browser seems to be more accurate than using, say, Chrome or Firefox.

Thank you "team" for any insights.

undefined

To increase the accuracy we have to wrap the currentTime check in a setInterval method. See this GitHub post. I've wrestled with it a little bit but I need more time. I think there are others here (Math, Tim, Sergey & Wendy immediately come to mind) with JS skill who can probably figure this out much quicker than me.

This can be quite useful. Once we get this working we can use audio and video files much like a sprite sheet. Load one source file and play different parts (cue point to cue point) when needed.

Is there a way to do this without accessing the script?

Discussions have been disabled for this post