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
Agregar los estilos
/*!
* 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
<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>
Agregar el 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
<iframe src="{url_video}" allowFullScreen></iframe>
<video src="{url_video}" controls></video>
Agregar una imagen por defecto
<div class="cv-player-body">
<div class="cv-player-body" data-poster='url_imagen.jpg'>
Agregar servidores
<button data-caption="{text}" data-type="{type}" data-src="{url_video}">Option 01 <span>Dropbox</span></button>
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
<li><a href="{link}">Nombre servidor <span>Tamaño</span></a></li>
Enlaces de navegación (opcionales)
<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>
Agregar animaciones personalizadas
/* cvPlayer: animation */
@keyframes cvPlayer {
from {
opacity: 0;
} to {
opacity: 1;
}
}
Agregar animaciones de animate.css
--animation-name: bounceIn;
--animation-name-dl: bounceIn;
Créditos
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.