France Televisions has been involved in HbbTV since 2010, and our frontend developers learned its limitations "the hard way" over the past 5 years. In the previous post we discussed what tools and good practices HbbTV developers should follow. In this post we list the main bugs and limitations we encountered on real TV sets.
Bugs and limitations
1HbbTV Headers
HbbTV applications must have a doctype, and a specific content-type. If these are not specified correctly, applications will crash on 2012 Philips models.
Here is the information that must be include:
- a Content-Type header in the HTTP response
|
- a Content-Type header in the meta HTML tags
|
- the HbbTV 1.1 doctype
|
2JavaScript
keycodes templates
At the bottom of the page you will find a list of hex codes for each key, and codes for masks grouping: http://www.francescpinyol.cat/hbbtv.html
JSON
Some javascript bugs are known on some TVs (2011 Samsung ). This is the case of the "JSON.parse ()" function that is not supported by some manufacturers, however, a simple "eval" will solve the problem or the use a third party library like json2.
Dynamically loading libraries
The dynamic insertion of "script" tags via javascript is likely to crash some old TVs (Sony, 2011, Samsung 2011, ...).
Playing videos
For Sony TVs it is mandatory to remove the "object" tag and create a new one to play other videos.
SetAttribute
Some TVs do not support this feature. It is then necessary to recover the element in the DOM and update the desired property directly.
Example:
|
Inheritance: Parent
The use of "parent" in JavaScript prototyping is not implemented on some TVs and the following code will not work on the entire installed base:
|
INNERHTML Crash (SYNTAX_ERR: DOM Exception 12)
When you dynamically create a DOM object (document.createElement), if you make a innerHTML of a string containing an HTML entity like "&" or " ", some TVs will crash immediately. Among the affected TVs: 2013 LG models and 2013 Toshiba models.
|
The problem will come from an internal encoding error. Indeed, the browser internal engine uses an XML library and an XSL validation, validation that is highly sensitive to encoding ...
The solution is to convert these HTML entities into something else, or using, where possible, the innerText function (when supported).
Details in this thread : http://stackoverflow.com/questions/4162270/dom-exception-when-assigning-html-entities-to-innerhtml
CSS classes and pseudo-elements
See below.
DOM
CSS
On 2011 Samsung TVs, it is imperative to load the CSS before the DOM. CSS loaded after the DOM will simply not be interpreted!
The rendering of a page is not always automatically refreshed by some TVs (2011 Samsung ) when updating the DOM or CSS.
To force a refresh of the rendering, simply insert a new image in the DOM: a URL to a simple file of one pixel (to be very light) post-fixed with a timestamp (to be "new") is enough.
On some TVs, such as 2011 Samsung models, a very strange side-effect is to crash the TV. If you specify :before :after CSS rules on some DOM elements, if you then try to assign dynamically, via javascript, more than three CSS classes, one of which involves a change in the pseudo-element, the TV reboots.
Security
Cross Domain Policy
To work around problems related to cross domain policy limitations on some TVs, it is required that all AJAX requests are performed in the same domain. To do this there are two methods, either using a reverse proxy (at the varnish level or at the Apache level) or using a PHP script that will do the same job.
Storage
1Cache
Let put it simply, most TVs do not have a local cache, for the simple reason that having a cache means having some available storage, and that storage is expensive and must be managed! So to make it simple no cache, hence the usefulness of a varnish or a CDN to offload charge on the frontend origin especially on static contents.
2Cookies
Cookies, you know them, you overuse them, on some TVs they have the tendency to disappear as soon as you turn off the TV. This is particularly the case with 2011 Samsung models and also on other models but more randomly. You should not giving up on using them, just be aware that you should not rely on them for essential features.
Identifying a TV
This is a subject frequently discussed. It is impossible to identify a unique HbbTV TV set. We have no access to the MAC address, or to a serial number. Remains the possibility of identifying users from their IP addresses. However many ISPs (such as Orange in France) use dynamic IP addresses. One should add that in France in 2012 there are 2.3 televisions per household! So with an IP one would potentially divide the number of users by as many users.
Vidéo
1Format
Only MPEG4 Progressive download videos is currently supported by all vendors.
Some TVs support HLS streaming, although it is not part of the HbbTV specs. Based on our tests, Samsung, LG and Sony devices support live HLS feeds in HbbTV apps.
DASH is part of the HbbTV 1.5 protocol, however it is still in the early stages ; in particular live DASH feeds are not always correctly supported by TVs. Based on our tests only recent Panasonic and Sony TVs support Live streaming using DASH.
2Controls
There are some limitations in playback controls for a video on demand.
Brand
|
Fast Forward
|
Rewind
|
---|---|---|
Samsung | Only when video is paused | Only when video is paused |
Philips | Only when video is paused | Only when video is paused |
Sony | Not available | Not available |
3Broadcast
On Philips TV, the bindToCurrentChannel() function triggers a channel switch and not the activation of the live feed in the broadcast object.
-----------------------------------------------
Bugs et limitations
Cette section vise à présenter les bugs et limitations techniques auxquels nous avons du faire face
1Headers HbbTV
Les applications HbbTV doivent avoir un doctype et content-type particulier. Si ils ne sont pas spécifiés correctement, les applications crasheront sur Philips 2012.
Voici les informations à mettre :
- un header Content-Type dans la réponse HTTP
<?php header( 'Content-Type: application/vnd.hbbtv.xhtml+xml; charset=UTF-8' ); ?> |
- un header Content-Type dans les balises meta HTML
< meta http-equiv = "content-type" content = "Content-Type: application/vnd.hbbtv.xhtml+xml; charset=UTF-8" /> |
- le doctype HbbTV 1.1
<!DOCTYPE html PUBLIC "-//HbbTV//1.1.1//EN" "http://www.hbbtv.org/dtd/HbbTV-1.1.1.dtd"> |
2JavaScript
Masques de keycodes
En bas de page se trouve une liste des codes hexadécimaux pour chaque touche, ainsi que les codes pour les masques les regroupant :http://www.francescpinyol.cat/hbbtv.html
JSON
Certains bugs javascript sont connus sur certains téléviseurs (Samsung 2011). C’est le cas de la fonction « JSON.parse() » qui n’est pas supporté chez certains constructeurs, toutefois un simple « eval » pourra palier le problème ou l’utilisation d’une librairie tierce comme https://github.com/douglascrockford/JSON-js/blob/master/json2.js.
Ajout de fichiers dynamiquement
L’insertion de balises « script » via javascript est susceptible de faire planter certains téléviseurs
(Sony 2011, Samsung 2011, …).
Lecture de vidéos
Sur les téléviseurs Sony il est obligatoire de supprimer la balise « object » et d’en créer une nouvelle pour enchaîner deux vidéos !
SetAttribute
Certains téléviseurs ne supportent pas cette fonctionnalité. Il est alors nécessaire de récupérer l’élément dans le DOM et de modifier la propriété souhaité directement.
Exemple :
var myInput = document.getElementById( "myInput" ); // Pas ça => myInput.setAttribute("name", "new_name"); myInput.name = "new_name" ; |
Héritage : parent
L’utilisation du « parent » dans le prototypage Javascript n’est pas implémenté sur certains téléviseurs ainsi le code suivant ne pourra pas fonctionner sur l’ensemble du parc :
// Inherit from the parent class /** * WRONG * Ftv.Utils.PlayApiClient.prototype = Object.create(Ftv.Utils.ApiClient.prototype); * Ftv.Utils.PlayApiClient.prototype.constructor = Ftv.Utils.PlayApiClient; * Ftv.Utils.PlayApiClient.prototype.parent = Ftv.Utils.ApiClient.prototype; */ // Inherit from the parent class /** * GOOD */ Ftv.Utils.PlayApiClient.prototype = new Ftv.Utils.ApiClient(playApiBaseUrl); Ftv.Utils.PlayApiClient.prototype.constructor = Ftv.Utils.PlayApiClient; |
INNERHTML (SYNTAX_ERR: DOM Exception 12)
Lorsque vous créez dynamiquement un objet DOM (document.createElement), si vous y faites un innerHTML d'une chaine de caractère (string) contenant une entité HTML (html entity) comme "&" ou " ", certaines télés plantent directement. Parmi les télé en question, il y a, LG 2013 et Toshiba 2013.
// Exemple de code qui plante : var div = document.createElement( 'div' ); div.id = 'div' ; div.innerHTML = ' ' ; |
Le problème viendra d'une erreur d'encodage en interne. En effet, dans le moteur interne du navigateur, on fait appel à une librairie XML et une validation XSL, validation très sensible aux encodages...
La solution sera dans la conversion de ces entités HTML en autre chose, ou bien dans l'utilisation, si possible, du innerText (quand supporté).
On en parle ici : http://stackoverflow.com/questions/4162270/dom-exception-when-assigning-html-entities-to-innerhtml
Classes CSS et pseudo-éléments
Voir la rubrique "CSS".
DOM
CSS
Sur les téléviseurs samsung 2011, il est impératif de charger les CSS avant le DOM. Les CSS chargés à postériori du DOM ne seront tout simplement pas interprétés !
Le rendu d’une page n’est pas toujours recalculé automatiquement par certains téléviseurs (Samsung 2011) à la modification du DOM ou des CSS.
Pour forcer un nouveau calcul du rendu, il suffit d’insérer une nouvelle image dans le DOM : un simple fichier d’un pixel (pour qu’il soit léger) post fixé du timestamp (pour qu’il soit « nouveau ») suffit.
Sur certains téléviseurs, comme Samsung 2011, un effet très étrange peut provoquer le plantage de la télé. Sur les éléments DOM pour lesquels vous spécifiez des règles CSS de :before / :after, si vous essayez d'assigner dynamiquement, via javascript, plus de trois classes CSS, dont une qui implique un changement de pseudo-élément, la télé redémarre.
Sécurité
Cross Domain Policy
Il est recommandé que toutes les requêtes AJAX soient réalisées sur le même domaine pour résoudre les problèmes de ce type. Pour y parvenir, il existe deux méthodes : ou en utilisant un reverse proxy ( varnish level ou Apache level) ou en utilisant un script PHP qui aura le même effet.
Stockage
1Cache
Faisons simple, la plupart des téléviseurs n’ont pas de cache, pour la simple est bonne raison que du cache ça veut dire du stockage, et que le stockage quoi que vous en pensiez ça coute cher et surtout il faut le gérer ! Donc c’est simple pas de cache, d’où l’utilité d’un varnish ou d’un CDN pour offloader la charge de l’origine surtout sur les contenus statiques.
2Cookies
Les cookies, vous les connaissez, vous en abusez, sur les certains téléviseurs ils ont la fâcheuse tendance à disparaitre dès qu’on éteint le téléviseur. C’est notamment le cas chez Samsung 2011 et des fois chez d’autres mais de façon plus aléatoire. Il ne faut pas pour autant renoncer à leur utilisation, juste être conscient qu’il ne faut pas en avoir un besoin « vital »
Identification d’un téléviseur
C’est un sujet maintes fois abordés. Il est impossible d’identifier un téléviseur de façon unique en HbbTV. Nous ne disposons pas d’accès à l’adresse MAC, où à un numéro de série. Reste la possibilité d’identifier par IP les utilisateurs. Mais bon nombre de FAI dont Orange utilise des adresses IP flottantes. A cela il faut rajouter qu’en France en 2012 on dénombre 2,3 téléviseurs par foyer ! Donc avec une IP on diviserait potentiellement par autant le nombre d’utilisateurs.
Vidéo
1Format
Seul le MPEG4 Progressive download est supporté par tous les constructeurs.
DASH n’en est qu’à ces balbutiements et il n’y a aucun firmware 1.5 largement répandu. Actuellement seul Philips sur sa gamme 2013 en possède. Sony devrait déployer un firmware avant fin 2013.
Les Samsung 2013 savent lire un flux HLS en live mais avec un seul débit.
Les LG 2013 savent lire un flux HLS.
2Contrôles
On dénombre un certain nombre de limitation dans les contrôles de la lecture d’une vidéo en replay.
Marque
|
Forward
|
Backward
|
---|---|---|
Samsung | Uniquement en pause | Uniquement en pause |
Philips | Uniquement en pause | Uniquement en pause |
Sony | Non disponible | Non disponible |
3Broadcast
Sur Phillips, la fonction bindToCurrentChannel() déclenche un zapping et non l’activation du live dans l’objet broadcast.