Programación de contenidos HTML
A continuación se describen las limitaciones y prácticas recomendadas para la programación de contenidos de tipo HTML para Admira Player HTML5.
Importante
El engine de reproducción de contenidos HTML puede variar dependiendo de la plataforma de el player. Así pues, un player corriendo sobre WebOS utilizara una versión determinada de Webkit dependiendo del firmware, Windows correrá sobre otra, algunas plataformas no aceptan plugins Flash, etc.
Admira se encuentra trabajando constantemente en la lista de cada una de las particularidades para cada plataforma, sistema operativo o firmware. De forma general, la mayoría de plataformas en sus últimas versiones (WebOS 4.0+, Tizen/SSSP5+, Windows, Linux NWJS 0.17.6 y Android) corren con Chrome v53.
Para necesidades concretas, puede contactar con soporte@admira.com para obtener más información. Recomendamos, una vez identificado el engine donde va a correr el contenido, revisar los requisitos desde la web www.caniuse.com. Herramientas como https://babeljs.io/repl pueden ser útiles para hacer el JS compatible.
Limitaciones
Estructura de ficheros
La estructura de ficheros actual para reproducción sobre player HTML5 limita el uso de subcarpetas. Cualquier fichero necesario para el contenido HTML debe permanecer en la misma carpeta que este, incluyendo ficheros de tipo css, js, png, jpg, mp4, ogg, etc.
Es decir la estructura sería:
-
main_12345.html
-
script_12345.js
-
image_12345.png
-
style_12345.css
-
….
Al no poder usar subcarpetas, se hace indispensable el correcto nombramiento de ficheros, siendo cada contenido un fichero único con sus asociados también únicos. En el ejemplo se usa “12345” para identificar de forma única el contenido.
Importante
Los nombres de fichero de scripts adjuntos no pueden contener el signo de punto (“.”). Es decir, no se aceptan nombres como “socket.io.js”, sino que se deberá subir renombrado como “socket_io.js”
Buenas Prácticas
Importante
Se deberá hacer uso de control de excepciones con try/catch. Las excepciones no controladas podrían inhabilitar el player HTML5 en alguna de sus funciones. Si se produjeran errores que puedan perjudicar la normal ejecución del player, Admira no se haría responsable de las consecuencias.
Iframe
La ejecución de contenidos o WebApps se produce dentro de un TAG HTML <iframe> sandboxed. Este iframe sandbox contiene los siguientes permisos habilitados:
-
allow-forms Re-enables form submission
-
allow-pointer-lock Re-enables APIs
-
allow-same-origin Allows the iframe content to be treated as being from the same origin
-
allow-scripts Re-enables scripts
Por contra no están permitidos:
-
top-navigation; (esto es, solo se puede usar “_self” en target de links)
-
popups
Acceso a recursos externos
Cada casuística es diferente. En el caso de querer acceder a recursos de otros “sites”, se deberán tener en cuenta las políticas de ejecución desde un <iframe>. Esto significa que opciones como X-Frame-Options o CORS deben ser seteadas correctamente en el servidor al que queramos hacer la petición. En definitiva, las WebApps que queramos correr en admira <iframe> no se ejecutan como en un navegador, sino en una “ventana desatendida”.
Peticiones ASYNC
Es importante remarcar que cualquier petición que se haga ya sea al exterior (url en internet) o de forma local (fichero en filesystem) debe hacerse de forma ASYNCRONA, ya que el contenido HTML comparte HILO de ejecución con el player. Por tanto, si se diera el caso de una petición SYNC, el player pararía hasta que la petición finalizara. Esto puede provocar problemas graves en la ejecución de player. Por tanto, TODAS las peticiones deben hacerse de modo ASYNCRONO, de igual modo que cualquier ejecución de código bloqueante SYNCRONO debe evitarse para que no provoque una parada inusual al player.
En esta web podemos simular bloqueos de peticiones:
http://slowwly.robertomurray.co.uk/delay/3000/url/http://api.admira.com
Donde 3000 es el delay en miliseconds.
Admira API Content HTML5
Admira API content HTML5 es el servicio disponible para poder comunicarse desde un contenido HTML al player de Admira via Javascript. A continuación se describen las funciones básicas de dicha API.
Para poder utilizar las funcionalidades de Admira API Content HTML5, es necesario disponer del script, proporcionado por Admira.
Una vez añadido como adjunto y incluido en el HTML principal, se puede invocar de la siguiente manera:
<script>
var api_obj = null;
function on_load(){
api_obj = new admira_api_content();
api_obj.onReady = function(){
console.log(«Ready !»);
};
api_obj.onStart = function(){
console.log(«Start !»);
};
}
</script>
<body onLoad=”on_load();”>
…
Eventos
Aqui se explican los eventos básicos de API Content.
-
onReady: se produce cuando el player ha conseguido precargar el contenido HTML con éxito, es decir, el HTML ha sido cargado dentro del iFrame. En este punto el iFrame sigue en DISPLAY:NONE
-
onStart: se produce cuando el player pone en “PLAY” el contenido. Cualquier animación o reproducción de elementos debe iniciarse aquí. En este punto el iFrame sigue en DISPLAY:INLINE
Funcionalidades
API content también permite enviar mensajes a player HTML5 para indicarle diferentes acciones a realizar:
-
API_DURATION: Cambia la duración del contenido que se está reproduciendo
-
API_FINISH: Finaliza el contenido que se está reproduciendo
-
API_CONDITION: Escribe una condición para poder ser leída posteriormente por el player con las capacidades de Playlist condicional y Triggers de condiciones
-
API_WRITE_FILE: Permite escribir datos de texto a un fichero en local
-
API_READ_FILE: Permite leer un fichero de texto local
Nota
Estas funcionalidades están en constante desarrollo y mejora. Para cualquier cuestión, no dudes en reportar a soporte@admira.com.
Nota
Para versiones de app inferiores a z19.05.30, cuando se quiere obtener el id del player, es necesario poner la llamada dentro de onStrat. Para las versiones posteriores a z19.05.30, esta incluida, se puede poner dentro de onReady. A continuación se muestra un ejemplo de cómo habría que pedir el id del player en ambos casos.
Versión de la aplicación anterior a z19.05.30
my_api.onReady = function(){
console.log("Ready !”);
};
my_api.onStart = function(){
console.log(“onStart”);
my_api.send("api_command",{command:my_api.API_PLAYER_INFO,params:{'callback':"onGetInfo"}});
};
Versión de la aplicación igual o posterior a z19.05.30
my_api.onReady = function(){
console.log("Ready !”);
my_api.send("api_command",{
command:my_api.API_PLAYER_INFO,params:{
'callback':"onGetInfo"
}
});
};
my_api.onStart = function(){
console.log(“onStart”);
};
Ejemplos de funciones
# API_DURATION:
api_obj.send("api_command",{
command:api_obj.API_DURATION,
params: {
duration:30
}
});
→ Cambiará la duración, donde 30 es el número de segundos a partir del momento de la llamada a API.
# API_FINISH:
api_obj.send("api_command",{
command:api_obj.API_FINISH
});
→ Finalizara el contenido de inmediato.
# API_CONDITION:
var condition_object = {
'id': ‘01’,
'filename': ‘internet_connected.xml’,
'value':1,
‘write’:true
};
api_obj.send("api_command",{
command:api_obj.API_CONDITION,
params:condition_object
});
→ Escribirá el valor de la condicion para “Internet Connected”.
# API_WRITE_FILE:
var file_object = {
'path': ‘./log’,
'filename': ‘hello.txt’,
'text':’ Hello World !’
};
api_obj.send("api_command",{
command:api_obj.API_WRITE_FILE,
params:file_object
});
→ Escribirá “Hello World!“ en ./content/hello.txt
# API_READ_FILE:
function onFileReadComplete(data){
console.log("HTML onFileReadComplete data : "+data);
}
var file_object = {
'path': ‘./log’,
'filename': ‘hello.txt’,
'callback': ‘onFileReadComplete’
};
api_obj.send("api_command",{
command:api_obj.API_READ_FILE,
params:file_object
});
→ Leerá ./content/hello.txt y enviara el resultado al callback : onFileReadComplete
# API_PLAYER_INFO:
**Ejemplo completo obtener player_id y usarlo (versiones app inferiores a z19.05.30)
<script>
my_api = new admira_api_content();
var started = false;
var playerId = 0;
if (typeof(Storage) !== "undefined") {
playerId = localStorage.getItem("playerID");
myFunction(playerId);
}
if(playerId == 0){
//Cuando inicia el player (Carga el HTML)
my_api.onReady = function () {
setTimeout(function(){my_api.onStart()},time);
};
//Cuando emite el HTML
my_api.onStart = function () {
clearTimeout(time)
if(!started){
my_api.send("api_command", {
command: my_api.API_PLAYER_INFO, params: { 'callback': "onGetInfo"
}
});
}
started = true;
};
my_api.onEvent = function (e) {
if (started) {
if (e.action == my_api.API_PLAYER_INFO) {
if (typeof (e.msg.callback) !== "undefined") {
eval(e.msg.callback)(e.msg.data);
}
}
}
};
}
function onGetInfo(data) {
try {
if (data) {
if (data.PlayerController && data.PlayerController.player_id) {
playerId = data.PlayerController.player_id;
localStorage.setItem("playerID", playerId);
myFunction(playerId);
}
}
}
catch (e) {
document.getElementById("contenedor").innerHTML = e;
}
};
</script>
# API_PLAYER_INFO:
**Ejemplo completo obtener player_id y usarlo (versiones app iguales o superiores a z19.05.30)
<script>
my_api = new admira_api_content();
var started = false;
var playerId = 0;
var time = 2000;
if (typeof(Storage) !== "undefined") {
playerId = localStorage.getItem("playerID");
myFunction(playerId);</p>
}
if(playerId == 0){
//Cuando inicia el player (Carga el HTML)
my_api.onReady = function () {
my_api.send("api_command", {
command: my_api.API_PLAYER_INFO, params: {
'callback': "onGetInfo"
}
});
};
//Cuando emite el HTML
my_api.onStart = function () {
started = true;
};
my_api.onEvent = function (e) {
if (started) {
if (e.action == my_api.API_PLAYER_INFO) {
if (typeof (e.msg.callback) !== "undefined") {
eval(e.msg.callback)(e.msg.data);
}
}
}
};
}
function onGetInfo(data) {
try {
if (data) {
if (data.PlayerController && data.PlayerController.player_id) {
playerId = data.PlayerController.player_id;
localStorage.setItem("playerID", playerId);
myFunction(playerId);
}
}
}
catch (e) {
document.getElementById("contenedor").innerHTML = e;
}
};
</script>
Nomenclatura de ficheros
Ficheros necesarios de base:
-
PROJECTID_H0001.html (el HTML de base)
-
PROJECTID_H0001.xml (xml que contiene los datos de adjuntos y settings del fastcontent)
-
PROJECTID_H0001.css (fichero de estilos que se aplicaran al fastcontent)
-
Adjunto_1.png (puede tener cualquier nombre de fichero)
-
Adjunto_2.mp4 (puede tener cualquier nombre de fichero)
-
…
(SE RECOMIENDA INCRUSTAR EN LO POSIBLE EL CODIGO DE CUALQUIER FICHERO JS EN EL HTML DIRECTAMENTE PARA EVITAR COLISIONES ENTRE FICHEROS)
Estructura de XML
Para ver un ejemplo de XML para Fastcontent (HTML / SWF), ver en este repo.
Estructura de HTML básico para plantilla
El HTML de fastcontent se distribuye en las siguientes secciones:
### HEAD
Global para todos los Fastcontent.
<style>
/* FASTCONTENT GLOBALS */
body {
margin: 0 0 0 0;
font-family: sans-serif;
}
#chrome_flags{
background-color: #c33e3e;
width: 100%;
height: 100%;
text-align: center;
font-size: 1vw;
}
#chrome_flasgs_inner{
padding: 20px;
background-color: #AAAAAA;
margin-left: 20%;
width: 60%;
text-align: left;
font-size: 1vw;
}
#chrome_info{
background-color: #228a33db;
width: 100%;
height: 100%;
text-align: center;
font-size: 1vw;
}
.image{
width:100%;
height: 100%;
}
.video{
width:100%;
height: 100%;
object-fit: fill
}
.shape{
width:100%;
height: 100%;
}
</style>
### FASTCONTENT UNIVERSAL SCRIPT
Este script se debe copiar del repo proporcionado anteriormente.
<!-- SCRIPT UNIVERSAL GENERICO DE FASTCONTENT HTML5 - INCLUYE API CONTENT & JQUERY -->
<script>
…… (añadir aquí el código del repo)
</script>>
### PERSONALIZACION DE FASTCONTENT
<!-- SCRIPT ESPECIFICO PARA ESTE CONTENIDO -->
<script>
…… (añadir aquí el código específico para el fastcontent)
</script>
### PERSONALIZACION EVENTOS EN RELACION A PLAYER
<!-- SCRIPTS ADICIONAL PARA EJECUTAR EN EL MOMENTO DE RENDERIZADO (PLAY) DEL CONTENIDO -->
<!-- el evento onRender se disparará cuando el player haga play del contenido -->
<script>
function onRender(slide_index){
console.log("Fastcontent is rendering slide : "+slide_index);
...(añadir aquí el código necesario para ser ejecutado cuando el player dispara el contenido)
}
</script>
### BODY
Crear las variables necesarias y correctamente seteadas que serán reflejadas en el XML.
<div id="background" class=""> </div>
<div id="producto" class="text"> </div>
<div id="imagen"> </div>
<div id="precio" class="text" style="opacity: 0;"> </div>
<div id="descripcion" class="text"> </div>
<div id="promo"> </div>
Contenidos de URL
En los casos en que se requiera cargar como contenido una página web sobre el player y la precarga de la misma afecta a la emisión de sus elementos, se ha creado un contenido para que esta carga sea compatible con el player Admira. El contenido está compuesto de una serie de archivos, incluido el acceso con la api del player, para la carga de los contenidos según su emisión. En uno de ellos debemos agregar la URL que queremos emitir y subir el contenido como HTML + adjuntos.
Ejemplo:

Puede solicitar el contenido al departamento de qa@admira.com.
Una vez tenemos el contenido solo debemos abrir el archivo variables.json

Y a continuación modificar la URL por la del contenido que se quiera subir.
Hecho esto, debemos subir el contenido a plataforma como HTML + adjuntos.