Simplified Metadataplayer instantiation new-model
authorveltr
Tue, 05 Jun 2012 20:55:42 +0200
branchnew-model
changeset 910 b9f1bd52df9a
parent 909 aa0e42229784
child 911 0df8104bb3d5
Simplified Metadataplayer instantiation
doc/architecture.fr.md
doc/general.fr.md
sbin/doc/markdown2dokuwiki.py
src/js/defaults.js
src/js/iframe_embed/embedder.js
src/js/init.js
src/js/serializers/PlatformAnnotateSerializer.js
src/js/serializers/PlatformSerializer.js
src/js/serializers/ldt.js
src/js/serializers/ldt_annotate.js
src/widgets/Mediafragment.js
test/jwplayer.htm
test/mashup/player-local.htm
test/mashup/player.htm
test/test-config.js
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/architecture.fr.md	Tue Jun 05 20:55:42 2012 +0200
@@ -0,0 +1,316 @@
+# Architecture du Metadataplayer #
+
+ATTENTION !
+Cette documentation se réfère à la v.3 du Metadataplayer, actuellement disponible dans la branche **new-model** du repository
+http://www.iri.centrepompidou.fr/dev/hg/metadataplayer
+
+## Bibliothèques extérieures ##
+
+Les bibliothèques utilisées par le Metadataplayer sont regroupées dans *src/libs*
+
+### LAB.js ###
+
+- **Fichier**: LAB.min.js
+- **Licence**: MIT.
+- **Rôle**: Charge les autres bibliothèques extérieures et les widgets.
+- **Utilisé par**: Code principal.
+- Du fait de ce mode de chargement, il s’agit de la seule bibliothèque nécessaire au moment de l’initialisation du code.
+- **Site**: http://labjs.com/
+
+### jQuery ###
+
+- **Fichier**: jquery.min.js
+- **Licence**: Double, MIT et GPL.
+- **Rôle**: Gère les actions du code sur la structure du document HTML (DOM)
+- **Utilisé par**: Code principal et tous les widgets.
+- **Site**: http://jquery.org/
+
+### jQuery UI ###
+
+- **Fichiers**: jquery-ui.min.js et jquery-ui.css
+- **Licence**: Double, MIT et GPL.
+- **Rôle**: Fournit des éléments d’interface utilisateurs, tels que *Sliders*
+- **Utilisé par**: Widgets, Controller (pour le volume) et Slider (pour le *Slider de progression*)
+- **Site**: http://jqueryui.com/
+
+### Underscore ###
+
+- **Fichier**: underscore-min.js
+- **Licence**: MIT.
+- **Rôle**: Fournit des fonctionnalités orientées programmation fonctionnelle pour manipuler tableaux, objets et fonctions.
+- **Utilisé par**: Code principal et widgets.
+- **Site**: http://documentcloud.github.com/underscore/
+
+### Popcorn ###
+
+- **Fichier**: popcorn-complete.min.js
+- **Licence**: MIT.
+- **Rôle**: Fournit une gestion de la lecture de vidéos HTML5.
+- **Utilisé par**: Players HTML5 et Youtube, ainsi que pour la communication avec le reste du Metadataplayer lorsque l’un de ces players est utilisé.
+- **Site**: http://popcornjs.org/
+
+### Mustache ###
+
+- **Fichier**: mustache.js
+- **Licence**: MIT.
+- **Rôle**: Permet de remplir des gabarits (*templates*) HTML.
+- **Utilisé par**: widgets.
+- **Site**: http://mustache.github.com/
+
+### Raphael ###
+
+- **Fichier**: raphael-min.js
+- **Licence**: MIT.
+- **Rôle**: Fournit une interface de dessin vectoriel (utilise SVG ou VML selon les navigateurs)
+- **Utilisé par**: Widgets et Sparkline
+- **Site**: http://raphaeljs.com/
+
+### ktbs4js Tracemanager ###
+
+- **Fichier**: tracemanager.js
+- **Licence**: LGPL.
+- **Rôle**: Permet de s’interfacer avec le système de gestion de traces KTBS, créé par Olivier Aubert (Liris)
+- **Utilisé par**: TraceWidget
+- **Site**: http://github.com/oaubert/ktbs4js
+
+## Code principal (core) du Metadataplayer ##
+
+Dans la version *release* du metadataplayer, les fichiers Javascript et CSS sont répartis entre le *core* et les *widgets*.
+
+*LdtPlayer-core.js* est compilé à partir de plusieurs fichiers Javascript situés (sauf LAB.min.js) dans *src/js*:
+
+### header.js ###
+
+Contient les crédits du Metadataplayer, ainsi que les informations sur la licence (*CeCILL-C*)
+
+### LAB.js ###
+
+cf. Bibliothèques extérieures.
+
+### init.js ###
+
+Définit l’objet *IriSP*, qui sert d’espace de nommage pour tout le Metadataplayer.
+Contient la classe *IriSP.Metadataplayer*, dont l’instanciation est la porte d’entrée principale du code.
+
+### pop.js ###
+
+Contient *IriSP.PopcornReplacement*, c’est à dire une version simplifiée de Popcorn pour communiquer avec des lecteurs vidéos non-supportés par Popcorn.
+Au moment de la création de cette partie, l’interfaçage Popcorn-jwplayer n’était pas satisfaisant, à remplacer éventuellement par de vrais players/plugins pour Popcorn.
+
+### utils.js ###
+
+Contient quelques fonctions utilitaires, telles que *IriSP.loadCss*, qui est l’équivalent pour les fichiers CSS de LAB.js.
+
+### model.js ###
+
+Contient les classes de gestion du modèle de données Cinelab, regroupées sous l’espace de nommage *IriSP.Model*.
+
+### widgets.js ###
+
+Contient la classe de base *IriSP.Widgets.Widget*, qui fournit les fonctionnalités de base pour les widgets.
+
+### players ###
+
+Les fichiers de ce répertoire permettent d’interfacer le *Popcorn Replacement* (cf. *pop.js*) avec des lecteurs vidéo tiers.
+
+Existent actuellement:
+
+1. **player.jwplayer**, pour communiquer avec JwPlayer, utilisé pour lire des flux RTMP sur la plateforme *Ligne de temps*
+2. **player.dailymotion**, pour lire des vidéos du *Youtube à la française*
+3. **player.allocine**, pour le player de allocine.net
+4. **player.mashup**, pour le player de bout à bout Flash créé par Thibaut Cavalié.
+
+### serializers ###
+
+Les Sérialiseurs servent d’interface entre les formats de données utilisés pour les échanges avec les serveurs.
+
+Deux sérialiseurs existent à l’heure actuelle:
+
+1. **ldt**, pour lire les flux JSON fournis par la plateforme *Lignes de Temps*.
+2. **ldt\_annotate**, pour communiquer avec l’API d’ajout d’annotations de la plateforme, dont le format est légèrement différent.
+
+## Widgets ##
+
+Les Widgets sont des modules, visibles ou non, permettant de rajouter des fonctionnalités au Metadataplayer.
+
+Situés dans le répertoire *src/widgets*, ils contiennent nécessairement un fichier de code *NomDuWidget.js* et, optionnellement un fichier de style *NomDuWidget.css*
+
+#### Options courantes ####
+
+- **metadata**, source de métadonnées, sous la forme { url: *URL de la source de données*, type: *Type de sérialiseur utilisé* }
+- **container**, à utiliser seulement si le widget ne doit pas être aligné en dessous des autres widgets, pour spécifier l’ID de l’élément HTML dans lequel il doit être affiché.
+- **annotation\_type**, dans les widgets affichant des annotations. Cette option peut prendre les valeurs suivantes:
+    - Chaîne de caractères: prend en compte les types d’annotations dont le titre contient la chaîne. Exemple: "chap" permet notamment d’afficher les annotations dans le type d’annotation "Chapitrage"
+    - Tableau de chaînes: pour prendre en compte plusieurs types d’annotations
+    - false: pour prendre en compte toutes les annotations du projet
+- **requires**, qui permet d’encapsuler un widget dans un autre.
+
+Voici la liste des widgets actuellement disponibles, avec leurs options:
+
+### HelloWorld ###
+
+- **Rôle**: Widget d’exemple démontrant l’API de création de widgets
+- **Options**:
+    - **text**: (défaut: "world"), texte à afficher après "Hello, "
+- Utilise un fichier CSS: oui
+
+### Slider ###
+
+- **Rôle**: Barre de progression et *Slider* indiquant la position de la tête de lecture vidéo et permettant de la déplacer.
+- **Options**:
+   - **minimized\_height**: (défaut: 4), hauteur en pixels du *Slider* en mode minimisé
+   - **maximized\_height**: (défaut: 10), hauteur en pixels du *Slider* en mode maximisé (lorsque la souris passe dessus)
+   - **minimize\_timeout**: (défaut: 1500), durée en millisecondes avant que le *Slider* ne se minimise. À une valeur de 0, le *Slider* ne se minimise plus.
+- Utilise la bibliothèque: jQuery UI
+- Utilise un fichier CSS: oui
+
+### Controller ###
+
+- **Rôle**: Boutons Lecture/Pause, Rechercher, Ouvrir l’annotateur et contrôle du volume
+- **Options**:
+    - **disable\_annotate\_btn**: (défaut: false), permet de désactiver le bouton d’ouverture de l’annotateur s’il est à *true*
+    - **disable\_search\_btn**: (défaut: true), permet de désactiver le bouton de recherche d’annotations
+- Utilise la bibliothèque: jQuery UI
+- Utilise un fichier CSS: oui
+
+### Arrow ###
+
+- **Rôle**: Dessine la flèche indiquant la position de l’annotation
+- **Options**:
+    - **arrow\_height**: (défaut: 16), hauteur en pixels de la flèche
+    - **arrow\_width**: (défaut: 24), largeur en pixels de la flèche
+    - **base\_height**: (défaut: 0), hauteur entre le bas de la flèche et le bas du widget. Nécessaire si l’on souhaite faire un widget aux bords arrondis.
+    - **base\_curve**: (défaut: 0), rayon de courbure des bords arrondis du widget.
+    - **fill\_url**: URL d’une image de remplissage pour le widget
+    - **fill\_color**: (défaut: "#ffffff" = blanc), couleur de remplissage du widget. Peut-être remplacé par un dégradé sous la forme angle en degrés-couleur de début-couleur de fin, ex: "90-#000-#fff"
+    - **stroke\_color**: (défaut: "#b7b7b7" = gris), couleur de la bordure du widget.
+    - **stroke\_width**: (défaut: 1.5), épaisseur en pixels de la bordure du widget.
+    - **animation\_speed**: (défaut: 20), vitesse de déplacement de la flèche.
+    - **pilot\_widget**: (défaut: "Annotation"), widget commandant la position de la flèche.
+- Utilise la bibliothèque: Raphael
+- Utilise un fichier CSS: non
+
+### Annotation ###
+
+- **Rôle**: Affiche les informations relatives à une annotation au moment où celle-ci est jouée
+- **Options**:
+    - **annotation\_type**: (défaut: "chapitrage"), cf. *Options courantes*, plus haut.
+    - **show\_top\_border**: (défaut: false), afficher ou non la bordure en haut du widget (au cas où il est utilisé sans/avec le widget *Arrow*)
+    - **site\_name**: "Lignes de Temps", nom du site à afficher lorsque l’on clique sur les boutons de partage pour réseaux sociaux.
+- Utilise un fichier CSS: oui
+
+### CreateAnnotation ###
+
+- **Rôle**: Permet de créer une annotation en affichant un formulaire
+- **Options**:
+    - **show\_title\_field**: (défaut: true), affiche un champ permettant de saisir le titre de l’annotation.
+    - **creator\_name**: nom d’utilisateur du créateur de l’annotation.
+    - **creator\_avatar**: URL de l’image de profil du créateur de l’annotation.
+    - **tags**: (défaut: false), liste des tags à afficher, sous la forme d’un tableau d’objets type [ { id: "tag-001", title: "" } ]. Si la valeur est false, affiche les tags les plus utilisés du projet.
+    - **max\_tags**: (défaut: 8), nombre de tags à afficher.
+    - **polemics**: boutons polémiques à afficher, sous la forme d’un tableau d’objets indiquant mot-clé à ajouter, couleur du fond du bouton, couleur du bouton, ex: [ { keyword: "++", background\_color: "#00a000", text\_color: "#ffffff" } ]
+    - **annotation\_type**: (défaut: "Contributions"), cf. *Options courantes*, plus haut.
+    - **api\_serializer**: (défaut: "ldt\_annotate"), sérialiseur à utiliser pour l’envoi des annotations.
+    - **api\_endpoint\_template**: URL de l’API, où {{id\}\} est remplacé par l’ID du projet, ex: "http://ldt.iri.centrepompidou.fr/ldtplatform/api/ldt/annotations/{{id}}.json".
+    - **api\_method**: (défaut: "PUT"), méthode HTTP utilisée pour envoyer les annotations. La plateforme *Lignes de temps* utilise PUT, mais cette méthode devrait être réservée pour la création d’une ressource dont l’URL est connue à l’avance.
+    - **close\_widget\_timeout**: (défaut: 0), durée en millisecondes avant que le widget ne soit refermé après l’envoi d’une annotation. Si la valeur est 0, le widget ne se referme pas.
+- Utilise un fichier CSS: oui
+
+### Polemic ###
+
+- **Rôle**: Affiche la *timeline polémique*, c’est à dire les tweets colorés en fonction de la syntaxe polémique. Selon le volume de tweets, deux modes de représentation existent:
+    - Avec un faible volume, les tweets sont des carrés dessinés individuellement.
+    - Avec un volume élevé, les colonnes présentent les volumes agrégés de tweets par couleur.
+- **Options**:
+    - **element\_width**: (défaut: 5), largeur en pixels d’une tranche de tweets.
+    - **element\_height**: (défaut: 5), hauteur en pixels d’un tweet, en mode faible volume.
+    - **max\_elements**: (défaut: 15), nombre de tweets dans une colonne à partir duquel le mode de représentation change.
+    - **annotation\_type**: (défaut: "tweet"), cf. *Options courantes*, plus haut.
+    - **defaultcolor**: (défaut: "#585858" = gris), couleur des tweets qui n’ont pas d’annotation polémique.
+    - **foundcolor**: (défaut: "#fc00ff" = mauve), couleur d’affichage des tweets correspondant à un résultat de recherche.
+    - **polemics**: couleurs polémiques à afficher, en fonction d’une recherche de termes, type [ { keywords: [ "++" ], color: "#1D973D" } ]
+- Utilise un fichier CSS: oui
+
+### Tweet ###
+
+- **Rôle**: Affiche furtivement le contenu d’un tweet
+- **Options**:
+    - **hide_timeout**: (défaut: 5000), durée en millisecondes, avant que l’affichage du Tweet ne se referme
+    - **polemics**: identique au paramètre *polemics* du widget *Polemic*
+
+### Sparkline ###
+
+- **Rôle**: Affiche une courbe indiquant l’évolution du volume d’annotations au cours du temps.
+- **Options**:
+    - **annotation\_type**: cf. *Options courantes*, plus haut.
+    - **lineColor**: (défaut: "#7492b4" = gris-bleu), couleur de la courbe
+    - **fillColor**: (défaut: "#aeaeb8" = gris), couleur de la surface sous la courbe
+    - **lineWidth**: (défaut: 2), épaisseur en pixels de la courbe
+    - **slice\_count**: (défaut: 20), nombre des tranches horaires dans lesquelles les annotations sont réparties pour calculer la courbe
+    - **height**: (défaut: 50), hauteur en pixels de la courbe
+    - **margin**: (défaut: 5), marge en pixels au-dessus de la courbe
+- Utilise la bibliothèque: Raphael
+- Utilise un fichier CSS: non
+
+### Tagcloud ###
+
+- **Rôle**: Affiche un nuage de mots-clés
+- **Options**:
+    - **include\_titles**: (défaut: true), utiliser le contenu du champ titre des annotations pour calculer le nuage de mots-clés.
+    - **include\_descriptions**: (défaut: true), utiliser le contenu du champ description des annotations pour calculer le nuage.
+    - **include\_tag\_texts**: (défaut: true), utiliser les textes des tags liés aux annotations pour calculer le nuage de mots-clés.
+    - **tag\_count**: (défaut: 30), nombre maximum de mots-clés à afficher.
+    - **stopword\_language**: (défaut: "fr"), code de langue correspondant à une liste de mots vides à exclure du nuage.
+    - **custom\_stopwords**: (défaut: []), liste de mots-vides à exclure du nuage.
+    - **exclude\_pattern**: (défaut: false), expression régulière à exclure du nuage.
+    - **annotation\_type**: (défaut: false), cf. *Options courantes*, plus haut. Concerne les annotations dont les contenus sont utilisés pour calculer le nuage.
+    - **segment\_annotation\_type**: (défaut: false), permet de définir la segmentation du nuage de mots-clés et de calculer un nuage pour chaque segment du type d’annotation choisi. Lorsque ce paramètre est à *false*, un seul nuage est calculé pour toute la durée de la vidéo.
+    - **min\_font\_size**: (défaut: 10), taille de caractères (en pixels) pour le mot le moins fréquent.
+    - **max\_font\_size**: (défaut: 26), taille de caractères (en pixels) pour le mot le plus fréquent.
+- Utilise un fichier CSS: oui
+
+### AnnotationsList ###
+
+- **Rôle**: Affiche une liste d’annotations
+- **Options**:
+    - **ajax\_url**: (défaut: false), spécifie un gabarit d’URL lorsque les annotations doivent être chargées par une API spécifique (API de segment). Dans l’URL, {{media}} sera remplacé par l’ID du média, {{begin}} par le *timecode* de début en millisecondes, {{end}} par le *timecode* de fin en millisecondes. Si le réglage est à *false*, les annotations affichées seront celles chargées à l’initialisation du Widget. Sur la plateforme *Lignes de Temps*, cette URL est http://ldt.iri.centrepompidou.fr/ldtplatform/api/ldt/segments/{{media}}/{{begin}}/{{end}}?callback=?
+    - **ajax\_granularity**: (défaut: 300000 ms = 5 minutes), spécifie la durée qui doit être chargée par l’API de segment, de part et d’autre du timecode courant (cf. ci-dessus) 
+    - **default\_thumbnail**: imagette à afficher par défaut à côté d’une annotation lorsque l’annotation n’a pas d’imagette.
+    - **foreign\_url**: spécifie un gabarit d’URL lorsque l’annotation n’a pas d’information d’URL et que l’annotation est dans un autre projet. Dans l’URL, {{media}} sera remplacé par l’ID du média, {{project}} par l’ID du projet, {{annotationType}} par l’ID du type d’annotation, {{annotation}} par l’ID de l’annotation. Sur la plateforme *Lignes de temps*, cette URL est http://ldt.iri.centrepompidou.fr/ldtplatform/ldt/front/player/{{media}}/{{project}}/{{annotationType}}#id={{annotation}}
+    - **annotation\_type**: (défaut: false), cf. *Options courantes*, plus haut.
+    - **refresh\_interval**: (défaut: 0), intervalle auquel le widget recharge en Ajax la liste des annotations (que l’on utilise l’API de segment ou non)
+    - **limit\_count**: (défaut: 10), nombre maximum d’annotations à afficher simultanément.
+    - **newest\_first**: (défaut: false), *true*: classe les annotations par ordre antéchronologique de création, *false*: classe les annotations par ordre chronologique de leur timecode vidéo.
+- Utilise un fichier CSS: oui
+
+### Media ###
+
+- **Rôle**: Affiche le média en cours, ainsi que la liste des autres médias du projet. Utilisé principalement pour les mashups
+- **Options**:
+    - **default\_thumbnail**: imagette à afficher par défaut à côté d’un média lorsque le média n’a pas d’imagette.
+    - **media\_url\_template**: spécifie un gabarit d’URL lorsque le média n’a pas d’information d’URL, par exemple: "http://ldt.iri.centrepompidou.fr/ldtplatform/ldt/front/player/{{media}}/"
+- Utilise un fichier CSS: oui
+
+### Tooltip ###
+
+- **Rôle**: Affiche une infobulle, utilisé uniquement comme *widget inclus* dans d’autres widgets.
+- Pas d’options
+- Utilise un fichier CSS: oui
+
+### Trace ###
+
+- **Rôle**: Envoi des traces au serveur KTBS
+- **Options**:
+    - **js\_console**: (défaut: false), écriture ou non des traces dans la console du navigateur.
+    - **url**: (défaut: "http://traces.advene.org:5000/"), URL du serveur de traces
+    - **requestmode**: (défaut: "GET"), méthode HTTP utilisée pour l’envoi des traces (seul *"GET"* permet le *cross-domain*).
+    - **syncmode**: (défaut: "sync"), envois groupés (mode *"delayed"*) ou non (*"sync"*) des traces
+- Utilise la bibliothèque: ktbs4js tracemanager
+- Utilise un fichier CSS: non
+
+### Mediafragment ###
+
+- **Rôle**: Gère les URLs à la norme *Mediafragment*: change la position de la tête de lecture en fonction de l’URL et inversement.
+- Une URL finissant par #id=*id de l’annotation* pointe sur une annotation, par #t=*temps en secondes* vers un timecode de la vidéo.
+- Pas d’options
+- Utilise un fichier CSS: non
--- a/doc/general.fr.md	Tue Jun 05 17:55:24 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,314 +0,0 @@
-# Architecture générale du Metadataplayer #
-
-ATTENTION !
-Cette documentation se réfère à la v.3 du Metadataplayer, actuellement disponible dans la branche **new-model** du repository
-http://www.iri.centrepompidou.fr/dev/hg/metadataplayer
-
-## Bibliothèques extérieures ##
-
-Les bibliothèques utilisées par le Metadataplayer sont regroupées dans *src/libs*
-
-### LAB.js ###
-
-- **Fichier**: LAB.min.js
-- **Licence**: MIT.
-- **Rôle**: Charge les autres bibliothèques extérieures et les widgets.
-- **Utilisé par**: Code principal.
-- Du fait de ce mode de chargement, il s’agit de la seule bibliothèque nécessaire au moment de l’initialisation du code.
-- **Site**: http://labjs.com/
-
-### jQuery ###
-
-- **Fichier**: jquery.min.js
-- **Licence**: Double, MIT et GPL.
-- **Rôle**: Gère les actions du code sur la structure du document HTML (DOM)
-- **Utilisé par**: Code principal et tous les widgets.
-- **Site**: http://jquery.org/
-
-### jQuery UI ###
-
-- **Fichiers**: jquery-ui.min.js et jquery-ui.css
-- **Licence**: Double, MIT et GPL.
-- **Rôle**: Fournit des éléments d’interface utilisateurs, tels que *Sliders*
-- **Utilisé par**: Widgets, Controller (pour le volume) et Slider (pour le *Slider de progression*)
-- **Site**: http://jqueryui.com/
-
-### Underscore ###
-
-- **Fichier**: underscore-min.js
-- **Licence**: MIT.
-- **Rôle**: Fournit des fonctionnalités orientées programmation fonctionnelle pour manipuler tableaux, objets et fonctions.
-- **Utilisé par**: Code principal et widgets.
-- **Site**: http://documentcloud.github.com/underscore/
-
-### Popcorn ###
-
-- **Fichier**: popcorn-complete.min.js
-- **Licence**: MIT.
-- **Rôle**: Fournit une gestion de la lecture de vidéos HTML5.
-- **Utilisé par**: Players HTML5 et Youtube, ainsi que pour la communication avec le reste du Metadataplayer lorsque l’un de ces players est utilisé.
-- **Site**: http://popcornjs.org/
-
-### Mustache ###
-
-- **Fichier**: mustache.js
-- **Licence**: MIT.
-- **Rôle**: Permet de remplir des gabarits (*templates*) HTML.
-- **Utilisé par**: widgets.
-- **Site**: http://mustache.github.com/
-
-### Raphael ###
-
-- **Fichier**: raphael-min.js
-- **Licence**: MIT.
-- **Rôle**: Fournit une interface de dessin vectoriel (utilise SVG ou VML selon les navigateurs)
-- **Utilisé par**: Widgets et Sparkline
-- **Site**: http://raphaeljs.com/
-
-### ktbs4js Tracemanager ###
-
-- **Fichier**: tracemanager.js
-- **Licence**: LGPL.
-- **Rôle**: Permet de s’interfacer avec le système de gestion de traces KTBS, créé par Olivier Aubert (Liris)
-- **Utilisé par**: TraceWidget
-- **Site**: http://github.com/oaubert/ktbs4js
-
-## Code principal (core) du Metadataplayer ##
-
-Dans la version *release* du metadataplayer, les fichiers Javascript et CSS sont répartis entre le *core* et les *widgets*.
-
-*LdtPlayer-core.js* est compilé à partir de plusieurs fichiers Javascript situés (sauf LAB.min.js) dans *src/js*:
-
-### header.js ###
-
-Contient les crédits du Metadataplayer, ainsi que les informations sur la licence (*CeCILL-C*)
-
-### LAB.js ###
-
-cf. Bibliothèques extérieures.
-
-### init.js ###
-
-Définit l’objet *IriSP*, qui sert d’espace de nommage pour tout le Metadataplayer.
-Contient la classe *IriSP.Metadataplayer*, dont l’instanciation est la porte d’entrée principale du code.
-
-### pop.js ###
-
-Contient *IriSP.PopcornReplacement*, c’est à dire une version simplifiée de Popcorn pour communiquer avec des lecteurs vidéos non-supportés par Popcorn.
-Au moment de la création de cette partie, l’interfaçage Popcorn-jwplayer n’était pas satisfaisant, à remplacer éventuellement par de vrais players/plugins pour Popcorn.
-
-### utils.js ###
-
-Contient quelques fonctions utilitaires, telles que *IriSP.loadCss*, qui est l’équivalent pour les fichiers CSS de LAB.js.
-
-### model.js ###
-
-Contient les classes de gestion du modèle de données Cinelab, regroupées sous l’espace de nommage *IriSP.Model*.
-
-### widgets.js ###
-
-Contient la classe de base *IriSP.Widgets.Widget*, qui fournit les fonctionnalités de base pour les widgets.
-
-### players ###
-
-Les fichiers de ce répertoire permettent d’interfacer le *Popcorn Replacement* (cf. *pop.js*) avec des lecteurs vidéo tiers.
-
-Existent actuellement:
-
-1. **player.jwplayer**, pour communiquer avec JwPlayer, utilisé pour lire des flux RTMP sur la plateforme *Ligne de temps*
-2. **player.dailymotion**, pour lire des vidéos du *Youtube à la française*
-3. **player.allocine**, pour le player de allocine.net
-4. **player.mashup**, pour le player de bout à bout Flash créé par Thibaut Cavalié.
-
-### serializers ###
-
-Les Sérialiseurs servent d’interface entre les formats de données utilisés pour les échanges avec les serveurs.
-
-Deux sérialiseurs existent à l’heure actuelle:
-
-1. **PlatformSerializer**, pour lire les flux JSON fournis par la plateforme *Lignes de Temps*.
-2. **PlatformAnnotateSerializer**, pour communiquer avec l’API d’ajout d’annotations de la plateforme, dont le format est légèrement différent.
-
-## Widgets ##
-
-Les Widgets sont des modules, visibles ou non, permettant de rajouter des fonctionnalités au Metadataplayer.
-
-Situés dans le répertoire *src/widgets*, ils contiennent nécessairement un fichier de code *NomDuWidget.js* et, optionnellement un fichier de style *NomDuWidget.css*
-
-#### Options courantes ####
-
-- Les widgets affichant des annotations possèdent l’option *annotation\_type*, qui peut prendre les valeurs suivantes:
-    - Chaîne de caractères: prend en compte les types d’annotations dont le titre contient la chaîne. Exemple: "chap" permet notamment d’afficher les annotations dans le type d’annotation "Chapitrage"
-    - Tableau de chaînes: pour prendre en compte plusieurs types d’annotations
-    - false: pour prendre en compte toutes les annotations du projet
-- *requires*, qui permet d’encapsuler un widget dans un autre.
-
-Voici la liste des widgets actuellement disponibles, avec leurs options:
-
-### HelloWorld ###
-
-- **Rôle**: Widget d’exemple démontrant l’API de création de widgets
-- **Options**:
-    - **text**: (défaut: "world"), texte à afficher après "Hello, "
-- Utilise un fichier CSS: oui
-
-### Slider ###
-
-- **Rôle**: Barre de progression et *Slider* indiquant la position de la tête de lecture vidéo et permettant de la déplacer.
-- **Options**:
-   - **minimized\_height**: (défaut: 4), hauteur en pixels du *Slider* en mode minimisé
-   - **maximized\_height**: (défaut: 10), hauteur en pixels du *Slider* en mode maximisé (lorsque la souris passe dessus)
-   - **minimize\_timeout**: (défaut: 1500), durée en millisecondes avant que le *Slider* ne se minimise. À une valeur de 0, le *Slider* ne se minimise plus.
-- Utilise la bibliothèque: jQuery UI
-- Utilise un fichier CSS: oui
-
-### Controller ###
-
-- **Rôle**: Boutons Lecture/Pause, Rechercher, Ouvrir l’annotateur et contrôle du volume
-- **Options**:
-    - **disable\_annotate\_btn**: (défaut: false), permet de désactiver le bouton d’ouverture de l’annotateur s’il est à *true*
-    - **disable\_search\_btn**: (défaut: true), permet de désactiver le bouton de recherche d’annotations
-- Utilise la bibliothèque: jQuery UI
-- Utilise un fichier CSS: oui
-
-### Arrow ###
-
-- **Rôle**: Dessine la flèche indiquant la position de l’annotation
-- **Options**:
-    - **arrow\_height**: (défaut: 16), hauteur en pixels de la flèche
-    - **arrow\_width**: (défaut: 24), largeur en pixels de la flèche
-    - **base\_height**: (défaut: 0), hauteur entre le bas de la flèche et le bas du widget. Nécessaire si l’on souhaite faire un widget aux bords arrondis.
-    - **base\_curve**: (défaut: 0), rayon de courbure des bords arrondis du widget.
-    - **fill\_url**: URL d’une image de remplissage pour le widget
-    - **fill\_color**: (défaut: "#ffffff" = blanc), couleur de remplissage du widget. Peut-être remplacé par un dégradé sous la forme angle en degrés-couleur de début-couleur de fin, ex: "90-#000-#fff"
-    - **stroke\_color**: (défaut: "#b7b7b7" = gris), couleur de la bordure du widget.
-    - **stroke\_width**: (défaut: 1.5), épaisseur en pixels de la bordure du widget.
-    - **animation\_speed**: (défaut: 20), vitesse de déplacement de la flèche.
-    - **pilot\_widget**: (défaut: "Annotation"), widget commandant la position de la flèche.
-- Utilise la bibliothèque: Raphael
-- Utilise un fichier CSS: non
-
-### Annotation ###
-
-- **Rôle**: Affiche les informations relatives à une annotation au moment où celle-ci est jouée
-- **Options**:
-    - **annotation\_type**: (défaut: "chapitrage"), cf. *Options courantes*, plus haut.
-    - **show\_top\_border**: (défaut: false), afficher ou non la bordure en haut du widget (au cas où il est utilisé sans/avec le widget *Arrow*)
-    - **site\_name**: "Lignes de Temps", nom du site à afficher lorsque l’on clique sur les boutons de partage pour réseaux sociaux.
-- Utilise un fichier CSS: oui
-
-### CreateAnnotation ###
-
-- **Rôle**: Permet de créer une annotation en affichant un formulaire
-- **Options**:
-    - **show\_title\_field**: (défaut: true), affiche un champ permettant de saisir le titre de l’annotation.
-    - **creator\_name**: nom d’utilisateur du créateur de l’annotation.
-    - **creator\_avatar**: URL de l’image de profil du créateur de l’annotation.
-    - **tags**: (défaut: false), liste des tags à afficher, sous la forme d’un tableau d’objets type [ { id: "tag-001", title: "" } ]. Si la valeur est false, affiche les tags les plus utilisés du projet.
-    - **max\_tags**: (défaut: 8), nombre de tags à afficher.
-    - **polemics**: boutons polémiques à afficher, sous la forme d’un tableau d’objets indiquant mot-clé à ajouter, couleur du fond du bouton, couleur du bouton, ex: [ { keyword: "++", background\_color: "#00a000", text\_color: "#ffffff" } ]
-    - **annotation\_type**: (défaut: "Contributions"), cf. *Options courantes*, plus haut.
-    - **api\_serializer**: (défaut: "ldt\_annotate"), sérialiseur à utiliser pour l’envoi des annotations.
-    - **api\_endpoint\_template**: URL de l’API, où {{id\}\} est remplacé par l’ID du projet, ex: "http://ldt.iri.centrepompidou.fr/ldtplatform/api/ldt/annotations/{{id}}.json".
-    - **api\_method**: (défaut: "PUT"), méthode HTTP utilisée pour envoyer les annotations. La plateforme *Lignes de temps* utilise PUT, mais cette méthode devrait être réservée pour la création d’une ressource dont l’URL est connue à l’avance.
-    - **close\_widget\_timeout**: (défaut: 0), durée en millisecondes avant que le widget ne soit refermé après l’envoi d’une annotation. Si la valeur est 0, le widget ne se referme pas.
-- Utilise un fichier CSS: oui
-
-### Polemic ###
-
-- **Rôle**: Affiche la *timeline polémique*, c’est à dire les tweets colorés en fonction de la syntaxe polémique. Selon le volume de tweets, deux modes de représentation existent:
-    - Avec un faible volume, les tweets sont des carrés dessinés individuellement.
-    - Avec un volume élevé, les colonnes présentent les volumes agrégés de tweets par couleur.
-- **Options**:
-    - **element\_width**: (défaut: 5), largeur en pixels d’une tranche de tweets.
-    - **element\_height**: (défaut: 5), hauteur en pixels d’un tweet, en mode faible volume.
-    - **max\_elements**: (défaut: 15), nombre de tweets dans une colonne à partir duquel le mode de représentation change.
-    - **annotation\_type**: (défaut: "tweet"), cf. *Options courantes*, plus haut.
-    - **defaultcolor**: (défaut: "#585858" = gris), couleur des tweets qui n’ont pas d’annotation polémique.
-    - **foundcolor**: (défaut: "#fc00ff" = mauve), couleur d’affichage des tweets correspondant à un résultat de recherche.
-    - **polemics**: couleurs polémiques à afficher, en fonction d’une recherche de termes, type [ { keywords: [ "++" ], color: "#1D973D" } ]
-- Utilise un fichier CSS: oui
-
-### Tweet ###
-
-- **Rôle**: Affiche furtivement le contenu d’un tweet
-- **Options**:
-    - **hide_timeout**: (défaut: 5000), durée en millisecondes, avant que l’affichage du Tweet ne se referme
-    - **polemics**: identique au paramètre *polemics* du widget *Polemic*
-
-### Sparkline ###
-
-- **Rôle**: Affiche une courbe indiquant l’évolution du volume d’annotations au cours du temps.
-- **Options**:
-    - **annotation\_type**: cf. *Options courantes*, plus haut.
-    - **lineColor**: (défaut: "#7492b4" = gris-bleu), couleur de la courbe
-    - **fillColor**: (défaut: "#aeaeb8" = gris), couleur de la surface sous la courbe
-    - **lineWidth**: (défaut: 2), épaisseur en pixels de la courbe
-    - **slice\_count**: (défaut: 20), nombre des tranches horaires dans lesquelles les annotations sont réparties pour calculer la courbe
-    - **height**: (défaut: 50), hauteur en pixels de la courbe
-    - **margin**: (défaut: 5), marge en pixels au-dessus de la courbe
-- Utilise la bibliothèque: Raphael
-- Utilise un fichier CSS: non
-
-### Tagcloud ###
-
-- **Rôle**: Affiche un nuage de mots-clés
-- **Options**:
-    - **include\_titles**: (défaut: true), utiliser le contenu du champ titre des annotations pour calculer le nuage de mots-clés.
-    - **include\_descriptions**: (défaut: true), utiliser le contenu du champ description des annotations pour calculer le nuage.
-    - **include\_tag\_texts**: (défaut: true), utiliser les textes des tags liés aux annotations pour calculer le nuage de mots-clés.
-    - **tag\_count**: (défaut: 30), nombre maximum de mots-clés à afficher.
-    - **stopword\_language**: (défaut: "fr"), code de langue correspondant à une liste de mots vides à exclure du nuage.
-    - **custom\_stopwords**: (défaut: []), liste de mots-vides à exclure du nuage.
-    - **exclude\_pattern**: (défaut: false), expression régulière à exclure du nuage.
-    - **annotation\_type**: (défaut: false), cf. *Options courantes*, plus haut. Concerne les annotations dont les contenus sont utilisés pour calculer le nuage.
-    - **segment\_annotation\_type**: (défaut: false), permet de définir la segmentation du nuage de mots-clés et de calculer un nuage pour chaque segment du type d’annotation choisi. Lorsque ce paramètre est à *false*, un seul nuage est calculé pour toute la durée de la vidéo.
-    - **min\_font\_size**: (défaut: 10), taille de caractères (en pixels) pour le mot le moins fréquent.
-    - **max\_font\_size**: (défaut: 26), taille de caractères (en pixels) pour le mot le plus fréquent.
-- Utilise un fichier CSS: oui
-
-### AnnotationsList ###
-
-- **Rôle**: Affiche une liste d’annotations
-- **Options**:
-    - **ajax\_url**: (défaut: false), spécifie un gabarit d’URL lorsque les annotations doivent être chargées par une API spécifique (API de segment). Dans l’URL, {{media}} sera remplacé par l’ID du média, {{begin}} par le *timecode* de début en millisecondes, {{end}} par le *timecode* de fin en millisecondes. Si le réglage est à *false*, les annotations affichées seront celles chargées à l’initialisation du Widget. Sur la plateforme *Lignes de Temps*, cette URL est http://ldt.iri.centrepompidou.fr/ldtplatform/api/ldt/segments/{{media}}/{{begin}}/{{end}}?callback=?
-    - **ajax\_granularity**: (défaut: 300000 ms = 5 minutes), spécifie la durée qui doit être chargée par l’API de segment, de part et d’autre du timecode courant (cf. ci-dessus) 
-    - **default\_thumbnail**: imagette à afficher par défaut à côté d’une annotation lorsque l’annotation n’a pas d’imagette.
-    - **foreign\_url**: spécifie un gabarit d’URL lorsque l’annotation n’a pas d’information d’URL et que l’annotation est dans un autre projet. Dans l’URL, {{media}} sera remplacé par l’ID du média, {{project}} par l’ID du projet, {{annotationType}} par l’ID du type d’annotation, {{annotation}} par l’ID de l’annotation. Sur la plateforme *Lignes de temps*, cette URL est http://ldt.iri.centrepompidou.fr/ldtplatform/ldt/front/player/{{media}}/{{project}}/{{annotationType}}#id={{annotation}}
-    - **annotation\_type**: (défaut: false), cf. *Options courantes*, plus haut.
-    - **refresh\_interval**: (défaut: 0), intervalle auquel le widget recharge en Ajax la liste des annotations (que l’on utilise l’API de segment ou non)
-    - **limit\_count**: (défaut: 10), nombre maximum d’annotations à afficher simultanément.
-    - **newest\_first**: (défaut: false), *true*: classe les annotations par ordre antéchronologique de création, *false*: classe les annotations par ordre chronologique de leur timecode vidéo.
-- Utilise un fichier CSS: oui
-
-### Media ###
-
-- **Rôle**: Affiche le média en cours, ainsi que la liste des autres médias du projet. Utilisé principalement pour les mashups
-- **Options**:
-    - **default\_thumbnail**: imagette à afficher par défaut à côté d’un média lorsque le média n’a pas d’imagette.
-    - **media\_url\_template**: spécifie un gabarit d’URL lorsque le média n’a pas d’information d’URL, par exemple: "http://ldt.iri.centrepompidou.fr/ldtplatform/ldt/front/player/{{media}}/"
-- Utilise un fichier CSS: oui
-
-### Tooltip ###
-
-- **Rôle**: Affiche une infobulle, utilisé uniquement comme *widget inclus* dans d’autres widgets.
-- Pas d’options
-- Utilise un fichier CSS: oui
-
-### Trace ###
-
-- **Rôle**: Envoi des traces au serveur KTBS
-- **Options**:
-    - **js\_console**: (défaut: false), écriture ou non des traces dans la console du navigateur.
-    - **url**: (défaut: "http://traces.advene.org:5000/"), URL du serveur de traces
-    - **requestmode**: (défaut: "GET"), méthode HTTP utilisée pour l’envoi des traces (seul *"GET"* permet le *cross-domain*).
-    - **syncmode**: (défaut: "sync"), envois groupés (mode *"delayed"*) ou non (*"sync"*) des traces
-- Utilise la bibliothèque: ktbs4js tracemanager
-- Utilise un fichier CSS: non
-
-### Mediafragment ###
-
-- **Rôle**: Gère les URLs à la norme *Mediafragment*: change la position de la tête de lecture en fonction de l’URL et inversement.
-- Une URL finissant par #id=*id de l’annotation* pointe sur une annotation, par #t=*temps en secondes* vers un timecode de la vidéo.
-- Pas d’options
-- Utilise un fichier CSS: non
--- a/sbin/doc/markdown2dokuwiki.py	Tue Jun 05 17:55:24 2012 +0200
+++ b/sbin/doc/markdown2dokuwiki.py	Tue Jun 05 20:55:42 2012 +0200
@@ -1,7 +1,7 @@
 import re, sys
 
 inputname = sys.argv[1]
-outputname = sys.argv[2]
+outputname = re.sub("\.\w+$",".dokuwiki",inputname)
 
 inputfile = open(inputname,'r')
 
--- a/src/js/defaults.js	Tue Jun 05 17:55:24 2012 +0200
+++ b/src/js/defaults.js	Tue Jun 05 20:55:42 2012 +0200
@@ -12,7 +12,8 @@
         popcorn : "popcorn-complete.min.js",
         jwplayer : "jwplayer.js",
         raphael : "raphael-min.js",
-        tracemanager : "tracemanager.js"
+        tracemanager : "tracemanager.js",
+        jwPlayerSWF : "player.swf"
     },
     locations : {
         // use to define locations outside defautl_dir
--- a/src/js/iframe_embed/embedder.js	Tue Jun 05 17:55:24 2012 +0200
+++ b/src/js/iframe_embed/embedder.js	Tue Jun 05 20:55:42 2012 +0200
@@ -23,7 +23,11 @@
     
     window.addEventListener('message', function(_e) {
         if (/^#/.test(_e.data) && !_blocked) {
-            document.location.hash = _e.data;
+            if (typeof window.history !== "undefined" && typeof window.history.replaceState !== "undefined") {
+                window.history.replaceState({}, "", _e.data);
+            } else {
+                document.location.hash = _e.data;
+            }
         }
     });
     
--- a/src/js/init.js	Tue Jun 05 17:55:24 2012 +0200
+++ b/src/js/init.js	Tue Jun 05 20:55:42 2012 +0200
@@ -7,7 +7,7 @@
 
 /* The Metadataplayer Object, single point of entry, replaces IriSP.init_player */
 
-IriSP.Metadataplayer = function(config, video_metadata) {
+IriSP.Metadataplayer = function(config) {
     IriSP.log("IriSP.Metadataplayer constructor");
     for (var key in IriSP.guiDefaults) {
         if (IriSP.guiDefaults.hasOwnProperty(key) && !config.gui.hasOwnProperty(key)) {
@@ -16,7 +16,6 @@
     }
     var _container = document.getElementById(config.gui.container);
     _container.innerHTML = '<h3 class="Ldt-Loader">Loading... Chargement...</h3>';
-    this.video_metadata = video_metadata;
     this.sourceManager = new IriSP.Model.Directory();
     this.config = config;
     this.callbackQueue = [];
@@ -94,7 +93,7 @@
     IriSP.loadCss(IriSP.getLib("cssjQueryUI"));
     IriSP.loadCss(this.config.gui.css);
     
-    this.videoData = this.loadMetadata(this.video_metadata);
+    this.videoData = this.loadMetadata(this.config.player.metadata);
     this.$ = IriSP.jQuery('#' + this.config.gui.container);
     this.$.css({
         "width": this.config.gui.width,
@@ -246,7 +245,7 @@
             delete opts.video;
 
             if(!opts.hasOwnProperty("flashplayer")) {
-                opts.flashplayer = IriSP.jwplayer_swf_path;
+                opts.flashplayer = IriSP.getLib("jwPlayerSWF");
             }
 
             if(!opts.hasOwnProperty("controlbar.position")) {
--- a/src/js/serializers/PlatformAnnotateSerializer.js	Tue Jun 05 17:55:24 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/* Used when Putting annotations on the platform */
-
-if (typeof IriSP.serializers === "undefined") {
-    IriSP.serializers = {}
-}
-
-IriSP.serializers.ldt_annotate = {
-    types :  {
-        annotation : {
-            serialized_name : "annotations",
-            serializer : function(_data, _source) {
-                return {
-                    begin: _data.begin.milliseconds,
-                    end: _data.end.milliseconds,
-                    content: {
-                        data: _data.description
-                    },
-                    tags: _data.getTagTexts(),
-                    media: _source.unNamespace(_data.getMedia().id),
-                    title: _data.title,
-                    type_title: _data.getAnnotationType().title,
-                    type: _source.unNamespace(_data.getAnnotationType().id)
-                }
-            }
-        }
-    },
-    serialize : function(_source) {
-        var _res = {},
-            _this = this;
-        _source.forEach(function(_list, _typename) {
-            if (typeof _this.types[_typename] !== "undefined") {
-                _res[_this.types[_typename].serialized_name] = _list.map(function(_el) {
-                    return _this.types[_typename].serializer(_el, _source);
-                });
-            }
-        });
-        _res.meta = {
-            creator: _source.creator,
-            created: _source.created
-        }
-        return JSON.stringify(_res);
-    },
-    deSerialize : function(_data, _source) {
-        if (typeof _data == "string") {
-            _data = JSON.parse(_data);
-        }
-        _source.addList('tag', new IriSP.Model.List(_source.directory));
-        _source.addList('annotationType', new IriSP.Model.List(_source.directory));
-        _source.addList('annotation', new IriSP.Model.List(_source.directory));
-        if (typeof _data.annotations == "object" && _data.annotations && _data.annotations.length) {
-            var _anndata = _data.annotations[0],
-                _ann = new IriSP.Model.Annotation(_anndata.id, _source);
-            _ann.title = _anndata.content.title || "";
-            _ann.description = _anndata.content.data || "";
-            _ann.created = new Date(_data.meta.created);
-            _ann.setMedia(_anndata.media, _source);
-            var _anntypes = _source.getAnnotationTypes(true).searchByTitle(_anndata.type_title);
-            if (_anntypes.length) {
-                var _anntype = _anntypes[0];
-            } else {
-                var _anntype = new IriSP.Model.AnnotationType(_anndata.type, _source);
-                _anntype.title = _anndata.type_title;
-                _source.getAnnotationTypes().push(_anntype);
-            }
-            _ann.setAnnotationType(_anntype.id);
-            var _tagIds = IriSP._(_anndata.tags).map(function(_title) {
-                var _tags = _source.getTags(true).searchByTitle(_title);
-                if (_tags.length) {
-                    var _tag = _tags[0];
-                }
-                else {
-                    _tag = new IriSP.Model.Tag(_title.replace(/\W/g,'_'),_source);
-                    _tag.title = _title;
-                    _source.getTags().push(_tag);
-                }
-                return _tag.id;
-            });
-            _ann.setTags(_tagIds);
-            _ann.setBegin(_anndata.begin);
-            _ann.setEnd(_anndata.end);
-            _ann.creator = _data.meta.creator;
-            _source.getAnnotations().push(_ann);
-        }
-    }
-}
\ No newline at end of file
--- a/src/js/serializers/PlatformSerializer.js	Tue Jun 05 17:55:24 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,195 +0,0 @@
-/* LDT Platform Serializer */
-
-if (typeof IriSP.serializers === "undefined") {
-    IriSP.serializers = {}
-}
-
-IriSP.serializers.ldt = {
-    types :  {
-        media : {
-            serialized_name : "medias",
-            deserializer : function(_data, _source) {
-                var _res = new IriSP.Model.Media(_data.id, _source);
-                _res.video = (
-                    typeof _data.url !== "undefined"
-                    ? _data.url
-                    : (
-                        typeof _data.href !== "undefined"
-                        ? _data.href
-                        : null
-                    )
-                );
-                if (typeof _data.meta.item !== "undefined" && _data.meta.item.name === "streamer") {
-                    _res.streamer = _data.meta.item.value;
-                }
-                _res.title = _data.meta["dc:title"];
-                _res.description = _data.meta["dc:description"];
-                _res.setDuration(_data.meta["dc:duration"]);
-                return _res;        
-            },
-            serializer : function(_data, _source) {
-                return {
-                    id : _source.unNamespace(_data.id),
-                    url : _data.video,
-                    meta : {
-                        "dc:title" : _data.title,
-                        "dc:description" : _data.description,
-                        "dc:duration" : _data.duration.milliseconds
-                    }
-                }
-            }
-        },
-        tag : {
-            serialized_name : "tags",
-            model_name : "tag",
-            deserializer : function(_data, _source) {
-                var _res = new IriSP.Model.Tag(_data.id, _source);
-                _res.title = _data.meta["dc:title"];
-                return _res;        
-            },
-            serializer : function(_data, _source) {
-                return {
-                    id : _source.unNamespace(_data.id),
-                    meta : {
-                        "dc:title" : _data.title
-                    }
-                }
-            }
-        },
-        annotationType : {
-            serialized_name : "annotation-types",
-            deserializer : function(_data, _source) {
-                var _res = new IriSP.Model.AnnotationType(_data.id, _source);
-                _res.title = _data["dc:title"];
-                _res.description = _data["dc:description"];
-                return _res;        
-            },
-            serializer : function(_data, _source) {
-                return {
-                    id : _source.unNamespace(_data.id),
-                    "dc:title" : _data.title,
-                    "dc:description" : _data.description
-                }
-            }
-        },
-        annotation : {
-            serialized_name : "annotations",
-            deserializer : function(_data, _source) {
-                var _res = new IriSP.Model.Annotation(_data.id, _source);
-                _res.title = _data.content.title || "";
-                _res.description = _data.content.description || "";
-                if (typeof _data.content.img !== "undefined" && _data.content.img.src !== "undefined") {
-                    _res.thumbnail = _data.content.img.src;
-                }
-                _res.created = IriSP.Model.isoToDate(_data.meta["dc:created"]);
-                if (typeof _data.color !== "undefined") {
-                    var _c = parseInt(_data.color).toString(16);
-                    while (_c.length < 6) {
-                        _c = '0' + _c;
-                    }
-                    _res.color = '#' + _c;
-                }
-                _res.setMedia(_data.media);
-                _res.setAnnotationType(_data.meta["id-ref"]);
-                _res.setTags(IriSP._(_data.tags).pluck("id-ref"));
-                _res.setBegin(_data.begin);
-                _res.setEnd(_data.end);
-                _res.creator = _data.meta["dc:creator"] || "";
-                _res.project = _data.meta.project || "";
-                if (typeof _data.meta["dc:source"] !== "undefined" && typeof _data.meta["dc:source"].content !== "undefined") {
-                    _res.source = JSON.parse(_data.meta["dc:source"].content);
-                }
-                return _res;
-            },
-            serializer : function(_data, _source) {
-                return {
-                    id : _source.unNamespace(_data.id),
-                    begin : _data.begin.milliseconds,
-                    end : _data.end.milliseconds,
-                    content : {
-                        title : _data.title,
-                        description : _data.description
-                    },
-                    media : _source.unNamespace(_data.media.id),
-                    meta : {
-                        "id-ref" : _source.unNamespace(_data.annotationType.id),
-                        "dc:created" : IriSP.Model.dateToIso(_data.created),
-                        "dc:creator" : _data.creator,
-                        project : _source.projectId
-                    },
-                    tags : IriSP._(_data.tag.id).map(function(_id) {
-                       return {
-                           "id-ref" : _source.unNamespace(_id)
-                       } 
-                    })
-                }
-            }
-        },
-        mashup : {
-            serialized_name : "mashups",
-            deserializer : function(_data, _source) {
-                var _res = new IriSP.Model.Mashup(_data.id, _source);
-                _res.title = _data.meta["dc:title"];
-                _res.description = _data.meta["dc:description"];
-                for (var _i = 0; _i < _data.segments.length; _i++) {
-                    _res.addSegmentById(_data.segments[_i]);
-                }
-                return _res;        
-            },
-            serializer : function(_data, _source) {
-                return {
-                    "dc:title": _data.title,
-                    "dc:description": _data.description,
-                    segments: _data.segments.map(function(_annotation) {
-                        return _source.unNamespace(_id);
-                    })
-                }
-            }
-        }
-    },
-    serialize : function(_source) {
-        var _res = {},
-            _this = this;
-        _source.forEach(function(_list, _typename) {
-            if (typeof _this.types[_typename] !== "undefined") {
-                _res[_this.types[_typename].serialized_name] = _list.map(function(_el) {
-                    return _this.types[_typename].serializer(_el, _source);
-                });
-            }
-        });
-        return JSON.stringify(_res);
-    },
-    loadData : function(_url, _callback) {
-        IriSP.jQuery.getJSON(_url, _callback)
-    },
-    deSerialize : function(_data, _source) {
-        if (typeof _data !== "object" || _data === null) {
-            return;
-        }
-        IriSP._(this.types).forEach(function(_type, _typename) {
-            var _listdata = _data[_type.serialized_name];
-            if (typeof _listdata !== "undefined" && _listdata !== null) {
-                var _list = new IriSP.Model.List(_source.directory);
-                if (_listdata.hasOwnProperty("length")) {
-                    var _l = _listdata.length;
-                    for (var _i = 0; _i < _l; _i++) {
-                        _list.push(_type.deserializer(_listdata[_i], _source));
-                    }
-                } else {
-                    _list.push(_type.deserializer(_listdata, _source));
-                }
-                _source.addList(_typename, _list);
-            }
-        });
-        
-        if (typeof _data.meta !== "undefined") {
-            _source.projectId = _data.meta.id;
-        }
-        
-        if (typeof _data.meta !== "undefined" && typeof _data.meta.main_media !== "undefined" && typeof _data.meta.main_media["id-ref"] !== "undefined") {
-            _source.setCurrentMediaId(_data.meta.main_media["id-ref"]);
-        }
-        _source.setDefaultCurrentMedia();
-    }
-}
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/js/serializers/ldt.js	Tue Jun 05 20:55:42 2012 +0200
@@ -0,0 +1,195 @@
+/* LDT Platform Serializer */
+
+if (typeof IriSP.serializers === "undefined") {
+    IriSP.serializers = {}
+}
+
+IriSP.serializers.ldt = {
+    types :  {
+        media : {
+            serialized_name : "medias",
+            deserializer : function(_data, _source) {
+                var _res = new IriSP.Model.Media(_data.id, _source);
+                _res.video = (
+                    typeof _data.url !== "undefined"
+                    ? _data.url
+                    : (
+                        typeof _data.href !== "undefined"
+                        ? _data.href
+                        : null
+                    )
+                );
+                if (typeof _data.meta.item !== "undefined" && _data.meta.item.name === "streamer") {
+                    _res.streamer = _data.meta.item.value;
+                }
+                _res.title = _data.meta["dc:title"];
+                _res.description = _data.meta["dc:description"];
+                _res.setDuration(_data.meta["dc:duration"]);
+                return _res;        
+            },
+            serializer : function(_data, _source) {
+                return {
+                    id : _source.unNamespace(_data.id),
+                    url : _data.video,
+                    meta : {
+                        "dc:title" : _data.title,
+                        "dc:description" : _data.description,
+                        "dc:duration" : _data.duration.milliseconds
+                    }
+                }
+            }
+        },
+        tag : {
+            serialized_name : "tags",
+            model_name : "tag",
+            deserializer : function(_data, _source) {
+                var _res = new IriSP.Model.Tag(_data.id, _source);
+                _res.title = _data.meta["dc:title"];
+                return _res;        
+            },
+            serializer : function(_data, _source) {
+                return {
+                    id : _source.unNamespace(_data.id),
+                    meta : {
+                        "dc:title" : _data.title
+                    }
+                }
+            }
+        },
+        annotationType : {
+            serialized_name : "annotation-types",
+            deserializer : function(_data, _source) {
+                var _res = new IriSP.Model.AnnotationType(_data.id, _source);
+                _res.title = _data["dc:title"];
+                _res.description = _data["dc:description"];
+                return _res;        
+            },
+            serializer : function(_data, _source) {
+                return {
+                    id : _source.unNamespace(_data.id),
+                    "dc:title" : _data.title,
+                    "dc:description" : _data.description
+                }
+            }
+        },
+        annotation : {
+            serialized_name : "annotations",
+            deserializer : function(_data, _source) {
+                var _res = new IriSP.Model.Annotation(_data.id, _source);
+                _res.title = _data.content.title || "";
+                _res.description = _data.content.description || "";
+                if (typeof _data.content.img !== "undefined" && _data.content.img.src !== "undefined") {
+                    _res.thumbnail = _data.content.img.src;
+                }
+                _res.created = IriSP.Model.isoToDate(_data.meta["dc:created"]);
+                if (typeof _data.color !== "undefined") {
+                    var _c = parseInt(_data.color).toString(16);
+                    while (_c.length < 6) {
+                        _c = '0' + _c;
+                    }
+                    _res.color = '#' + _c;
+                }
+                _res.setMedia(_data.media);
+                _res.setAnnotationType(_data.meta["id-ref"]);
+                _res.setTags(IriSP._(_data.tags).pluck("id-ref"));
+                _res.setBegin(_data.begin);
+                _res.setEnd(_data.end);
+                _res.creator = _data.meta["dc:creator"] || "";
+                _res.project = _data.meta.project || "";
+                if (typeof _data.meta["dc:source"] !== "undefined" && typeof _data.meta["dc:source"].content !== "undefined") {
+                    _res.source = JSON.parse(_data.meta["dc:source"].content);
+                }
+                return _res;
+            },
+            serializer : function(_data, _source) {
+                return {
+                    id : _source.unNamespace(_data.id),
+                    begin : _data.begin.milliseconds,
+                    end : _data.end.milliseconds,
+                    content : {
+                        title : _data.title,
+                        description : _data.description
+                    },
+                    media : _source.unNamespace(_data.media.id),
+                    meta : {
+                        "id-ref" : _source.unNamespace(_data.annotationType.id),
+                        "dc:created" : IriSP.Model.dateToIso(_data.created),
+                        "dc:creator" : _data.creator,
+                        project : _source.projectId
+                    },
+                    tags : IriSP._(_data.tag.id).map(function(_id) {
+                       return {
+                           "id-ref" : _source.unNamespace(_id)
+                       } 
+                    })
+                }
+            }
+        },
+        mashup : {
+            serialized_name : "mashups",
+            deserializer : function(_data, _source) {
+                var _res = new IriSP.Model.Mashup(_data.id, _source);
+                _res.title = _data.meta["dc:title"];
+                _res.description = _data.meta["dc:description"];
+                for (var _i = 0; _i < _data.segments.length; _i++) {
+                    _res.addSegmentById(_data.segments[_i]);
+                }
+                return _res;        
+            },
+            serializer : function(_data, _source) {
+                return {
+                    "dc:title": _data.title,
+                    "dc:description": _data.description,
+                    segments: _data.segments.map(function(_annotation) {
+                        return _source.unNamespace(_id);
+                    })
+                }
+            }
+        }
+    },
+    serialize : function(_source) {
+        var _res = {},
+            _this = this;
+        _source.forEach(function(_list, _typename) {
+            if (typeof _this.types[_typename] !== "undefined") {
+                _res[_this.types[_typename].serialized_name] = _list.map(function(_el) {
+                    return _this.types[_typename].serializer(_el, _source);
+                });
+            }
+        });
+        return JSON.stringify(_res);
+    },
+    loadData : function(_url, _callback) {
+        IriSP.jQuery.getJSON(_url, _callback)
+    },
+    deSerialize : function(_data, _source) {
+        if (typeof _data !== "object" || _data === null) {
+            return;
+        }
+        IriSP._(this.types).forEach(function(_type, _typename) {
+            var _listdata = _data[_type.serialized_name];
+            if (typeof _listdata !== "undefined" && _listdata !== null) {
+                var _list = new IriSP.Model.List(_source.directory);
+                if (_listdata.hasOwnProperty("length")) {
+                    var _l = _listdata.length;
+                    for (var _i = 0; _i < _l; _i++) {
+                        _list.push(_type.deserializer(_listdata[_i], _source));
+                    }
+                } else {
+                    _list.push(_type.deserializer(_listdata, _source));
+                }
+                _source.addList(_typename, _list);
+            }
+        });
+        
+        if (typeof _data.meta !== "undefined") {
+            _source.projectId = _data.meta.id;
+        }
+        
+        if (typeof _data.meta !== "undefined" && typeof _data.meta.main_media !== "undefined" && typeof _data.meta.main_media["id-ref"] !== "undefined") {
+            _source.setCurrentMediaId(_data.meta.main_media["id-ref"]);
+        }
+        _source.setDefaultCurrentMedia();
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/js/serializers/ldt_annotate.js	Tue Jun 05 20:55:42 2012 +0200
@@ -0,0 +1,85 @@
+/* Used when Putting annotations on the platform */
+
+if (typeof IriSP.serializers === "undefined") {
+    IriSP.serializers = {}
+}
+
+IriSP.serializers.ldt_annotate = {
+    types :  {
+        annotation : {
+            serialized_name : "annotations",
+            serializer : function(_data, _source) {
+                return {
+                    begin: _data.begin.milliseconds,
+                    end: _data.end.milliseconds,
+                    content: {
+                        data: _data.description
+                    },
+                    tags: _data.getTagTexts(),
+                    media: _source.unNamespace(_data.getMedia().id),
+                    title: _data.title,
+                    type_title: _data.getAnnotationType().title,
+                    type: _source.unNamespace(_data.getAnnotationType().id)
+                }
+            }
+        }
+    },
+    serialize : function(_source) {
+        var _res = {},
+            _this = this;
+        _source.forEach(function(_list, _typename) {
+            if (typeof _this.types[_typename] !== "undefined") {
+                _res[_this.types[_typename].serialized_name] = _list.map(function(_el) {
+                    return _this.types[_typename].serializer(_el, _source);
+                });
+            }
+        });
+        _res.meta = {
+            creator: _source.creator,
+            created: _source.created
+        }
+        return JSON.stringify(_res);
+    },
+    deSerialize : function(_data, _source) {
+        if (typeof _data == "string") {
+            _data = JSON.parse(_data);
+        }
+        _source.addList('tag', new IriSP.Model.List(_source.directory));
+        _source.addList('annotationType', new IriSP.Model.List(_source.directory));
+        _source.addList('annotation', new IriSP.Model.List(_source.directory));
+        if (typeof _data.annotations == "object" && _data.annotations && _data.annotations.length) {
+            var _anndata = _data.annotations[0],
+                _ann = new IriSP.Model.Annotation(_anndata.id, _source);
+            _ann.title = _anndata.content.title || "";
+            _ann.description = _anndata.content.data || "";
+            _ann.created = new Date(_data.meta.created);
+            _ann.setMedia(_anndata.media, _source);
+            var _anntypes = _source.getAnnotationTypes(true).searchByTitle(_anndata.type_title);
+            if (_anntypes.length) {
+                var _anntype = _anntypes[0];
+            } else {
+                var _anntype = new IriSP.Model.AnnotationType(_anndata.type, _source);
+                _anntype.title = _anndata.type_title;
+                _source.getAnnotationTypes().push(_anntype);
+            }
+            _ann.setAnnotationType(_anntype.id);
+            var _tagIds = IriSP._(_anndata.tags).map(function(_title) {
+                var _tags = _source.getTags(true).searchByTitle(_title);
+                if (_tags.length) {
+                    var _tag = _tags[0];
+                }
+                else {
+                    _tag = new IriSP.Model.Tag(_title.replace(/\W/g,'_'),_source);
+                    _tag.title = _title;
+                    _source.getTags().push(_tag);
+                }
+                return _tag.id;
+            });
+            _ann.setTags(_tagIds);
+            _ann.setBegin(_anndata.begin);
+            _ann.setEnd(_anndata.end);
+            _ann.creator = _data.meta.creator;
+            _source.getAnnotations().push(_ann);
+        }
+    }
+}
\ No newline at end of file
--- a/src/widgets/Mediafragment.js	Tue Jun 05 17:55:24 2012 +0200
+++ b/src/widgets/Mediafragment.js	Tue Jun 05 20:55:42 2012 +0200
@@ -6,7 +6,7 @@
     if (typeof window.addEventListener !== "undefined") {
         window.addEventListener('message', function(_msg) {
             if (/^#/.test(_msg.data)) {
-                document.location.hash = _msg.data;
+                this.setWindowHash(_msg.data);
             }
         })
     };
@@ -22,6 +22,14 @@
     this.goToHash();
 }
 
+IriSP.Widgets.Mediafragment.prototype.setWindowHash = function(_hash) {
+    if (typeof window.history !== "undefined" && typeof window.history.replaceState !== "undefined") {
+        window.history.replaceState({}, "", _hash);
+    } else {
+        document.location.hash = _hash;
+    }
+}
+
 IriSP.Widgets.Mediafragment.prototype.getLastHash = function() {
     var _tab = document.location.hash.replace(/^#/,'').split('&');
     _tab = IriSP._(_tab).filter(function(_el) {
@@ -71,7 +79,7 @@
         this.last_hash_key = _key;
         this.last_hash_value = _value;
         var _hash = this.getLastHash();
-        document.location.hash = _hash;
+        this.setWindowHash(_hash);
         if (window.parent !== window) {
             window.parent.postMessage(_hash,"*")
         }
--- a/test/jwplayer.htm	Tue Jun 05 17:55:24 2012 +0200
+++ b/test/jwplayer.htm	Tue Jun 05 20:55:42 2012 +0200
@@ -15,7 +15,7 @@
         <div id="LdtPlayer"></div>
         <div id="AnnotationsListContainer"></div>
         <script type="text/javascript">
-    IriSP.jwplayer_swf_path = "player.swf";
+    IriSP.libFiles.locations.jwPlayerSWF = "player.swf";
     IriSP.libFiles.defaultDir = "libs/";
     IriSP.widgetsDir = "metadataplayer";
     var _metadata = {
@@ -62,11 +62,12 @@
             height: 350, 
             width: 620, 
             provider: "rtmp",
-            autostart: true
+            autostart: true,
+            metadata: _metadata
         }
     };
     
-    _myPlayer = new IriSP.Metadataplayer(_config, _metadata);
+    _myPlayer = new IriSP.Metadataplayer(_config);
     
         </script>
     </body>
--- a/test/mashup/player-local.htm	Tue Jun 05 17:55:24 2012 +0200
+++ b/test/mashup/player-local.htm	Tue Jun 05 20:55:42 2012 +0200
@@ -97,11 +97,12 @@
         provider: "rtmp",
         mashup_swf : "bab_files/player_bab_ldt.swf",
         mashup_xml : "bab_files/mashup-local.xml",
-        autostart: true
+        autostart: true,
+        metadata: _metadata
     }
 };
 
-_myPlayer = new IriSP.Metadataplayer(_config, _metadata);
+_myPlayer = new IriSP.Metadataplayer(_config);
 
     </script>
     </body>
--- a/test/mashup/player.htm	Tue Jun 05 17:55:24 2012 +0200
+++ b/test/mashup/player.htm	Tue Jun 05 20:55:42 2012 +0200
@@ -97,11 +97,12 @@
         provider: "rtmp",
         mashup_swf : "bab_files/player_bab_ldt.swf",
         mashup_xml : "bab_files/mashup.xml",
-        autostart: true
+        autostart: true,
+        metadata: _metadata
     }
 };
 
-_myPlayer = new IriSP.Metadataplayer(_config, _metadata);
+_myPlayer = new IriSP.Metadataplayer(_config);
 
     </script>
     </body>
--- a/test/test-config.js	Tue Jun 05 17:55:24 2012 +0200
+++ b/test/test-config.js	Tue Jun 05 20:55:42 2012 +0200
@@ -45,9 +45,10 @@
             height: 350, 
             width: 620, 
             provider: "rtmp",
-            autostart: true
+            autostart: true,
+            metadata: _metadata
         }
     };
     
-    return new IriSP.Metadataplayer(_config, _metadata);
+    return new IriSP.Metadataplayer(_config);
 }
\ No newline at end of file