MediaElement.js video player: Display time based on outside data? - javascript

I've got a MediaElement.js player with a video loaded into it, and I have a (database-driven) function which, given a time offset within that video, gives me the actual real-world time at which that part of the video represents.
I.e., if the video consists of 2 30-second clips, the first of which was recorded Tuesday morning, and the second of which was recorded Thursday evening, the function I've got will take an input of 25.2 and return a particular time on Tuesday morning, or it'll take an input of 44.6 and return a time on Thursday evening. And so on.
My question is: Is it possible for me to intercept the bits of MediaElement that are used to display time (e.g. the floating div that shows the time offset when you're hovering over the time rail, and so on), and have them use my function to determine what to display? Ideally, I'd like to do this without modifying the MEJS code itself, if possible.
Thanks!

+1 Good question, and yes - it is possible. What you want to do is create your own plugin/feature for the progress and currenttime etc.
Here's a simple example how you can create a plugin/feature for currenttime, that should get you started, make sure you prefix your featurename with "build":
(function($) {
MediaElementPlayer.prototype.buildmyfeature = function(player, controls, layers, media) {
var t = this;
$('<div class="mejs-time">'+
'<span class="mejs-currenttime">' + (player.options.alwaysShowHours ? '00:' : '')
+ (player.options.showTimecodeFrameCount? '00:00:00':'00:00')+ '</span>'+
'</div>')
// append it to the toolbar
.appendTo(controls);
//attach element we want to update to t (this) for easier access
t.currenttime = t.controls.find('.mejs-currenttime');
// add a timeupdate event
media.addEventListener('timeupdate',function() {
if(t.currenttime) {
//replace with whatever time you want to insert here
t.currenttime.html(mejs.Utility.secondsToTimeCode(t.media.currentTime, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25));
}
}, false);
}
})(jQuery);
And add your plugin/feature to the features: param, like so:
$('audio,video').mediaelementplayer({
features: ['playpause','myfeature','progress']
});
There is an example how to create a loop button (plugin/feature) from the official mediaelementjs site here:
http://mediaelementjs.com/examples/?name=loop
If you need some code to get started on the progress bar, just have a look at mep-feature-progress.js at git.

Related

Make GIF in Javascript from multiple images without any library

Is there any way to make GIFs in Javascript without any library? I've searched half the internet and found nothing.
Note to potential downvoters
I know that this is a low-quality question. However, I believe that the usual reasons for not answering have been invalidated. Seeing as it has been almost a month since it was asked, I doubt I'll be doing their homework as it would probably be past due for weeks at this point. And as for them not taking the time to research this myself, I'm fixing the problem at its source by teaching them how to research it.
Answer
Note that I'm answering this assuming that you know some Javascript, but not all of it, and that you want to learn how to write code that you might not yet know how to do. If you're just looking for the solution, then feel free to copy-paste it or whatever. But reading through this and understanding the process I used to tackle this problem, like how to think through it and look things up, will help you in the future. If you learn how to learn, you'll be a lot better off.
Now, first of all, we need a way to display images. I know from experience that there are two main methods to do this. One involves using the canvas element to draw the image; this is the more complicated method. Method 2 uses the image tag, <img>. I assume this is the method you want. If you didn't know how to draw an image using HTML and Javascript, a simple google search (here's another) can clear that up. (Actually, the second one mostly returns the canvas method-- but you probably knew about the image tag already anyways.)
Next we need a way to change what image is displayed. Well, that should be as simple as changing the thing that tells the image what to display in the first place. The top result from the first example search is a nice documentation page-- perfect. Reading through, I get to this part:
HTML Images Syntax
In HTML, images are defined with the tag.
The tag is empty, it contains attributes only, and does not have a closing tag.
The src attribute specifies the URL (web address) of the image:
<img src="url">
Well that looks like it's what controls what the image is. So we simply have to make a Javascript script that changes this property regularly. To do this right, we need a JS method that will wait for a specified amount of time. Searching "javascript wait" in Google, I see the second result is from the same source webpage that told me about images, so I'll go with that one. In the docs, I see this:
The setInterval() Method
The setInterval() method repeats a given function at every given time-interval.
window.setInterval(function, milliseconds);
The window.setInterval() method can be written without the window prefix.
The first parameter is the function to be executed.
The second parameter indicates the length of the time-interval between each execution.
(It even gives an example!)
This seems to be what we want. Using this method, I can make a simple code to change between two images every second (explanatory comments to the right, scroll to see them better):
function changePicture(){ //Make the function that will change the pictures
var picture = document.getElementById('picture1'); //Get the picture element from the HTML
if(picture.src == "https://vignette.wikia.nocookie.net/starpolar/images/9/96/Paul_blart.jpg/revision/latest?cb=20150419171412"){ //If it's the Paul Blart picture then:
picture.src = "https://i.ytimg.com/vi/A5KWYdrOXDk/movieposter.jpg"; //Set it to the Bee Movie
} else { //If it's not Paul Blart (and is therefore probably the Bee Movie image):
picture.src = "https://vignette.wikia.nocookie.net/starpolar/images/9/96/Paul_blart.jpg/revision/latest?cb=20150419171412"; //Set it to Paul Blart
}
}
setInterval(changePicture, 1000); //Use the new method we learned about to schedule our picture-changing function to happen once every second
<!--This is the image that we will change.-->
<img id="picture1" src="https://vignette.wikia.nocookie.net/starpolar/images/9/96/Paul_blart.jpg/revision/latest?cb=20150419171412"/>
Now, that's a good start-- we can change between 2 different totally definitely random images.
But we need more. We don't want to code in every new image manually; what we need is an array. It's hard to know that through a search, but if you've taken a primer course or learned some JS on your own you should be pretty familiar with arrays and would probably realize that they are a good option here. So we set up the array with all the images we want it to change between (scroll to the right to see it all):
var gifImages = ["https://vignette.wikia.nocookie.net/starpolar/images/9/96/Paul_blart.jpg/revision/latest?cb=20150419171412","https://i.ytimg.com/vi/A5KWYdrOXDk/movieposter.jpg","http://content.tv3.ie/content/images/0647/1_165781.jpg","https://upload.wikimedia.org/wikipedia/en/thumb/4/47/Spongebob-squarepants.svg/1200px-Spongebob-squarepants.svg.png","http://i0.kym-cdn.com/entries/icons/mobile/000/016/958/Dankkkk.jpg"];
Then we need to change our original function. It should cycle through this array of images; to do this, we'll need to make a variable to hold the position in the array.
var currentFrame = 0; //Call it a frame because we're making a gif and every image (so every array index) will be a frame
function changePicture(){
currentFrame++;
}
This should work for now, let's test it:
//Set up the array of frames
var gifImages = ["https://vignette.wikia.nocookie.net/starpolar/images/9/96/Paul_blart.jpg/revision/latest?cb=20150419171412","https://i.ytimg.com/vi/A5KWYdrOXDk/movieposter.jpg","http://content.tv3.ie/content/images/0647/1_165781.jpg","https://upload.wikimedia.org/wikipedia/en/thumb/4/47/Spongebob-squarepants.svg/1200px-Spongebob-squarepants.svg.png","http://i0.kym-cdn.com/entries/icons/mobile/000/016/958/Dankkkk.jpg"];
var currentFrame = 0; //Call it a frame because we're making a gif and every image (so every array index) will be a frame
function changePicture(){
document.getElementById("picture1").src = gifImages[currentFrame]; //Get the gif element and set its source to the current frame
currentFrame++; //Increase the current frame by 1
}
setInterval(changePicture,1000);
<!--This is the image that we will change.-->
<img id="picture1" src="https://vignette.wikia.nocookie.net/starpolar/images/9/96/Paul_blart.jpg/revision/latest?cb=20150419171412"/>
You should notice 2 things. The first is that the images have wildly different sizes and length/width ratios, resulting is the image changing size every time. The second thing you should notice is that when we run out of images, it doesn't loop back. Oops! (Side note: I actually made this mistake. Don't be discouraged by mistakes, we all make them!)
To remedy the first problem, we can look back to the HTML images documentation and see that there are two properties that can help us: width and height. These will lock the image into the specified dimensions. Frame sizes shouldn't be much of a problem with an actual gif, since the frames would probably all be the same size, but it doesn't hurt to be safe:
<img id="picture1" width="100px" height="100px" src="https://vignette.wikia.nocookie.net/starpolar/images/9/96/Paul_blart.jpg/revision/latest?cb=20150419171412"/>
The second problem is a bit harder. But looking through the code, we should be able to spot the bug fairly quickly. (Note: An experienced developer such as myself might be able to see a problem like this in a small, simple program almost instantly. Don't be discouraged if you can't; we all started somewhere and becoming a 1337 hax0r comes with time.)
If we look at how our program operates, we could say it works like this:
Loop forever:
Set the image to the current frame
Increase the frame
It becomes apparent that while we have a limited number of frames, we keep increasing the current one without going back down! Our progress through the gif would look like this (skipping to every 3rd frame and assuming 10 frames total):
|---------
---|------
------|---
---------|
---------- | <-- ???? oh no
This can be solved with a simple if statement that resets the current frame to 0 when we go past the end of our gif (line above is also shown for clarity):
currentFrame++; //Increase the current frame by 1
if(currentFrame >= gifImages.length){ //If we've gone past the end of our array of frames, then:
currentFrame = 0; //Reset back to frame 0
}
With those changes, our gif looks like this:
//Set up the array of frames
var gifImages = ["https://vignette.wikia.nocookie.net/starpolar/images/9/96/Paul_blart.jpg/revision/latest?cb=20150419171412","https://i.ytimg.com/vi/A5KWYdrOXDk/movieposter.jpg","http://content.tv3.ie/content/images/0647/1_165781.jpg","https://upload.wikimedia.org/wikipedia/en/thumb/4/47/Spongebob-squarepants.svg/1200px-Spongebob-squarepants.svg.png","http://i0.kym-cdn.com/entries/icons/mobile/000/016/958/Dankkkk.jpg"];
var currentFrame = 0; //Call it a frame because we're making a gif and every image (so every array index) will be a frame
function changePicture(){
document.getElementById("picture1").src = gifImages[currentFrame]; //Get the gif element and set its source to the current frame
currentFrame++; //Increase the current frame by 1
if(currentFrame >= gifImages.length){ //If we've gone past the end of our array of frames, then:
currentFrame = 0; //Reset back to frame 0
}
}
setInterval(changePicture,1000);
<!--This is the image that we will change.-->
<img id="picture1" width="100px" height="100px" src="https://vignette.wikia.nocookie.net/starpolar/images/9/96/Paul_blart.jpg/revision/latest?cb=20150419171412"/>
Now all we need to do is get the right frames into the array and speed it up! For a real gif, assuming this is a website you're making, the files will probably be named something like gif-frame-1, gif-frame-2, gif-frame-3, etc. Because of this, we can automate making the array, putting it into a for loop:
var gifImages = [];
for(var i=0;i<200;i++){ //Change 200 to the number of frames your gif has
gifImages[i] = "pictures/gif-frame-"+i+".png";
}
That code probably won't work with your website right away-- you have to change around the names of the images and number of frames and things-- but it should help you. If you specify where these pictures are, how they're named, how many there are, etc. then I could help you more, but I don't have enough information to write that part. Also note that this can be sped up about 50 times faster than it's going at the moment, but it looks weird without real frames to be used. For now, we can consider our final code to be:
//Set up the array of frames
var gifImages = ["https://vignette.wikia.nocookie.net/starpolar/images/9/96/Paul_blart.jpg/revision/latest?cb=20150419171412","https://i.ytimg.com/vi/A5KWYdrOXDk/movieposter.jpg","http://content.tv3.ie/content/images/0647/1_165781.jpg","https://upload.wikimedia.org/wikipedia/en/thumb/4/47/Spongebob-squarepants.svg/1200px-Spongebob-squarepants.svg.png","http://i0.kym-cdn.com/entries/icons/mobile/000/016/958/Dankkkk.jpg"];
var currentFrame = 0; //Call it a frame because we're making a gif and every image (so every array index) will be a frame
function changePicture(){
document.getElementById("picture1").src = gifImages[currentFrame]; //Get the gif element and set its source to the current frame
currentFrame++; //Increase the current frame by 1
if(currentFrame >= gifImages.length){ //If we've gone past the end of our array of frames, then:
currentFrame = 0; //Reset back to frame 0
}
}
setInterval(changePicture,100);
<!--This is the image that we will change.-->
<img id="picture1" width="100px" height="100px" src="https://vignette.wikia.nocookie.net/starpolar/images/9/96/Paul_blart.jpg/revision/latest?cb=20150419171412"/>
It's possible to touch it up (for example, you could move the function inside the setInterval itself) but this should work fine.
I hope this answer has helped you to learn how to figure these things out!
I ended up just writing a script to replace the image in a div every second. It's not technically a gif, but it works very similarly.
eval('var frame' + word + ' = 0;');
var bigFrame = 0;
setInterval(function(){ //everysecond
var noSpaces = input.replace(/\s/g, '');
var cLetter = noSpaces[bigFrame];
var thisSource = 'media/signs/alphabet/' + cLetter + '.jpeg';
$('#video').attr("src", thisSource);
$('#video').attr("alt", thisSource);
$('#video').attr("height", "350");
if(bigFrame + 1 >= noSpaces.length){
bigFrame = 0;
} else{
bigFrame = bigFrame +1;
}
for(word = 0; word < wordList.length; word ++){ //for every word
var currentFrame = eval('frame' + word);
currentWord = wordList[word];
currentWord = currentWord.toLowerCase();
console.log('current word is ' + currentWord);
var letterList = currentWord.split('');
var currentLetter = letterList[currentFrame];
var currentSource = 'media/signs/alphabet/' + currentLetter + '.jpeg';
var currentImage = "#" + eval('"image' + word + '"');
$(currentImage).attr("src", currentSource);
$(currentImage).attr("alt", currentSource);
$(currentImage).attr("height", "200");
if(currentFrame + 1 >= letterList.length){
eval('frame' + word + ' = 0');
} else{
eval('frame' + word + ' = currentFrame + 1;');
}
}
}, 1000);
I don't know if this is helpful, or even understandable, but it might help someone. Also, I haven't bothered to edit the code, so there are definitely bits that won't make sense and weird variable names.

live times in default receiver

I have a chromecast sender application that is using the default receiver.
I am passing a live MPEG-DASH stream and all is working.
I have one concern the time that is displayed in the seek bar is incorrect it looks like a malformation of an epoch timestamp.
example
416797:35:52
is there anything I can do to make this timestamp work?
I am currently getting an epoch timestamp back as currentTime from the remotePlayer
I have bound the RemotePlayerController like the following
this._remotePlayer = new cast.framework.RemotePlayer();
this._remoteController = new cast.framework.RemotePlayerController(this._remotePlayer);
This is because the duration for live is infinity. I had the same problem, I had to manually calculate progress to show it correctly, although you can't use it to seek to a position for live contents.
If you bind with RemotePlayerController it should handle this for you, this would basically disable seek bar and show you default -- -- start and end time.

Settimeout not working when window loses focus

I have a simple JavaScript chronograph that displays on a form field called "d2", it is used to check how long someone takes on doing a specific task:
var milisec=0
var seconds=0
var complemento1=""
document.form1.d2.value='00:00:00'
function display(){
if (milisec>=9){
milisec=0
seconds+=1
}
else{
milisec+=1
}
complemento1=complemento2=complemento3="";
if ((seconds%60)<10) complemento1="0";
if ((Math.floor(seconds/60)%60)<10) complemento2="0";
if ((Math.floor(seconds/3600))<10) complemento3="0";
document.form1.d2.value=complemento3+Math.floor(seconds/3600)+":"+complemento2+(Math.floor(seconds/60)%60)+":"+complemento1+(seconds%60)
setTimeout("display()",100)
}
The problem is that when the person opens a new tab / uses another program the timer stops, and then resumes when the window is focused again (Using Chrome). It has the weirdest behavior, because sometimes it works, sometimes it doesn't.
I saw many posts that needed a script to stop when not on focus, I want the exact opposite and searched for over an hour with no luck. Your help is greatly appreciated!
JavaScript timeouts are not guaranteed be executed at a specific time. For example if the thread is busy with something else at the time when the timer finishes, it will first finish what it is doing and then execute your timer.
Also your function does not take into account the time spend inside the display function, so a little delay will be added for each millisecond.
The correct way to implement a timer is using the system time.
So something like:
//Call at the beggining to save the start time
var start_time = new Date()
// Compute seconds (does not matter when/how often you call it.)
var milliseconds_since_start = new Date().valueOf() - start_time
The Date object can also format this period as a clock for you:
var m = new Date(milliseconds_since_start)
m.getMinutes()+":"+m.getSeconds()

How do I get the current position (frame) of a movie clip in EaselJS?

I have a MovieClip that fades in and then fades out. I'd like to find the half way mark in this movie clip and pause it. However in EaselJS I cannot find any way to get the movie clip's current frame position. Is this possible?
I'd like to do something like the following:
canvas = document.getElementById("introCanvas");
exportRoot = new lib.MyMovieClip();
exportRoot.onTick = function () {
//get the mc's length in frames
//get the current frame position
//if current frame postion == mc's lenght / 2
//then pause movie clip
};
Can anyone provide me with some suggestions or ideas for how I might accomplish the above?
Thanks!
After reading through the documentation, it seems that a TweenJS Timeline is automatically allocated to manage the change in the animation, it doesn't look like there are any actual frames like we see in flash.
If you look at the docs for TweenJS Timeline its possible you could use the duration property, as the docs state:
Read-only property specifying the total duration of this timeline in milliseconds (or ticks if useTicks is true). This value is usually automatically updated as you modify the timeline. See updateDuration for more information.
So if you get the duration and divide by 2, or multiply by 0.5 ;) then you could find out the middle point of your animation. Try using this in your onTick method to see if it works.
I always do this...
(movieclip.timeline.position)%movieclip.timeline.duration
Or another way...
var tl = movieclip.timeline;
var d = timeline.duration;
(tl.position)%d
You have to get the movieclip's timeline's position & duration, and add a %. This will get the current frame of the movieclip.

JW FLV Player Javascript event

When a user triggers a Javascript action, I want the JW FLV to seek back 5 seconds from the current location. I know how to send events using player.sendEvent('SEEK',seconds). But I dont know how many seconds to pass as JS does not know the current location. Can someone please help?
http://developer.longtailvideo.com/trac/wiki/FlashEvents#Viewevents.
1)You can get the current location as :
getPosition(): Returns the current playback position in seconds, as a number.
2)And then seek to required position as:
seek(position):Jump to the specified position within the currently playing item. Parameters: position:Number: Requested position in seconds.
Also refer this
Actually you can get the current location with javascript. Here's how:
player.addModelListener('TIME', 'timeMonitor');
var time = null;
function timeMonitor(obj) {
time = obj.position;
}
The time variable constantly updates, so then just do something like:
function userTriggeredJsAction(){
var newTime = time - 5;
player.sendEvent('SEEK',newTime);
}

Categories