Crear un reproductor de video de YouTube personalizado con las API de YouTube

Las presentaciones en video son una gran adición a cualquier página de producto. Con una presentación, puede mostrar las características de su producto sin que el visitante lea largos párrafos de texto. Pero además de producir el video, aún necesita convertirlo manualmente y encontrar (o codificar) algún tipo de reproductor flash que lo muestre en su sitio.

El otro camino posible es subirlo a un sitio para compartir videos como YouTube, pero tendrá dificultades para incorporar el reproductor en su diseño.

Afortunadamente para nosotros, YouTube proporciona una solución a este problema:su reproductor sin bordes (una versión simplificada del reproductor insertable normal), que le permite crear y diseñar sus propios controles personalizados. De esta manera, tiene una forma rápida y segura de incluir videos en sus páginas y la libertad de personalizar de la forma que desee.

La idea

Hoy vamos a crear un complemento de jQuery que utiliza el reproductor sin bordes de YouTube. y crea nuestro propio conjunto de controles minimalistas, lo que permite una integración perfecta con sus diseños. Los controles admitidos incluyen un botón Reproducir/Pausar/Reproducir y una barra de progreso en la que se puede hacer clic.

El complemento utilizará la API gdata de YouTube para determinar si se ha permitido la incrustación del video y obtendrá información detallada al respecto, como el título, la descripción, las etiquetas, las capturas de pantalla y más, que puede usar para mejorar el complemento.

Usar el complemento para incrustar videos es extremadamente fácil:

// Embed a video into the #player div:
$('#player').youTubeEmbed('http://www.youtube.com/watch?v=u1zgFlCw8Aw');

// Chaining is also supported:
$('#player').youTubeEmbed('http://www.youtube.com/watch?v=u1zgFlCw8Aw');
        .youTubeEmbed('http://www.youtube.com/watch?v=AsdfFdwlzdAw');

También puede especificar un ancho para el video incrustado (la altura se calculará automáticamente según la relación de aspecto) y optar por deshabilitar la barra de progreso:

$('#player').youTubeEmbed({
    video           : 'http://www.youtube.com/watch?v=u1zgFlCw8Aw',
    width           : 600,      // Height is calculated automatically
    progressBar : false     // Hide the progress bar
});

Puede obtener el complemento desde el botón de descarga de arriba y comenzar con el primer paso.

Paso 1 - XHTML

Nuestro complemento depende de jQuery SWFObject para incrustar los archivos SWF en la página. A continuación, puede ver el marcado combinado generado por ambos complementos.

youtube-player.html

<div class="flashContainer" style="width: 640px; height: 360px;">

    <object height="360" width="640" id="video_26ELpS3Wc4Q" type="application/x-shockwave-flash"
    data="http://www.youtube.com/apiplayer?enablejsapi=1&version=3">

        <param value="always" name="allowScriptAccess">
        <param value="transparent" name="wmode">
        <param value="video_id=26ELpS3Wc4Q&playerapiid=26ELpS3Wc4Q"
        name="flashvars">
        <param value="http://www.youtube.com/apiplayer?enablejsapi=1&version=3"
        name="movie">

    </object>

    <div class="controlDiv play"></div>

    <div class="progressBar">
        <div class="elapsed"></div>
    </div>
</div>

El .flashContainerDiv es creado dinámicamente por el complemento para cada video en la página. Se rellena con el código de inserción generado por SWFObject, el .controlDiv (que actúa como un botón de reproducción/pausa) y la barra de progreso.

Como se mencionó anteriormente, la inserción del reproductor en sí es manejada por el complemento SWFObject. Según el navegador, puede generar un objeto elemento o una incrustación no estándar elemento para IE. Esto nos quita la carga y nos permite concentrarnos en tareas como consultar las API de YouTube y crear los controles del reproductor.

Paso 2:jQuery

El código del complemento se encuentra en youTubeEmbed-jquery-1.0.js expediente. Sin embargo, antes de poder usarlo, debe incluir la última versión de la biblioteca jQuery en la página, junto con el complemento jQuery SWFObject y, por último, script.js , que inserta dos videos en la página de demostración y maneja los envíos del formulario de vista previa.

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="jquery.swfobject.1-1-1.min.js"></script>
<script src="youTubeEmbed/youTubeEmbed-jquery-1.0.js"></script>
<script src="script.js"></script>

Antes de comenzar a profundizar en el código del complemento del reproductor, echemos un vistazo a una respuesta de muestra de la API de gdata de YouTube. Puede brindarle mucha información útil sobre un video, incluida la duración, el control de acceso (ambos utilizados por el complemento) y todo tipo de datos adicionales, como título, descripción, etiquetas, capturas de pantalla y más.

Respuesta JSON de muestra

{
    "id": "u1zgFlCw8Aw",
    "uploaded": "2008-03-05T01:22:17.000Z",
    "updated": "2010-07-23T01:02:42.000Z",
    "uploader": "GoogleDevelopers",
    "category": "People",
    "title": "The YouTube API: Upload, Player APIs and more!",
    "description": "Listen to the YouTube APIs and Tools team talk about...",
    "tags": ["youtube", "launch", "api", "engineering"],
    "thumbnail": {
        "sqDefault": "http://i.ytimg.com/vi/u1zgFlCw8Aw/default.jpg",
        "hqDefault": "http://i.ytimg.com/vi/u1zgFlCw8Aw/hqdefault.jpg"
    },
    "player": {
        "default": "http://www.youtube.com/watch?v=u1zgFlCw8Aw",
        "mobile": "http://m.youtube.com/details?v=u1zgFlCw8Aw"
    },
    "content": {
        "1": "rtsp://v4.cache5.c.youtube.com/CiILE..",
        "5": "http://www.youtube.com/v/u1zgFlCw8Aw?f..",
        "6": "rtsp://v3.cache4.c.youtube.com/CiILENy73.."
    },
    "duration": 259,
    "location": "san bruno, ca",
    "rating": 4.3,
    "likeCount": "119",
    "ratingCount": 144,
    "viewCount": 251024,
    "favoriteCount": 164,
    "commentCount": 118,
    "accessControl": {
        "syndicate": "allowed",
        "commentVote": "allowed",
        "rate": "allowed",
        "list": "allowed",
        "comment": "allowed",
        "embed": "allowed",
        "videoRespond": "allowed"
    }
}

Todos los campos de estos objetos de respuesta están disponibles como propiedades en los datos variable (datos.nombre de campo ). Podría modificar el complemento para mostrar el título con un enlace a la página del video en YouTube o mostrar la calificación del video.

Ahora sumerjámonos directamente en el código fuente del script.

YouTubeEmbed-jquery-1.0.js - Parte 1

(function($){

    $.fn.youTubeEmbed = function(settings){

        // Settings can be either a URL string,
        // or an object

        if(typeof settings == 'string'){
            settings = {'video' : settings}
        }

        // Default values

        var def = {
            width       : 640,
            progressBar : true
        };

        settings = $.extend(def,settings);

        var elements = {
            originalDIV : this, // The "this" of the plugin
            container   : null, // A container div, inserted by the plugin
            control     : null, // The control play/pause button
            player      : null, // The flash player
            progress    : null, // Progress bar
            elapsed     : null  // The light blue elapsed bar
        };

        try{    

            settings.videoID = settings.video.match(/v=(\w+)/)[1];

            // safeID is a stripped version of videoID,
            // ready for use as a JavaScript function name

            settings.safeID = settings.videoID.replace(/[^a-z0-9]/ig,'');

        } catch (e){
            // If the url was invalid, just return the "this"
            return elements.originalDIV;
        }

        // Fetch data about the video from YouTube's API

        var youtubeAPI = 'http://gdata.youtube.com/feeds/api/videos?v=2&alt=jsonc';

        $.get(youtubeAPI,{'q':settings.videoID},function(response){

            var data = response.data;

            if(!data.totalItems || data.items[0].accessControl.embed!="allowed"){

                // If the video was not found, or embedding is not allowed;

                return elements.originalDIV;
            }

            // data holds API info about the video:

            data = data.items[0];

            settings.ratio = 3/4;
            if(data.aspectRatio == "widescreen"){
                settings.ratio = 9/16;
            }

            settings.height = Math.round(settings.width*settings.ratio);

Comenzamos definiendo nuestro script como un complemento de jQuery agregándolo como una función a $.fn objeto. Para que el código sea más fácil de seguir y leer, puse todos los elementos de la página, como el control y los divs de la barra de progreso en una estructura llamada elements. .

Después de extraer el id del video (una secuencia única de 11 caracteres después de ?v= parámetro), enviamos una solicitud JSONP a la API gdata de youtube. Dependiendo de si existe dicho video y de si se permite incrustarlo, procedemos a calcular la relación de aspecto. La altura del video se calcula usando esta proporción y multiplicándola por el ancho.

YouTubeEmbed-jquery-1.0.js - Parte 2

          // Creating a container inside the original div, which will
            // hold the object/embed code of the video

            elements.container = $('<div>',{className:'flashContainer',css:{
                width   : settings.width,
                height  : settings.height
            }}).appendTo(elements.originalDIV);

            // Embedding the YouTube chromeless player
            // and loading the video inside it:

            elements.container.flash({
                swf         : 'http://www.youtube.com/apiplayer?enablejsapi=1&version=3',
                id          : 'video_'+settings.safeID,
                height      : settings.height,
                width       : settings.width,
                allowScriptAccess:'always',
                wmode       : 'transparent',
                flashvars   : {
                    "video_id"      : settings.videoID,
                    "playerapiid"   : settings.safeID
                }
            });

            // We use get, because we need the DOM element
            // itself, and not a jquery object:

            elements.player = elements.container.flash().get(0);

            // Creating the control Div. It will act as a ply/pause button

            elements.control = $('<div>',{className:'controlDiv play'})
                               .appendTo(elements.container);

            // If the user wants to show the progress bar:

            if(settings.progressBar){
                elements.progress = $('<div>',{className:'progressBar'})
                                    .appendTo(elements.container);

                elements.elapsed =  $('<div>',{className:'elapsed'})
                                    .appendTo(elements.progress);

                elements.progress.click(function(e){

                    // When a click occurs on the progress bar, seek to the
                    // appropriate moment of the video.

                    var ratio = (e.pageX-elements.progress.offset().left)/elements.progress.outerWidth();

                    elements.elapsed.width(ratio*100+'%');
                    elements.player.seekTo(Math.round(data.duration*ratio), true);
                    return false;
                });

            }

En la segunda parte del código, usamos el SWFObject complemento para generar el código de inserción del reproductor sin cromo de youtube. Tenga en cuenta que la identificación del video se pasa como flashvar para que el reproductor pueda cargarlo directamente. La variable safeID (una versión segura de JavaScript del videoid) se convierte en el valor del id parámetro del elemento de objeto que se va a generar. De esta forma, podemos obtener más tarde el elemento DOM ejecutando document.getElementById('video_'+settings.safeID) y acceda a los métodos que controlan el reproductor de YouTube (reproducir, pausar, etc.).

YouTubeEmbed-jquery-1.0.js - Parte 3

var initialized = false;

// Creating a global event listening function for the video
// (required by YouTube's player API):

window['eventListener_'+settings.safeID] = function(status){

    var interval;

    if(status==-1)  // video is loaded
    {
        if(!initialized)
        {
            // Listen for a click on the control button:

            elements.control.click(function(){
                if(!elements.container.hasClass('playing')){

                    // If the video is not currently playing, start it:

                    elements.control.removeClass('play replay').addClass('pause');
                    elements.container.addClass('playing');
                    elements.player.playVideo();

                    if(settings.progressBar){
                        interval = window.setInterval(function(){
                            elements.elapsed.width(
                    ((elements.player.getCurrentTime()/data.duration)*100)+'%'
                            );
                        },1000);
                    }

                } else {

                    // If the video is currently playing, pause it:

                    elements.control.removeClass('pause').addClass('play');
                    elements.container.removeClass('playing');
                    elements.player.pauseVideo();

                    if(settings.progressBar){
                        window.clearInterval(interval);
                    }
                }
            });

            initialized = true;
        }
        else{
            // This will happen if the user has clicked on the
            // YouTube logo and has been redirected to youtube.com

            if(elements.container.hasClass('playing'))
            {
                elements.control.click();
            }
        }
    }

Para poder controlar el reproductor de video, debemos recibir una notificación cuando ocurran ciertos eventos (como la reproducción detenida, el video listo, etc.). Normalmente, esto significaría que necesitamos pasar una función de devolución de llamada, que el jugador ejecuta cada vez que ocurre un evento de este tipo.

Desafortunadamente, Flash solo puede ejecutar funciones si están definidas en el ámbito global y no puede ver las funciones que están definidas dentro del complemento. Sin embargo, al crear funciones con nombres únicos (con el safeID ) y agregarlos explícitamente a la ventana objeto podemos hacer que esto suceda. Si no fuera por este pequeño truco, sería imposible que el complemento funcionara.

YouTubeEmbed-jquery-1.0.js - Parte 4

              if(status==0){ // video has ended
                    elements.control.removeClass('pause').addClass('replay');
                    elements.container.removeClass('playing');
                }
            }

            // This global function is called when the player is loaded.
            // It is shared by all the videos on the page:

            if(!window.onYouTubePlayerReady)
            {
                window.onYouTubePlayerReady = function(playerID){
                    document.getElementById('video_'+playerID).addEventListener('onStateChange','eventListener_'+playerID);
                }
            }
        },'jsonp');

        return elements.originalDIV;
    }

})(jQuery);

La función de escucha de eventos que creamos en la sección anterior del código se adjunta al reproductor con addEventListener. método. Se llama cada vez que un "stateChange " (inicio de reproducción, pausa de reproducción, fin de reproducción, etc.). Se pasa un código numérico a la función de escucha de eventos como parámetro, correspondiente al evento.

Ahora echemos un vistazo a cómo se usa nuestro complemento.

secuencia de comandos.js

$(document).ready(function(){

    $('#player').youTubeEmbed('http://www.youtube.com/watch?v=u1zgFlCw8Aw');

    /*
        //You can alternatively pass an object:

        $('#player').youTubeEmbed({
            video           : 'http://www.youtube.com/watch?v=u1zgFlCw8Aw',
            width           : 600,      // Height is calculated automatically
            progressBar : false     // Hide the progress bar
        });

    */

});

Solo necesita llamar al youTubeEmbed() y pásele una cadena o un objeto de configuración. Si se pasa una cadena, se supone que es la URL de un video de YouTube. Si está pasando un objeto, asegúrese de que está pasando el video propiedad con una URL de video correcta.

Paso 3 - CSS

Finalmente nos queda aplicar algunos estilos CSS al reproductor. Cambiarán el diseño de los controles del reproductor y definirán la forma en que se colocan en la ventana del reproductor.

YouTubeEmbed-jquery-1.0.css

.flashContainer{

    /*  Setting the container to relative positioning
        so we can center the control div */

    position:relative;
    overflow:hidden;
}

.progressBar{
    display:none;
    position:absolute;
    width:auto;
    height:8px;
    left:20px;
    right:105px;
    bottom:20px;
    background-color:#141414;
    overflow:hidden;
    cursor:pointer;

    /* A light CSS3 bottom highlight */

    -moz-box-shadow:0 1px 0 rgba(255, 255, 255, 0.3);
    -webkit-box-shadow:0 1px 0 rgba(255, 255, 255, 0.3);
    box-shadow:0 1px 0 rgba(255, 255, 255, 0.3);
}

.progressBar .elapsed{
    position:absolute;
    width:0;
    height:100%;
    background-color:#1fa2f6;
    border-right:1px solid #49AFF0;
}

.controlDiv{
    /* Centering the control div */
    position:absolute;
    width:120px;
    height:120px;
    cursor:pointer;
    top:50%;
    left:50%;
    margin:-60px 0 0 -60px;
}

.controlDiv.play{
    background:url('img/play.png') no-repeat center center;
}

.controlDiv.replay{
    background:url('img/replay.png') no-repeat center center;
}

.controlDiv.pause{
    background:url('img/pause.png') no-repeat -99999px;
}

.flashContainer:hover .controlDiv.pause{
    background-position:center center;
}

/* Only show the progress bar when the video is playing */

.flashContainer.playing:hover .progressBar{
    display:block;
}

Para personalizar el aspecto del reproductor, solo necesita cambiar los valores de color de arriba. También puede editar los archivos png con los botones de reproducción/pausa. Claramente, esto es mucho más fácil que modificar la apariencia del reproductor de YouTube predeterminado. También elimina todo el cromo innecesario y te deja con lo más importante:tu video.

¡Con esto, nuestro complemento de reproductor personalizado de YouTube está completo!

¿Te ha gustado este tutorial? Comparta sus pensamientos en la sección de comentarios a continuación.