1

I'm dynamically inserting an html5 video tag with unknown dimensions onto a page. I'm getting the dimensions with the loadedmetadata event which works like a charm on all browsers.

However, from what I understand this event won't fire until the user touches the video on the ipad. This makes it really difficult to get the actual dimensions of the video which I need in order to size it's container.

Is there

  1. Another way to get dimensions of a video which would work in this scenario? or
  2. A way to trigger the loadedmetaevent?

Thanks!

CODE:

 var src=fullPathToVideoWithoutExtension;

 // DETECT WHICH FILE FORMAT TO USE
 if($.support.browser.h264||$.support.mpeg4){
     var supportedSRC=supportedSRC+'<source src="'+src+'.mp4" type="video/mp4">';
  };

  if($.support.browser.ogg){
     var supportedSRC=supportedSRC+'<source src="'+src+'.ogv" type="video/ogg">';
  };

  // SETUP THE VIDEO ELEMENT
  var $Video=$('<video id="Box_Video" controls>'+supportedSRC+'</video>');

  $Video[0].src=src+'.mp4';
  $Video[0].addEventListener('loadedmetadata',function(){
     var width=this.videoWidth;
         height=this.videoHeight;   
   },false)

Here's a fiddle: http://jsfiddle.net/Fv4XG/1/

Notice that in the browser it will immediately alert the video dimensions, but on the ipad you have to wait until there is user interaction before it pulls the dimensions. How can I get the dimensions when the video is inserted into the DOM like in all other browsers?

net.uk.sweet
  • 12,444
  • 2
  • 24
  • 42
Aaron
  • 2,482
  • 1
  • 26
  • 56
  • You can't autoplay video on the iPad but I think you could hide the video element and implement a button to start it playing, then reveal the element after the metadata event is received. – net.uk.sweet May 10 '13 at 00:14
  • Yeah, I'm not trying to autoplay it, but understand that it doesn't pull the video info until it starts playing. The container it is in starts out hidden, the I need to resize it to the video dimensions and show the container. Just trying to find a way to get the dimensions of the video first. – Aaron May 10 '13 at 00:20
  • Can you make a http://jsfiddle.net ? I'm guessing a bit here, but playing the video and immediately pausing it may cause the event you need to trigger. You can then resize the container, reveal it, and start playing the video again. – net.uk.sweet May 10 '13 at 00:25
  • There shouldn't be any user interaction. I've also tried setting a touchstart event that trying to trigger that in hopes that it would fire the loadedmetadata event, but no luck there. I think Apple has locked out some triggering in this situation – Aaron May 10 '13 at 00:28
  • I think that's the point - there has to be user interaction. See this http://stackoverflow.com/questions/12496144/can-you-autoplay-html5-videos-on-the-ipad . The user has to opt-in to playing back the video. You have to find a way to do that which best fits with the requirements of whatever you're building. – net.uk.sweet May 10 '13 at 00:30
  • So, how would I load a video into a modal window similar to loading an image without having to hard code all of the video dimensions. The code I have now works 100% cross browser except for the ipad. I'll post the code I have in the question. – Aaron May 10 '13 at 00:33
  • The code you've posted isn't complete is it? If you create a simple demo of the code you have working on jsfiddle, it will be easier to help you. – net.uk.sweet May 10 '13 at 00:53
  • Added a fiddle on there – Aaron May 10 '13 at 01:01
  • It's past my bedtime now. Will have a look tomorrow if noone else has helped before then. – net.uk.sweet May 10 '13 at 01:19
  • The following is where I got to. It doesn't work and I can't debug it now, but I think you might be able to get it to work using that approach. http://jsfiddle.net/5aHhS/5/ – net.uk.sweet May 10 '13 at 01:26
  • 1
    The fiddle you posted still requires user interaction. Just looking for a way to mimic pulling dimensions before video interaction like all other browsers can do. – Aaron May 10 '13 at 17:00
  • I don't think it can be done. See my answer. – net.uk.sweet May 10 '13 at 18:15

1 Answers1

2

I don't believe there is a way to get the loadedmetadata event (which you need in order to read the dimensions of the dynamically loaded video) to fire on iOS without user interaction. For reasons explained in a fairly detailed answer here, Apple disabled autoplay from iOS version 6.01. I'll include the quote from the Apple documentation here.

"Apple has made the decision to disable the automatic playing of video on iOS devices, through both script and attribute implementations.

In Safari, on iOS (for all devices, including iPad), where the user may be on a cellular network and be charged per data unit, preload and auto-play are disabled. No data is loaded until the user initiates it." - Apple documentation.

I think the only solution available to you, therefore, is to hide the video initially and display a button which prompts the video to load when clicked. This will cause the loadedmetadata event to fire, at which point you can set the size of your container based on the video dimensions, start playing the video, and finally reveal it.

I did the following in plain old JavaScript for ease. It hopefully demonstrates both the issue and the workaround I'm suggesting (jsfiddle here):

    var video = document.getElementById('video');
    video.load(); // In desktop browser this will cause loadedmetadata event to fire

    // Hide the video initially
    video.style.visibility = 'hidden';

    document.getElementById('button').addEventListener('click', function() {
        video.load(); // on iOS we need user interaction to prompt load
    });

    video.addEventListener('loadedmetadata', function() {

        // console log is much less intrusive than window.alert
        // you can see the log statements in Safari developer tools if you plug in a device
        window.alert(this.videoWidth);
        window.alert(this.videoHeight);

        // Now we can set container size, reveal and play
        video.width = this.videoWidth;
        video.height = this.videoHeight;

        video.play();
        video.style.visibility = 'visible';
    }); 

I've found this page from the W3 to be useful in the past for playing around with the HTML5 video API.

Community
  • 1
  • 1
net.uk.sweet
  • 12,444
  • 2
  • 24
  • 42
  • Thank you, yeah this is the path I started heading down earlier today. It's understandable why Apple has put this in place, however it would have been much more ideal if they pulled the meta of the video down and allowed for this. I've even tried adding the video to the page to see if Safari was smart enough to autosize it, but it just adds it with incorrect dimensions. – Aaron May 10 '13 at 18:16
  • Yeah I think it's a poor decision from Apple and I don't really agree with their reasoning. Why not let the user decide whether they want to trash their data plan watching my video? – net.uk.sweet May 10 '13 at 18:20