问题
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
event
listener (inside thesuccess
setting) 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
true
to our flag (previously initialized asfalse
)validate the
_canPlay
flag 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