Empezar la reproducción en un punto concreto con HTML 5 video

Una funcionalidad bastante útil que Youtube ya implementó hace tiempo es la posibilidad de compartir un enlace de un vídeo con el momento exacto donde queremos que comience a reproducirse, en lugar de tener que ver el vídeo entero para llegar al punto exacto. Otro uso también interesante es poder guardar el momento donde nos quedamos para continuar más tarde.
En Youtube hubo un momento que aparecía de manera automática, pero tiempo después optaron por dejar esta característica como opcional en el apartado de Compartir:

Start at Youtube

En este post me gustaría mostrar cómo sería posible gestionar esta funcionalidad utilizando la etiqueta video de HTML 5.

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>

    <video id="myVideo" controls autoplay>
        <source src="[YOUR_VIDEO_SOURCE]" />
    </video>
    <div>
        <input id="btnStartAt" type="button" value="Start At" />
        <input id="btnClearMark" type="button" value="Clean mark" />
    </div>
    <script>
        (function () {

            function Id(elem) {
                return document.getElementById(elem);
            }

            function getParams(values) {

                var vars = [];

                for (var i = 0; i < values.length; i++) {
                    var position = values[i].indexOf('=');

                    if (position > 0) {
                        var key = values[i].substring(0, position),
                            value = values[i].substring(position + 1);

                        vars[key] = value;
                    }
                }

                return vars;
            }

            function getFormat(seconds) {

                var date = new Date(seconds * 1000);
                var hh = date.getUTCHours();
                var mm = date.getUTCMinutes();
                var ss = date.getSeconds();

                if (hh > 12) { hh = hh - 12; }

                if (hh < 10) { hh = "0" + hh; }
                if (mm < 10) { mm = "0" + mm; }
                if (ss < 10) { ss = "0" + ss; }

                return hh + "h" + mm + "m" + ss + "s";
            }

            var query = location.search.substring(1),
                params = getParams(query.split('&'));

            var time = params["t"],
            video = Id("myVideo");

            video.onprogress = function (e) {

                btnStartAt.value = "Start at: " + getFormat(video.currentTime);
            };

            Id("btnStartAt").addEventListener("click", function () {

                location.search = "?t=" + getFormat(video.currentTime);
            });

            Id("btnClearMark").addEventListener("click", function () {

                location.search = "";

            });

            if (time) {

                var hoursPosition = time.indexOf('h'),
                    minutesPosition = time.indexOf('m'),
                    secondsPosition = time.indexOf('s');

                var hours = parseInt(time.substring(0, hoursPosition)) * 3600,
                    min = parseInt(time.substring(hoursPosition + 1, minutesPosition)) * 60,
                    sec = parseInt(time.substring(minutesPosition + 1, secondsPosition));

                if (!isNaN(hours))
                    sec += hours;
                if (!isNaN(min))
                    sec += min;

                video.play();

                var setted = false;

                video.oncanplay = function () {
                    if (!setted)
                        video.currentTime = sec;
                };
            }

        })();
    </script>
</body>
</html>

Lo primero que tenemos es una etiqueta vídeo de HTML 5 con la fuente que queremos reproducir. En este ejemplo he utilizado un botón para modificar la URL de la página, indicando las horas, minutos y segundos con el siguiente formato: 00h00m00s (la función getFormat se encarga de pasar los segundos a dicho formato). Cada vez que la página se carga, recuperamos el query string de location.search y utilizamos getParams para montar un array con los valores que se han pasado como parámetro, con el objetivo de encontrar el llamado t que contiene el momento exacto donde debe comenzar la reproducción. Además se han capturado el evento progress que muestra el valor que tendría si iniciáramos el vídeo en ese momento y el evento click del botón que hace que se modifique el valor de location.search para indicar dónde queremos que empiece el vídeo a partir de ahora. También se ha añadido un botón para eliminar la marca y que vuelva a comenzar desde el principio.

Si ya tenemos una marca de tiempo establecida en la URL, convertiremos los valores de horas y minutos a segundos y, una vez que el vídeo sea capaz de reproducirse (evento canplay), cambiaremos el valor de currentTime al pasado por parámetro.

Espero que sea de utilidad.

¡Saludos!