问题
As is shown here: How do I get mediaelement.js player state (paused, volume, etc.)?
you can access MediaElement attributes by simply adding 'media' to the instance and then you can get the api described here:http://mediaelementjs.com/#api.
But how do I make it so that the 'media' wont be necessary, making the MediaElement api exactly(almost) the same as that of the html5 video?
回答1:
You can access API methods (as HTML5 video) but not properties or events, which still need to refer to the underlying media element and just after MEJS has been successfully loaded.
Notice that setter properties can be accessed referring either the underlying media element (inside the success setting) or the MEJS player.
So, to illustrate :
var myPlayer = new MediaElementPlayer('.player_1', {
success: function (mediaElement) {
// properties need to refer the MEJS underlaying element
console.log(mediaElement.paused); // return true
console.log(mediaElement.muted); // returns false
// same for events
mediaElement.addEventListener('playing', function () {
console.log("event triggered after play method");
}, false);
mediaElement.addEventListener('pause', function () {
// set time at 90 seconds and unmute if player is paused
// but wait 3 seconds before doing that
// notice the previous time set (145 seconds)
setTimeout(function () {
// setters can refer MEJS underlaying element
mediaElement.setCurrentTime(90);
mediaElement.setMuted(false);
}, 3000);
}, false);
}
});
// methods can refer the MEJS player
myPlayer.play();
// but not properties
console.log("paused? " + myPlayer.paused); // returns undefined
console.log("muted? " + myPlayer.muted); // returns undefined
// pauses, set time and mute after 5 seconds of playing
setTimeout(function () {
myPlayer.pause(); // method
// setters can also refer the MEJS player
myPlayer.setCurrentTime(145);
myPlayer.setMuted(true);
}, 5000);
See JSFIDDLE
EDIT
OP commented :
... could I somehow have all those elements and properties refer up by one 'element'
Interesting. Reviewing another code I wrote I think it would be possible to declare, let's call it an universal element, to which you can apply any method, property or event, from anywhere in your code.
The only thing you would need to do is to declare your one element as global :
var uElement; // the universal element
Then set the value withing the success setting to override the underlying media element like :
success: function (mediaElement) {
uElement = mediaElement;
....
}
From there, you could now apply any method, property or event to that single uElement object only. So using the previous example :
var uElement; // the universal element
var myPlayer = new MediaElementPlayer('.player_1', {
success: function (mediaElement) {
// set the universal element
uElement = mediaElement;
// properties for universal element
console.log(uElement.paused); // OK return true
console.log(uElement.muted); // OK returns false
// set events for universal element
uElement.addEventListener('playing', function () {
console.log("event triggered after play method");
}, false);
uElement.addEventListener('pause', function () {
// set time at 90 seconds and unmute if player is paused
// but wait 3 seconds before doing that
// notice the previous time set (145 seconds)
setTimeout(function () {
// setters for universal element
uElement.setCurrentTime(90); // OK
uElement.setMuted(false); // OK
}, 3000);
}, false);
}
});
// method for universal element
uElement.play(); // OK
// properties for universal element
console.log("paused? " + uElement.paused); // OK returns false
console.log("muted? " + uElement.muted); // OK returns false
// pauses, set time and mute after 5 seconds of playing
setTimeout(function () {
uElement.pause(); // OK method for universal element
// setters for universal element
uElement.setCurrentTime(145); // OK
uElement.setMuted(true); // OK
}, 5000);
See forked JSFIDDLE
IMPORTANT
In the example above we used audio, however videos are other type of animal.
First, you need to bear in mind that you may not able to refer to the uElement object, unless the video has been completely loaded AND is ready to play. Applying a method (like .play() ) to the uElement before the video is ready may trow a js error and malfunction.
For instance, in our previous example, if we call the uElement.play() method (for videos) just right after the MEJS initialization, it will trigger the js error uElement is undefined. This is because the method was called before the uElement initialization inside the success setting.
If we want to autoplay the video (uElement.play()) just after it's loaded (or call any other method applied to the uElement as a matter of fact) we need to do 2 things to workaround the situation described above:
add an
eventlistener (inside thesuccesssetting) that informs us when the video is ready to play:uElement.addEventListener('canplay', function () { _canPlay = true; }, false);if the video is ready to play, then we set
trueto our flag (previously initialized asfalse)validate the
_canPlayflag inside asetInterval()function until istrue, then playvar readyToPlay = setInterval(function () { console.log("not ready yet"); if ( _canPlay ) { console.log("Now it's ready, so play"); uElement.play(); clearInterval(readyToPlay); }; }, 100);
This workaround can be used for youtube videos as well as self-hosted (mp4) videos.
See last JSFIDDLE
LAST NOTE : if you have several videos and you want to apply different methods, properties or events to each of them, then you have to initialize them individually and create a different uElement for each of them
来源:https://stackoverflow.com/questions/24146812/make-mediaelement-same-as-html5-video