UPDATE: Mediaelement.js has been updated to support responsive layouts.

It should be a matter of adding the following to your html:

<video width="640" height="360" style="width: 100%; height: 100%;" id="player1" preload="none">

        <!-- Pseudo HTML5 -->
        <source type="video/youtube" src="http://www.youtube.com/watch?v=nOEw9iiopwI" />
</video>  

NOTE: The below solution is outdated.

I am getting close to completing a project that involves a lot of video. One major requirement was for the video to re-size dynamically to various screen sizes. This would probably have been a great project for flash. But, 1. I was determined to make it work with HTML5, and 2, it needed to work on iOS devices.

I decided to use the awesome and open-source mediaelement.js project by John Dyer. The projects fallback flash and silverlight players were right up my alley for this project. Why? The main reason is that they still utilize html elements for play controls. This was a big win for me.

Getting to the point: resizing video was NOT easy. It took me a bit of figuring out how medialement works by looking through the source-code (beauty of open-source). When I finally figured out how the element is built I got to work.

I had two scenarios to keep in mind when working with the resizing:

The media element object when built natively (html5)
The media element object when built using plugin (flash or silverlight)
They both returned different results, adding to the complication.

I utilized two additional libraries that helped support the project: head.js and jQuery.

I used those classes to determine the approximate size I wanted to videos to grow or shrink to. Yes, I used fixed dimensions (WxH)–mediaelement.js currently has no support for percentages.

One of head.js’ features, is that appends special classes to the html element on the page that help determine what the current window size is. I used those classes to determine the approximate size I wanted to videos to grow or shrink to. Yes, I used fixed dimensions (WxH)–mediaelement.js currently has no support for percentages.

Here are the default dimensions head.js works with: 320, 480, 640, 768, 800, 1024, 1280, 1440, 1680, 1920

You can add your own through the api. If the current window is sized at approximately 1024×768, the html element would contain the following class: lt-1024

Mega helpful.

Okay, let’s get to the code:

First thing I needed to do was build the mediaelement object. Let’s assume we have a video element on the page with the following id: video-player. The video element is wrapped within a div tag width the id: #video-wrap.

This element was sized through the stylesheet’s headjs classes (lt-1024, lt-1280, etc.). I used that element’s width and height to determine what the default width and height settings should be for the media element.

var $videoWrap = $("#video-wrap"), // caching object  
    default_ht = $videoWrap.height(), // get current height
    default_wt = $videoWrap.width(), // get current width

    $me = $("#video-player").mediaelementplayer({

        videoHeight : default_ht, //set default height

        videoWidth : default_wt, //set default width

        defaultVideoWidth : default_wt, //another option for default width

        defaultVideoHeight : default_ht, //another option for default height

        success : function(me,domObj){ //phew we are ready to go
...

This first part is pretty straight forward. I initially get the video wrap object and cache it. I then utilize the object to set the current width and height I want the media element object to render. I use the $me variable for caching purposes, however, when mediaelement rendered the plugin video player (flash or silverlight) things got a bit weird with the object.

...
  success : function(me,domObj){ //phew we are ready to go

    var player = me.player || domObj.player, //me does not always have the player, strange.

        //Okay, so if we have an $MediaElement object, we use it!
        //Otherwise default to the mediaElement object passed into the function.
        meElem = ($me) ? $me[0] : me, //sometimes $me is undefined, strange.

        isNative = (player.media.pluginType == "native"); //Key to resizing plugin (flash or silverlight)
   }
...

Okay, this looks bad. I went through hell to figure this crap out.

Whenever mediaelement built the flash player, it didn’t return the player object along with the mediaelement object, however the domObj did contain the player object (not sure if this is a bug, have to parse through the code some more). Also, $me would be empty when mediaelement rendered native video. I needed to know whether or not the player was in native mode (html5) to determine how to resize the video.

The following contains the function I utilized to resize the video:

...
                      isNative = (player.media.pluginType == "native"), //Key to resizing plugin (flash or silverlight)

                      $html = $("html"), //Grab the html object and cache it

                      width, 

                      height, 

                      prevWidth, //used to determine if the size has actually changed

                      rTimer; //We will be using this during the window.resize handler

                      function resize_video(){
                          if($html.hasClass("lt-1024")){//1024w
                             width = 658;
                             height = 372;
                           }else if($html.hasClass("lt-1280")){//1280w
                             width = 848;
                             height = 480;
                           }else if($html.hasClass("lt-1440")){//1440w
                             width = 1056;
                             height = 594;
                           }else{//1920w
                            width = 1404;
                            height= 794;
                           }
                     }//end function resize_video
...

Great. The functionality here is simple. I utilize the jQuery.hasClass function on the html element. Notice that I check for the sizes from least to greatest because head.js always appends the classes that the window size is currently less than. Are you confused? Let me try to articulate with an example:

Let’s account for a screen of 1024×768. 1024 is less than say 1280, 1440 and 1920. This means that lt-1440, lt-1280 and lt-1920 will always be appended to the html elements class attribute and will therefore always exist.

If we stared at a window size that’s larger than 1440, lt-1024 and lt-1440 would be removed from the html class attribute.

Hope that made sense. Onward to resizing.

MediaElementjs has some supporting function calls, both on the player object and the mediaelement object.

mejs.player.setPlayerSize(w,h) – sets the player size and video size

mejs.player.setControlSize() – resizes the control dimensions appropriate to the video size.

mejs.setVideoSize(w,h) – sets the actual video width and height, not the video element.

We’re going to use these functions to help with the resizing effort.

...
    function resize_video(){
    ... //removed for brevity
    }

    if( prevWidth != width ) { //has the width changed from the previous width?

       $videoWrap.width(width); //Let's set the wraps width first.
       meElem.player.setPlayerSize(width,height); //call mejs.player.setPlayerSize to reset video width and height
       meElem.player.setControlsSize(); // now let's reset the controls appropriate to the new width and height

       if(!isNative){ // If this is a plugin (flash or silverlight) we have to do some more work
           meElem.player.options.videoWidth = width; //I did this for safety measure, not sure if it's necessary
           meElem.player.options.videoHeight = height; //I did this for safety measure, not sure it's necessary
           me.setVideoSize(width,height);  //this function is always returned with the me object bassed by the success handler.

       }// end if not:isNative

    }//end width check

    prevWidth = width; //used to detect whether or not we need to resize video
}//end function resize_video

       //Now we add the window.resize handler
      $(window).resize(function() {
        clearTimeout(rTimer); //for some resize is executed twice, so we use this "hack" to avoid that.
        rTimer = setTimeout(resize_video,500); //keeps the event from being called twice
       });
    }//end of success property
}); //end mediaelmentplayer

Hokay! Simple, right? Well, I’m not that happy with it either. As I’ve mentioned before, I had to bounce back and forth between the different objects when either in native or plugin mode.

This is what worked for me, I don’t know if it’s a matter of bugs or that I’m simply not using the object correctly. I’m going to continue researching the mediaelementjs source code and hope to determine a better solution soon.