Agrega un sencillo pero poderoso player multitabs para blogger


Hola a todos, espero que se encuentren bien. En éste nuevo post les quiero compartir un pequeño aporte que estoy seguro les será de mucha ayuda. Es un player de video multitabs para agregar en su blog de series o películas. Es simple, pero espero sea de su agrado. 


Características

  • Desarrollado con vanillaJS
  • Soporte para agregar urls de enlaces directos (dropbox, google drive, etc) y enlaces de vídeos embebidos.
  • Botones para navegar entre capítulos.
  • Variables css para editar colores y demás de manera sencilla.
  • Compatibilidad con la librería animate.css y animaciones propias (para modal y lista de descarga).

Instalación


Antes de empezar con los pasos, quiero decir que si bien la instalación es para blogger, el código es perfectamente válido para usar en el CMS de tu preferencia.

Agregar los estilos


Para agregar los estilos en blogger, debemos ir a nuestro panel > Tema > Personalizar > Opciones avanzadas > Agregar CSS y pegar el siguiente código:

/*!
* cvPlayer -  v1.1.1
* Copyright 2021 © Karasu themes
* Developed by Marcelo (github.com/MarceloTLD)
* MIT License
*/

/* css variables */
.cv-player {
  --color: #5c6bc0;
  --light: #f1f3f7;
  --container: #fff;
  --text: #263238;
  --size-base: 14px;
  --size-btn: 12px;
  --radius: 4px;
  --play-icon-width: 92px;
  --transition-dur: .2s;
  --animation-name: cvPlayer; 
  --animation-name-dl: cvPlayer;
  --animation-dur: .4s;
}

.cv-player-body{position:relative}@media screen and (min-width:576px){.cv-player-flex{display:flex;justify-content:space-between}}.cv-player-body{padding:16px 0;position:relative}.cv-player-poster{position:absolute;left:0;top:16px;width:100%;height:calc(100% - 32px);z-index:100;border-radius:var(--radius);overflow:hidden;display:flex;transition:opacity .3s}.cv-player-poster:before{content:"";position:absolute;left:0;top:0;width:100%;height:100%;background:#000;opacity:.25}.cv-player-poster img{width:100%;height:100%;object-fit:cover}.cv-player-poster .ico{position:absolute;left:0;top:0;width:100%;height:100%;display:flex;align-items:center;justify-content:center;user-select:none}.cv-player-poster .ico svg{width:var(--play-icon-width);height:var(--play-icon-width);fill:#fff;cursor:pointer}.cv-player-poster.is-fading{opacity:0}.cv-player-outside{background:rgba(0,0,0,.5);position:fixed;left:0;top:0;width:100%;height:100%;display:none;align-items:center;justify-content:center;z-index:3001}.cv-player-select{padding:16px;min-width:260px;max-height:296px;background:var(--container);border-radius:var(--radius);display:none;position:relative;box-shadow:0 4px 8px rgba(0,0,0,.1);z-index:3002}@media screen and (min-width:576px){.cv-player-select{max-height:296px}}.cv-player-select>div{width:100%;display:flex;flex-direction:column;overflow-y:auto}.cv-player-outside.is-visible{display:flex;animation-duration:var(--animation-dur);animation-name:cvPlayer;animation-fill-mode:forwards}.cv-player-outside.is-visible .cv-player-select{animation-duration:calc(var(--animation-dur) * 2);animation-name:var(--animation-name);animation-fill-mode:forwards;display:flex}.cv-player-download ul li a,.cv-player-select button,.cv-player-trigger{background:var(--light);color:var(--text);border:0;outline:0;padding:12px 16px;text-align:left;font-weight:700;font-size:var(--size-base);cursor:pointer;border-radius:var(--radius);text-transform:uppercase;transition:color var(--transition-dur),background var(--transition-dur);position:relative;user-select:none;text-decoration:none}.cv-player-select button[data-caption]:before{background:rgba(0,0,0,.1);color:var(--text);font-size:var(--size-btn);padding:4px;content:attr(data-caption);text-transform:initial;border-radius:var(--radius);position:absolute;right:8px;top:calc(100% / 2 - 12px)}.cv-player-select button[data-caption].is-selected:before{background:#fff;color:var(--color)}.cv-player-select button:hover,.cv-player-trigger:hover{color:var(--color)}.cv-player-download ul li:not(:last-child) a,.cv-player-select button:not(:last-child){margin-bottom:8px}.cv-player-select button span{display:block;text-transform:lowercase;font-size:var(--size-btn);opacity:.5;margin-top:2px}.cv-player-select button.is-selected{background:var(--color);color:#fff}.cv-player-select button.is-disable{opacity:.5;pointer-events:none}.cv-player-close{background:var(--color);color:#fff;width:36px;height:36px;display:flex;align-items:center;justify-content:center;text-align:center;border-radius:50%;position:absolute;right:0;top:0;margin:-20px;cursor:pointer;box-shadow:0 4px 8px rgba(0,0,0,.1);z-index:3003}.cv-player-embed{position:relative;left:0;top:0;width:100%;padding-top:100%;display:block;border-radius:var(--radius);overflow:hidden;user-select:none}.cv-player-embed{padding-top:56.25%}.cv-player-embed iframe,.cv-player-embed video{outline:0;border:0;position:absolute;left:0;top:0;width:100%;height:100%;z-index:1}.cv-player-action{display:flex;align-items:center}.cv-player-action .cv-player-trigger#server{margin-right:8px}@media screen and (max-width:576px){.cv-player-action{justify-content:space-between}}.cv-player-trigger{display:flex;align-items:center}.cv-player-trigger svg{width:24px;height:24px;fill:currentColor;opacity:.8;margin-right:8px}.cv-player-download .cv-player-trigger svg{margin-right:0}.cv-player-download{position:relative}.cv-player-download input[type=checkbox]{display:none}.cv-player-download ul{background:var(--container);position:absolute;left:calc(100% + 12px);bottom:0;margin:0;margin-right:16px;padding:8px;min-width:14em;border-radius:var(--radius);box-shadow:0 0 8px rgba(0,0,0,.1);display:none;z-index:201}@media screen and (max-width:576px){.cv-player-download ul{left:auto;right:calc(100% + 4px)}}.cv-player-download input[type=checkbox]:checked~ul{display:block;animation-duration:calc(var(--animation-dur) * 2);animation-name:var(--animation-name-dl);animation-fill-mode:forwards}.cv-player-download ul li{list-style:none;padding:0;margin:0;display:block;animation-name:var(--animation-name-dl)}.cv-player-download ul li a{text-decoration:none;display:flex;align-items:center;justify-content:space-between}.cv-player-download ul li a span{font-size:var(--size-btn)}.cv-player-download ul li a:hover{background:var(--color);color:#fff}.cv-player-nav{display:flex;align-items:center}@media screen and (max-width:576px){.cv-player-nav{margin-top:12px}.cv-player-nav .cv-player-trigger{flex-grow:1;justify-content:center}}.cv-player-nav .cv-player-trigger:not(:first-child){margin-left:8px}

/* cvPlayer: animation */
@keyframes cvPlayer {
  from {
    opacity: 0;
  } to {
    opacity: 1;
  }
}
Al principio del código encontraremos unas variables css que nos permitirán editar el color, duración y animaciones del player. En la siguiente tabla se detalla el uso de cada una de éstas variables.
Variable uso
--color Color principal.
--light Color de fondo de los botones.
--container Color de fondo del modal y el dropdown de descargas.
--text Color de los textos.
--size-base Tamaño base.
--size-btn Tamaño de botón.
--radius Tamaño de los bordes.
--play-icon-width Tamaño máximo del icono de Play utilizado con la imagen por defecto.
--transition-dur Duración de la transición (botones)
--animation-name Nombre de una animación css para el modal
--animation-name-dl Nombre de una animación css para las descargas
--animation-dur Duración de la animaciones (keyframes)

Agregar el código de javascript

Con respecto al código de javascript, necesitamos ir a nuestro panel > Tema > Editar HTML y justo por arriba de </body> pegamos el siguiente código:
<b:if cond='data:view.isPost or data:view.isPage'>
<script>
//<![CDATA[
/*!
* cvPlayer -  v1.1.1
* Copyright 2021 © Karasu themes
* Developed by Marcelo (github.com/MarceloTLD)
* MIT License
*/
"use strict";var e,t,c;c=function(e,t){for(var c=0;c<e.length;c++)t.call(e[c],c,e[c])},e=document.querySelectorAll(".cv-player-select button"),t=document.querySelector(".cv-player-embed"),c(e,(function(n,r){var i=r;i.addEventListener("click",(function(){var n=null!=i.getAttribute("data-type")&&i.getAttribute("data-type"),r=i.getAttribute("data-src");if(i.classList.contains("is-selected"))return!1;c(e,(function(e,t){return t.classList.remove("is-selected")})),i.classList.add("is-selected"),t.innerHTML="",t.appendChild(function(e,t){var c=document.createElement("video"),n=document.createElement("iframe");return"video"==e?(c.src=t,c.controls=!0,c):(n.src=t,n.allowfullscreen=!0,n.setAttribute("allowFullScreen",""),n)}(n,r))}))})),function(){var e=document.querySelector(".cv-player-trigger#server"),t=document.querySelector(".cv-player-outside"),c=document.querySelector(".cv-player-close"),n=document.querySelector(".cv-player-body"),r=n.getAttribute("data-poster"),i=document.body,s=document.querySelector(".cv-player-download");if(e.addEventListener("click",(function(){t.classList.add("is-visible")})),c.addEventListener("click",(function(){t.classList.remove("is-visible")})),t.addEventListener("click",(function(e){e.target.classList.contains("cv-player-outside")&&t.classList.remove("is-visible")})),i.addEventListener("click",(function(){s.addEventListener("click",(function(e){return e.stopPropagation()})),s.querySelector("input").checked=!1})),r){var a=function(e){var t=document.createElement("div"),c=document.createElement("img"),n=document.createElement("div");return t.classList.add("cv-player-poster"),n.classList.add("ico"),c.src=e,n.innerHTML='<svg viewBox="0 0 24 24"><path d="M8,5.14V19.14L19,12.14L8,5.14Z" /></svg>',t.appendChild(c),t.appendChild(n),t}(r),l=n.querySelector("iframe, video");a.querySelector("svg").addEventListener("click",(function(){a.classList.add("is-fading"),l.autoplay=1,a.addEventListener("transitionend",(function(){a.remove()}))})),n.appendChild(a)}}();
//]]>
</script>
</b:if>
Guardamos los cambios y listo.

Agregar el html


Ya para terminar debemos de agregar el html para que todo quede funcionando correctamente. Desde nuestro Panel > Entradas agregamos una nueva entrada o bien editamos una, luego pegamos el siguiente código html:
<!-- cvPlayer v1.0 -->
<div class="cv-player">
<!-- Cuerpo -->
<div class="cv-player-body">
    <div class="cv-player-embed">
    	<!-- Servidor por defecto -->
    </div>
</div><!-- ./Cuerpo -->

<div class="cv-player-flex">
<!-- Acciones -->
<div class="cv-player-action">
<div>
    <div id="server" class="cv-player-trigger">
    <svg viewBox="0 0 24 24">
        <path d="M4,1H20A1,1 0 0,1 21,2V6A1,1 0 0,1 20,7H4A1,1 0 0,1 3,6V2A1,1 0 0,1 4,1M4,9H20A1,1 0 0,1 21,10V14A1,1 0 0,1 20,15H4A1,1 0 0,1 3,14V10A1,1 0 0,1 4,9M4,17H20A1,1 0 0,1 21,18V22A1,1 0 0,1 20,23H4A1,1 0 0,1 3,22V18A1,1 0 0,1 4,17M9,5H10V3H9V5M9,13H10V11H9V13M9,21H10V19H9V21M5,3V5H7V3H5M5,11V13H7V11H5M5,19V21H7V19H5Z" />
    </svg>
    Servidores</div>
</div>

<!-- Lista de opciones para servidores -->
<div class="cv-player-outside">
    <div class="cv-player-select">
    <div>
        <!-- Servidores -->
    </div>
    <!-- Cierra el modal -->
    <span class="cv-player-close">
        <svg style="width:24px;height:24px" viewBox="0 0 24 24">
        <path fill="currentColor" d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" />
        </svg>
    </span><!-- ./Cierra el modal -->
    </div>
</div><!-- ./Lista de opciones para servidores -->


<!-- Download links -->
<div class="cv-player-download">
    <label for="cvDL" class="cv-player-trigger is-dropdown">
    <svg viewBox="0 0 24 24"><path d="M5,20H19V18H5M19,9H15V3H9V9H5L12,16L19,9Z" /></svg></label>
    <input type="checkbox" id="cvDL"/>
    <ul>
        <!-- Enlaces de descarga -->
    </ul>
</div><!-- ./Download links -->
</div><!-- ./Acciones -->
<!-- Navegación -->
<div class="cv-player-nav">
	<!-- Enlaces de navegación -->
</div><!-- ./Navegación -->
</div>

</div><!-- ./cvPlayer v1.0 -->

NOTA: este proceso podemos hacerlo perfectamente en las páginas también.



Agregar servidor por defecto

En el código html debemos buscar <!-- Servidor por defecto --> y reemplazarlo por el siguiente código:
<iframe src="{url_video}" allowFullScreen></iframe>
Si tenemos enlaces directos como los de dropbox, google drive o similar, pegamos el siguiente código en su lugar:
<video src="{url_video}" controls></video>
En ambos casos debemos reemplazar {url_video} incluyendo los corchetes por la url correspondiente.

Agregar una imagen por defecto

Ahora podemos agregar una imagen por defecto que cubre el player. Muy útil si usamos servidores que no nos permiten usar una miniatura por defecto.

Para poder agregar la imagen debemos buscar el siguiente html en el código:
<div class="cv-player-body">
y agregar el atributo data-poster. Quedando de la siguiente manera:
<div class="cv-player-body" data-poster='url_imagen.jpg'>
dónde url_imagen.jpg es una url de una imagen directa.

Agregar servidores

Para agregar servidores, debemos buscar <!-- Servidores --> en el html y reemplazarlos por el siguiente código:
<button data-caption="{text}" data-type="{type}" data-src="{url_video}">Option 01 <span>Dropbox</span></button>
Para que cada boton pueda visualizar su correspondiente video, los botones deben llevar unos atributos data. En la siguiente tabla se detallan cuales son y su uso.

Atributo data uso
data-src Es la url de un video. Esta puede ser la url de un enlace directo a bien un enlace de un video embebido alojado en un servidor de terceros.
data-caption Texto que acompaña el botón. Usalo para dar determinada información.
data-type Su valor admitido es únicamente video y su uso es para cuando tenemos enlaces directos (dropbox, google drive, etc) si no es el caso, no agregar.
class Agrega el valor is-selected para remarcar un botón.

Agregar enlaces de descarga

Para agregar los enlaces de descarga, debemos buscar <!-- Enlaces de descarga --> en el html y reemplazarlos por el siguiente código:
<li><a href="{link}">Nombre servidor <span>Tamaño</span></a></li>
Reemplaza {link} incluyendo los corchetes por la url correspondiente.

Enlaces de navegación (opcionales)

En el código html, debemos buscar <!-- Enlaces de navegación --> y reemplazarlos por el siguiente código:
<a href="{url}" class="cv-player-trigger">
    <svg viewBox="0 0 24 24">
    <path d="M15.41,16.58L10.83,12L15.41,7.41L14,6L8,12L14,18L15.41,16.58Z" />
    </svg> ant.</a>
<a href="{url}" class="cv-player-trigger">
    <svg sviewBox="0 0 24 24">
    <path d="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z" />
    </svg>
    sig.</a>
<a href="{url}" class="cv-player-trigger">Lista de cap.</a>
Cambia {url} incluyendo los corchetes por la url correspondiente.

Agregar animaciones personalizadas


Es posible agregar animaciones propias gracias a las variables css. En el código css, busca:
/* cvPlayer: animation */
@keyframes cvPlayer {
  from {
    opacity: 0;
  } to {
    opacity: 1;
  }
}
y agrega tus animaciones propias. Recuerda editar los valores en las variables css para que surtan efecto.

Agregar animaciones de animate.css

Es posible agregar animaciones de la librería animate.css agregando los nombres de los keyframes de su animación correspondiente en las variables css:
--animation-name: bounceIn; 
--animation-name-dl: bounceIn;

Créditos


Agradecimientos a Material Design Icons por proporcionar los iconos en formato svg para el player.

Nota: En caso que no les funcione tienen que leer bien las instrucciones que están escritas, y una cosa más en las instrucciones dice que tienen que reemplazar el texto no que lo pongan debajo del texto.