10.- Juegos y Multimedia HTML5 - Reproductor de vídeo

Tras estos dos largos meses en "silencio" volvemos a la carga con la décima entrega del curso de Juegos y Multimedia en HTML5. Os traigo un largo videotutorial en el que veremos como hacer paso a paso un reproductor de vídeo algo especial. En nuestro reproductor los botones se encontrarán flotando por encima del vídeo y deberás perseguirlos con el ratón si quieres pulsarlos ;). Para realizar esta aplicación nos basamos en conocimientos con los que ya hemos trabajado antes, si hay algo que no entiendes bien te recomendaría que le echaras un vistazo a las anteriores entregas del curso. Como siempre, yo creo que el vídeo se explica por si solo. Os dejo un enlace junto al código para que veáis el reproductor en funcionamiento.



Código del vídeo. Ver reproductor en funcionamiento.
<!DOCTYPE html>
<html>
  <head>
    <title>Videos en los Canvas</title>
    <meta charset="UTF-8">
    <meta name="author" 
        content="http://programmingheroes.blogspot.com.es">
    <style>
        
     #canvasControles {
            position: absolute;
            box-shadow: 0px 0px 10px #000;
        }
        
     #canvasVideo {
            position: absolute;
        }
        
        .bn {
            -webkit-filter: grayscale(100%);
        }
        
    </style>
    <script>
        var canvasVideo, ctxVideo, video;
        var canvasControles, ctxControles, controles;
        var xPoint, yPoint, down;
        
        window.addEventListener('load', function () {
            if (!hayCanvas()) {
                alert("Tu navegador no soporta canvas");
            }
            video = document.createElement("video");
            if (video == null) {
                alert("Tu navegador no soporta video");
            }
            canvasVideo = document.getElementById("canvasVideo");
            canvasControles = document.getElementById("canvasControles");
            ctxVideo = canvasVideo.getContext("2d");
            ctxControles = canvasControles.getContext("2d");
            video.src = "video/Gatitos.webm";
            video.addEventListener('loadedmetadata', function () {
                canvasVideo.width = canvasControles.width =
                 video.videoWidth;
                canvasVideo.height = canvasControles.height =
                 video.videoHeight;
            });
            video.addEventListener('canplay', function () {
                setInterval(paintVideo, 33);
                setInterval(paintControles, 11);
            });
            
            var play = new Boton(pintarPlay, playPause);
            var mute = new Boton(pintarMute, muted);
            var bn = new Boton(pintarBn, accionBn);
            controles = [play, mute, bn];
            
            canvasControles.addEventListener("mousedown", mouseDown);
            canvasControles.addEventListener("mouseup", mouseUp);
            canvasControles.addEventListener("mouseout", mouseUp);
            canvasControles.addEventListener("mousemove", movePoint);
        });
        
        function paintVideo() {
            ctxVideo.drawImage(video, 0, 0,
                canvasVideo.width, canvasVideo.height);
        }
        
        function paintControles() {
            ctxControles.clearRect(0, 0,
                canvasControles.width, canvasControles.height);
            for (var i=0; i<controles.length; i++) {
                controles[i].mover();
                if (down && 
                    (controles[i].x-xPoint)*(controles[i].x-xPoint)+
                    (controles[i].y-yPoint)*(controles[i].y-yPoint)
                    <= controles[i].r*controles[i].r)
                {
                        controles[i].accion();
                        down = false;
                }
                controles[i].estilo(ctxControles);
            }
        }
        
        function mouseDown(e) {
            down = true;
            movePoint(e);
        }
        
        function mouseUp(e) {
            down = false;
        }
        
        function movePoint(e) {
            var ie = navigator.userAgent.toLowerCase()
                .indexOf('msie')!=-1;
            if (ie) {
                e = window.event;
                e.pageX = e.clientX+window.pageXOffset;
                e.pageY = e.clientY+window.pageYOffset;
            }
            xPoint = e.pageX-canvasControles.offsetLeft;
            yPoint = e.pageY-canvasControles.offsetTop;
        }
        
        function hayCanvas() {
            var elem = document.createElement('canvas');
            return !!(elem.getContext && elem.getContext('2d'));
        }
        
        function Boton(estilo, accion) {
            this.r = canvasControles.width*0.05;
            this.x = this.r+Math.random()*(canvasControles.width-this.r);
            this.y = this.r+Math.random()*(canvasControles.height-this.r);
            this.vx = (Math.random()-0.5)*4;
            this.vy = (Math.random()-0.5)*4;
            this.accion = accion;
            this.estilo = estilo;
        }
        
        Boton.prototype = {
            mover: function() {
                    this.x += this.vx;
                    if (this.x+this.r > canvasControles.width) {
                            this.vx = -this.vx;
                            this.x = canvasControles.width-this.r;
                    } else if (this.x-this.r < 0) {
                            this.vx = -this.vx;
                            this.x = this.r;
                    }
                    this.y += this.vy;
                    if (this.y+this.r > canvasControles.height) {
                        this.vy = -this.vy;
                        this.y = canvasControles.height-this.r;
                    } else if (this.y-this.r < 0) {
                            this.vy = -this.vy;
                            this.y = this.r;
                    }
            }
        }
        
        function playPause() {
            if (video.paused) {
                video.play();
            } else {
                video.pause();
            }
        }
        
        function pintarPlay(ctx) {
            // Círculo de fondo
            ctx.beginPath();
            ctx.arc(this.x, this.y, this.r, 0, Math.PI*2);
            ctx.fillStyle = "rgba(0, 0, 0, 0.5)";
            ctx.closePath();
            ctx.fill();
            // Dibujo
            ctx.beginPath();
            if (video.paused) {
                ctx.moveTo(this.x-this.r/2, this.y-this.r/2);
                ctx.lineTo(this.x-this.r/2, this.y+this.r/2);
                ctx.lineTo(this.x+this.r/2, this.y);
                ctx.lineTo(this.x-this.r/2, this.y-this.r/2);
            } else {
                ctx.moveTo(this.x-this.r/2, this.y-this.r/2);
                ctx.lineTo(this.x-this.r/2, this.y+this.r/2);
                ctx.lineTo(this.x-this.r*0.2, this.y+this.r/2);
                ctx.lineTo(this.x-this.r*0.2, this.y-this.r/2);
                ctx.lineTo(this.x-this.r/2, this.y-this.r/2);
       
                ctx.moveTo(this.x+this.r/2, this.y-this.r/2);
                ctx.lineTo(this.x+this.r/2, this.y+this.r/2);
                ctx.lineTo(this.x+this.r*0.2, this.y+this.r/2);
                ctx.lineTo(this.x+this.r*0.2, this.y-this.r/2);
                ctx.lineTo(this.x+this.r/2, this.y-this.r/2);
            }
            ctx.fillStyle = "rgba(255, 255, 255, 0.5)";
            ctx.closePath();
            ctx.fill();
        }
        
        function muted() {
           video.muted = !video.muted;
        }
        
        function pintarMute(ctx) {
            // Círculo de fondo
            ctx.beginPath();
            ctx.arc(this.x, this.y, this.r, 0, Math.PI*2);
            ctx.fillStyle = "rgba(0, 0, 0, 0.5)";
            ctx.closePath();
            ctx.fill();
            // Altavoz
            ctx.beginPath();
            ctx.moveTo(this.x-this.r/2, this.y-this.r/4);
            ctx.lineTo(this.x-this.r/2, this.y+this.r/4);
            ctx.lineTo(this.x, this.y+this.r/4);
            ctx.lineTo(this.x+this.r/2, this.y+this.r/2);
            ctx.lineTo(this.x+this.r/2, this.y-this.r/2);
            ctx.lineTo(this.x, this.y-this.r/4);
            ctx.lineTo(this.x-this.r/2, this.y-this.r/4);
            ctx.fillStyle = "rgba(255, 255, 255, 0.5)";
            ctx.closePath();
            ctx.fill();
            // Silencio o no
            if (video.muted) {
                ctx.beginPath();
                ctx.moveTo(this.x-this.r/2, this.y-this.r/2);
                ctx.lineTo(this.x+this.r/2, this.y+this.r/2);
                ctx.strokeStyle = "rgba(255, 50, 50, 0.5)";
                ctx.closePath();
                ctx.stroke();
            }
        }
        
        function accionBn() {
           canvasVideo.classList.toggle("bn");
        }
        
        function pintarBn(ctx) {
            // Círculo de fondo
            ctx.beginPath();
            ctx.arc(this.x, this.y, this.r, Math.PI, Math.PI*2);
            ctx.fillStyle = "rgba(0, 0, 0, 0.5)";
            ctx.closePath();
            ctx.fill();
            // Altavoz
            ctx.beginPath();
            ctx.arc(this.x, this.y, this.r, 0, Math.PI);
            ctx.fillStyle = "rgba(255, 255, 255, 0.5)";
            ctx.closePath();
            ctx.fill();
        }
    </script>
  </head>
  <body style="background-color: #AAA">
      <noscript>
        No tiene habilitado JavaScript. Debería habilitarlo para poder
        disfrutar al completo de los contenidos de esta página.
      </noscript>
      <div>
          <canvas id="canvasVideo">
              Tu navegador no soporta el elemento
              <code>canvas</code> de HTML5.
          </canvas>
          <canvas id="canvasControles">
          </canvas>
      </div>
  </body>
</html>

2 comentarios :

  1. Muy buen ejemplo, pero tengo una duda, cuando el video es de una página web diferente, los efectos no funcionan :S de antemano, muchas gracias...

    ResponderEliminar