3

I have 15 videos I need to show. Instead of creating 15 pages with each html5 video embed targeting a different video, I rather have just one page and via the URL tell the player what to load. This way I can just have 15 custom links but just one player and one html page. Need this to be supported by all browsers, iOS and Android.

Example:

  • www.mysite.com/videoplayer.html?v=mymovie

  • www.mysite.com/videoplayer.html?v=mymovie&t=13.6 - this should jump to the player playhead to a point in time.

videoplayer.html

<script>
    function getQueryVariable(variable) {
        var query = window.location.search.substring(1);
        var vars = query.split("&");
        for (var i=0;i<vars.length;i++) {
            var pair = vars[i].split("=");
            if (pair[0] == variable) {
                return pair[1];
            }
        }
        alert('Query Variable ' + variable + ' not found');
    }
    var videoFile = getQueryVariable("v");
    var videoElement = document.getElementById("mp4source");
    videoElement.setAttribute("source", videoFile + ".mp4"); 
</script>

<video id="mp4" controls="controls">
    <source id="mp4source" src="../videos/jude.mp4" type="video/mp4"  />
</video>

Main.html

<div id="menubar1">
    <a href="videoplayer.html?v=mymovie">Play Movie</a>
    <a href="videoPlayer.html?v=mymovie&t=14.5">Chapter 2</a>
</div>

I'm a beginner to javascript, please be specific in your answers.

Thanks.

Artur Filipiak
  • 9,027
  • 4
  • 30
  • 56
Thanu
  • 41
  • 1
  • 5

1 Answers1

1

IMHO DOM Manipulation on the main page would be a better solution, but here it is, at least for modern browsers, from your example code.

  • I changed your getQueryVariable in order to be able to use it as a boolean.

  • To change the current playback time, you will have to wait for the video's metadata to be loaded, then you can set the currentTime property (in seconds).

  • In order to comply the "all browsers" support you will have to transcode your videos to ogg vorbis format, then add a source pointing to this video file. This will do for major modern browsers.

  • For older browsers, you will have to add a fallback (e.g. flash player or java applet).

  • For the "jumping playhead" in ios, you have some tricks to do : look at this question , personally I used this code which seems to work on my ipad ios 8. Note that it will lack of autoplay if you decide to add it in the video tag.

  • Now, you can't get video for all browsers (e.g text-based browsers).

Live Example


Play Movie                Chapter 2


Commented videoplayer.html

<video id="video" controls="controls">
    <source id="mp4source" src="" type="video/mp4" />
    <source id="oggSource" src="" type="video/ogg" />
</video>

<script>
    function getQueryVariable(variable) {
        var query = window.location.search.substring(1);
        var vars = query.split("&");
        for (var i = 0; i < vars.length; i++) {
            var pair = vars[i].split("=");
            if (pair[0] == variable) {
                return pair[1];
            }
        }
        //returning false will help knowing if that variable exists
        return false;
    }

    function loadVideo() {
        var videoFile = getQueryVariable("v");

        //if v is not set
        if (!videoFile) {
            alert('please choose a video file, \n maybe you came here by accident?');
            //no need to go further
            return;
        }

        //Select the sources for the mp4 and the ogg version
        var mp4source = document.getElementById("mp4source");
        mp4source.setAttribute("src", videoFile + ".mp4");
        var oggSource = document.getElementById("oggSource");
        oggSource.setAttribute("src", videoFile + ".ogv");

        //if t is set   
        if (getQueryVariable("t")) {
            //userAgent can be overridden but it may be the best way to detect ios devices
            var iOS = navigator.userAgent.match(/(iPad|iPhone|iPod)/) !== null;
            if (iOS) {
                iOSLoadSeek();
            } else {
                //wait for the video meta data to be loaded
                document.getElementById('video').addEventListener('loadedmetadata', function() {
                    //then change the time position
                    this.currentTime = getQueryVariable("t");
                })
            }
        }
    }

    //ios load seek workaround, edited from https://gist.github.com/millermedeiros/891886
    function iOSLoadSeek() {
        var vid = document.getElementById('video');
        if (vid.readyState !== 4) { //HAVE_ENOUGH_DATA
            vid.addEventListener('canplaythrough', iosCanPlay, false);
            vid.addEventListener('load', iosCanPlay, false); //add load event as well to avoid errors, sometimes 'canplaythrough' won't dispatch.
            vid.addEventListener('play', iosCanPlay, false); //Actually play event seems to be faster
            vid.play();
            setTimeout(function() {
                vid.pause(); //block play so it buffers before playing
            }, 10); //it needs to be after a delay otherwise it doesn't work properly.
        }
    }
    //called when one of the three events fires
    function iosCanPlay() {
        //remove all the event listeners
        this.removeEventListener('canplaythrough', iosCanPlay, false);
        this.removeEventListener('load', iosCanPlay, false);
        this.removeEventListener('play', iosCanPlay, false);
        //finally seek the desired position
        this.currentTime = getQueryVariable("t");
        this.play();
    }

    //When the page is loaded, execute
    window.onload = loadVideo();
</script>
Community
  • 1
  • 1
Kaiido
  • 123,334
  • 13
  • 219
  • 285
  • great work @Kaiido It works on desktop with no problem. Iam having a hard time on iphones. Is the code only looking for ogg source on iso devices? – Thanu Feb 11 '15 at 02:40
  • @Thanu no, the workaround only has access to the `video` element, not its sources. Does the problem occurs when you don't set the `t` parameter? I can't help you too much as I don't have any iphone device, but it does work on my ipad and on iOS Simulator – Kaiido Feb 11 '15 at 02:57
  • its without the `t` parameter. I just tested on ipad still same result. Its going to the right page but its not loading the video file. – Thanu Feb 11 '15 at 03:06
  • which version of iOS? – Kaiido Feb 11 '15 at 03:07
  • its on 8.1.3 and my iPhone is on 8.1 – Thanu Feb 11 '15 at 03:12
  • and are you using the [jsbin](http://jsbin.com/zefedu/1/?v=trailer) link or your own video file? – Kaiido Feb 11 '15 at 03:13
  • my own video files on the same directory as the html files. – Thanu Feb 11 '15 at 03:17
  • If it does work on desktop, the problem might be with video encoding. Could you give a link to your test page? I'll have a look on it (maybe later cause it's 4am in here) – Kaiido Feb 11 '15 at 03:22
  • np @Kaiido when you get a chance. My files are only for local use, its not going to be online. I can share a dropbox link with you or i will upload it to a ftp tomorrow for you. – Thanu Feb 11 '15 at 03:32
  • @Thanu, I just tried over the local network and it does work. Must come from your mp4 files, it might not have been encoded with the right settings. Have a look at [this answer](http://stackoverflow.com/a/13402284/3702797), and to be sure, download the examples video files [here](http://media.w3.org/2010/05/sintel/trailer.mp4) and [here](http://media.w3.org/2010/05/sintel/trailer.ogv) and try loading them with the script. – Kaiido Feb 12 '15 at 02:04