front_idill/src/player/metadataplayer/LdtPlayer-core.js
changeset 35 4267d6d27a7d
parent 31 2c7fc855eba8
child 44 8393d3473b98
--- a/front_idill/src/player/metadataplayer/LdtPlayer-core.js	Thu May 24 10:35:27 2012 +0200
+++ b/front_idill/src/player/metadataplayer/LdtPlayer-core.js	Wed May 30 10:21:36 2012 +0200
@@ -41,11 +41,35 @@
     this.video_metadata = video_metadata;
     this.sourceManager = new IriSP.Model.Directory();
     this.config = config;
+    this.callbackQueue = [];
+    this.isLoaded = false;
     this.loadLibs();
 }
 
 IriSP.Metadataplayer.prototype.toString = function() {
-    return 'A Metadataplayer in DIV #' + this.config.gui.container;
+    return 'Metadataplayer in #' + this.config.gui.container;
+}
+
+IriSP.Metadataplayer.prototype.deferCallback = function(_callback) {
+    var _this = this;
+    IriSP._.defer(function() {
+        _callback.call(_this);
+    });
+}
+
+IriSP.Metadataplayer.prototype.handleCallbacks = function() {
+    this.isLoaded = true;
+    while (this.callbackQueue.length) {
+        this.deferCallback(this.callbackQueue.splice(0,1)[0]);
+    }
+}
+
+IriSP.Metadataplayer.prototype.onLoad = function(_callback) {
+    if (this.isLoaded) {
+        this.deferCallback(_callback);
+    } else {
+        this.callbackQueue.push(_callback);
+    }
 }
 
 IriSP.Metadataplayer.prototype.loadLibs = function() {
@@ -143,6 +167,7 @@
         });
     };
     this.$.find('.Ldt-Loader').detach();
+    this.handleCallbacks();
 }
 
 IriSP.Metadataplayer.prototype.loadWidget = function(_widgetConfig, _callback) {
@@ -178,7 +203,7 @@
         spacerDiv = ret[1],
         _this = this,
         _types = {
-            "html5" : /\.(ogg|ogv|webm|mp4)$/,
+            "html5" : /\.(ogg|ogv|webm)$/,
             "youtube" : /^(https?:\/\/)?(www\.)?youtube\.com/,
             "dailymotion" : /^(https?:\/\/)?(www\.)?dailymotion\.com/
         };
@@ -255,6 +280,10 @@
             pop = new IriSP.PopcornReplacement.dailymotion("#" + containerDiv, this.config.player);
             break;
 
+        case "mashup":
+            pop = new IriSP.PopcornReplacement.mashup("#" + containerDiv, this.config.player);
+            break;
+            
         case "allocine":
             /* pass the options as-is to the allocine player and let it handle everything */
             pop = new IriSP.PopcornReplacement.allocine("#" + containerDiv, this.config.player);
@@ -301,7 +330,7 @@
 /* utils.js - various utils that don't belong anywhere else */
 
 IriSP.jqEscape = function(_text) {
-    return text.replace(/(:|\.)/g,'\\$1');
+    return _text.replace(/(:|\.)/g,'\\$1');
 }
 
 IriSP.getLib = function(lib) {
@@ -362,7 +391,7 @@
     "muted": false
   };
     
-  this.container = container.slice(1); //eschew the '#'
+  this.container = container.replace(/^#/,''); //eschew the '#'
   
   this.msgPump = {}; /* dictionnary used to receive and send messages */
   this.__codes = []; /* used to schedule the execution of a piece of code in 
@@ -625,6 +654,7 @@
     this.directory = _directory;
     this.idIndex = [];
     if (typeof _directory == "undefined") {
+        console.trace();
         throw "Error : new IriSP.Model.List(directory): directory is undefined";
     }
 }
@@ -632,15 +662,7 @@
 IriSP.Model.List.prototype = new Array();
 
 IriSP.Model.List.prototype.getElement = function(_id) {
-    var _index = IriSP._(this.idIndex).indexOf(_id);
-    if (_index !== -1) {
-        return this[_index];
-    } else {
-        var _un = _id.replace(/.*:/);
-        return IriSP._(this.idIndex).find(function(_i) {
-            return _i.replace(/.*:/) === _un;
-        });
-    }
+    return this[_id];
 }
 
 IriSP.Model.List.prototype.hasId = function(_id) {
@@ -668,6 +690,12 @@
     }
 }
 
+IriSP.Model.List.prototype.pluck = function(_key) {
+    return this.map(function(_value) {
+        return _value[_key];
+    });
+}
+
 /* We override Array's filter function because it doesn't return an IriSP.Model.List
  */
 IriSP.Model.List.prototype.filter = function(_callback) {
@@ -800,6 +828,12 @@
  */
 
 IriSP.Model.Time = function(_milliseconds) {
+    this.milliseconds = 0;
+    this.setMilliseconds(_milliseconds);
+}
+
+IriSP.Model.Time.prototype.setMilliseconds = function(_milliseconds) {
+    var _ante = _milliseconds;
     switch(typeof _milliseconds) {
         case "string":
             this.milliseconds = parseFloat(_milliseconds);
@@ -814,7 +848,7 @@
             this.milliseconds = 0;
     }
     if (this.milliseconds === NaN) {
-        this.milliseconds = 0;
+        this.milliseconds = _ante;
     }
 }
 
@@ -955,13 +989,24 @@
 IriSP.Model.Media.prototype = new IriSP.Model.Element();
 
 IriSP.Model.Media.prototype.setDuration = function(_durationMs) {
-    this.duration.milliseconds = _durationMs;
+    this.duration.setMilliseconds(_durationMs);
 }
 
 IriSP.Model.Media.prototype.getAnnotations = function() {
     return this.getRelated("annotation");
 }
 
+IriSP.Model.Media.prototype.getAnnotationsByTypeTitle = function(_title) {
+    var _annTypes = this.source.getAnnotationTypes().searchByTitle(_title).pluck("id");
+    if (_annTypes.length) {
+        return this.getAnnotations().filter(function(_annotation) {
+            return IriSP._(_annTypes).indexOf(_annotation.getAnnotationType().id) !== -1;
+        });
+    } else {
+        return new IriSP.Model.List(this.source.directory)
+    }
+}
+
 /* */
 
 IriSP.Model.Tag = function(_id, _source) {
@@ -1001,11 +1046,11 @@
 IriSP.Model.Annotation.prototype = new IriSP.Model.Element(null);
 
 IriSP.Model.Annotation.prototype.setBegin = function(_beginMs) {
-    this.begin.milliseconds = _beginMs;
+    this.begin.setMilliseconds(_beginMs);
 }
 
 IriSP.Model.Annotation.prototype.setEnd = function(_beginMs) {
-    this.end.milliseconds = _beginMs;
+    this.end.setMilliseconds(_beginMs);
 }
 
 IriSP.Model.Annotation.prototype.setMedia = function(_idRef) {
@@ -1036,17 +1081,21 @@
     return this.getTags().getTitles();
 }
 
+IriSP.Model.Annotation.prototype.getDuration = function() {
+    return new IriSP.Model.Time(this.end.milliseconds - this.begin.milliseconds)
+}
+
 /* */
 
-IriSP.Model.MashedAnnotation = function(_annotation, _offset) {
-    IriSP.Model.Element.call(this, IriSP.Model.getUID(), _annotation.source);
+IriSP.Model.MashedAnnotation = function(_mashup, _annotation) {
+    IriSP.Model.Element.call(this, _mashup.namespacedId.name + "_" + _annotation.namespacedId.name, _annotation.source);
     this.elementType = 'mashedAnnotation';
     this.annotation = _annotation;
-    this.begin = new IriSP.Model.Time(_offset);
-    var _duration = (this.annotation.end - this.annotation.begin);
-    this.end = new IriSP.Model.Time(_offset + _duration)
+    this.begin = new IriSP.Model.Time(_mashup.duration);
+    this.end = new IriSP.Model.Time(_mashup.duration + _annotation.getDuration());
     this.title = this.annotation.title;
     this.description = this.annotation.description;
+    this.color = this.annotation.color;
 }
 
 IriSP.Model.MashedAnnotation.prototype = new IriSP.Model.Element(null);
@@ -1073,15 +1122,24 @@
     IriSP.Model.Element.call(this, _id, _source);
     this.elementType = 'mashup';
     this.duration = new IriSP.Model.Time();
-    this.segments = new IriSP.Model.List();
-    this.medias = new IriSP.Model.List();
+    this.segments = new IriSP.Model.List(_source.directory);
+    this.medias = new IriSP.Model.List(_source.directory);
 }
 
 IriSP.Model.Mashup.prototype = new IriSP.Model.Element();
 
 IriSP.Model.Mashup.prototype.addSegment = function(_annotation) {
-    this.segments.push(new IriSP.Model.MashedAnnotation(_annotation));
-    this.medias.addElement(_annotation.getMedia());
+    var _mashedAnnotation = new IriSP.Model.MashedAnnotation(this, _annotation);
+    this.duration.setMilliseconds(_mashedAnnotation.end);
+    this.segments.push(_mashedAnnotation);
+    this.medias.push(_annotation.getMedia());
+}
+
+IriSP.Model.Mashup.prototype.addSegmentById = function(_elId) {
+    var _annotation = this.source.getElement(_elId);
+    if (typeof _annotation !== "undefined") {
+        this.addSegment(_annotation);
+    }
 }
 
 IriSP.Model.Mashup.prototype.getAnnotations = function() {
@@ -1091,6 +1149,38 @@
 IriSP.Model.Mashup.prototype.getMedias = function() {
     return this.medias;
 }
+
+IriSP.Model.Mashup.prototype.getAnnotationsByTypeTitle = function(_title) {
+    var _annTypes = this.source.getAnnotationTypes().searchByTitle(_title).pluck("id");
+    if (_annTypes.length) {
+        return this.getAnnotations().filter(function(_annotation) {
+            return IriSP._(_annTypes).indexOf(_annotation.getAnnotationType().id) !== -1;
+        });
+    } else {
+        return new IriSP.Model.List(this.source.directory)
+    }
+}
+
+IriSP.Model.Mashup.prototype.getAnnotationAtTime = function(_time) {
+    var _list = this.segments.filter(function(_annotation) {
+        return _annotation.begin <= _time && _annotation.end > _time;
+    });
+    if (_list.length) {
+        return _list[0];
+    } else {
+        return undefined;
+    }
+}
+
+IriSP.Model.Mashup.prototype.getMediaAtTime = function(_time) {
+    var _annotation = this.getAnnotationAtTime(_time);
+    if (typeof _annotation !== "undefined") {
+        return _annotation.getMedia();
+    } else {
+        return undefined;
+    }
+}
+
 /* */
 
 IriSP.Model.Source = function(_config) {
@@ -1181,7 +1271,7 @@
 
 IriSP.Model.Source.prototype.setCurrentMediaId = function(_idRef) {
     if (typeof _idRef !== "undefined") {
-        this.currentMedia = this.getMedias().getElement(this.getNamespaced(_idRef).fullname);
+        this.currentMedia = this.getElement(_idRef);
     }
 }
 
@@ -1225,7 +1315,6 @@
         this.deferCallback(this.callbackQueue.splice(0,1)[0]);
     }
 }
-
 IriSP.Model.Source.prototype.onLoad = function(_callback) {
     if (this.status === IriSP.Model._SOURCE_STATUS_READY) {
         this.deferCallback(_callback);
@@ -1252,6 +1341,16 @@
     return this.getList("media", _global);
 }
 
+IriSP.Model.Source.prototype.getTags = function(_global) {
+    _global = (typeof _global !== "undefined" && _global);
+    return this.getList("tag", _global);
+}
+
+IriSP.Model.Source.prototype.getMashups = function(_global) {
+    _global = (typeof _global !== "undefined" && _global);
+    return this.getList("mashup", _global);
+}
+
 IriSP.Model.Source.prototype.getAnnotationTypes = function(_global) {
     _global = (typeof _global !== "undefined" && _global);
     return this.getList("annotationType", _global);
@@ -1318,18 +1417,7 @@
 }
 
 IriSP.Model.Directory.prototype.getElement = function(_id) {
-    var _res = this.elements[_id];
-    if (typeof _res === "undefined") {
-        var _un = _id.replace(/.*:/),
-            _keys = IriSP._(this.elements).keys();
-            _key = IriSP._(_keys).find(function(_i) {
-                return _i.replace(/.*:/) === _un;
-            });
-        if (typeof _key !== "undefined") {
-            _res = this.elements[_key];
-        }
-    }
-    return _res;
+    return this.elements[_id];
 }
 
 IriSP.Model.Directory.prototype.addElement = function(_element) {
@@ -1498,7 +1586,8 @@
 }
 
 IriSP.Widgets.Widget.prototype.getWidgetAnnotations = function() {
-    return typeof this.annotation_type !== "undefined" && this.annotation_type ? this.source.getAnnotationsByTypeTitle(this.annotation_type) : this.source.getAnnotations();
+    var _curmedia = this.source.currentMedia;
+    return typeof this.annotation_type !== "undefined" && this.annotation_type ? _curmedia.getAnnotationsByTypeTitle(this.annotation_type) : _curmedia.getAnnotations();
 }
 
 /**
@@ -1810,148 +1899,176 @@
 };
 
 IriSP.PopcornReplacement.jwplayer.prototype = new IriSP.PopcornReplacement.player("", {});
-/* Cinecast Cinelab Serializer */
+/* To wrap a player the develop should create a new class derived from
+the IriSP.PopcornReplacement.player and defining the correct functions */
+
+/** jwplayer player wrapper */
+IriSP.PopcornReplacement.mashup = function(container, options) {
+    /* Appel du constructeur de la classe parente */
+    IriSP.PopcornReplacement.player.call(this, container, options);   
+    
+    var _this = this;
+
+    /* Définition des fonctions de commande :
+     this.playerFns.play, .pause, .getPosition, .seek,
+     .getMute, .setMute, .getVolume, .setVolume
+     doivent être rattachés aux fonctions du player
+     * */
+
+    this.playerFns = {
+        play : function() {
+            if (_this.player) {
+                return _this.player.playVideo();
+            } else {
+                return false;
+            }
+        },
+        pause : function() {
+            if (_this.player) {
+                return _this.player.pauseVideo();
+            } else {
+                return false;
+            }
+        },
+        getPosition : function() {
+            if (_this.player) {
+                return _this.player.getCurrentTime();
+            } else {
+                return 0;
+            }
+        },
+        seek : function(pos) {
+            if (_this.player) {
+                return _this.player.seekTo(pos);
+            } else {
+                return false;
+            }
+        },
+        getMute : function() {
+            if (_this.player) {
+                return _this.player.isMuted();
+            } else {
+                return false;
+            }
+        },
+        setMute : function(p) {
+            if (_this.player) {
+                if (p) {
+                    _this.player.mute();
+                }
+                else {
+                    _this.player.unMute();
+                }
+            }
+        },
+        getVolume : function() {
+            if (_this.player) {
+                return _this.player.getVolume() / 2;
+            } else {
+                return false;
+            }
+        },
+        setVolume : function(p) {
+            if (_this.player) {
+                _this.player.setVolume(Math.floor(2 * p));
+            }
+        },
+    }
+    
+    /* Dailymotion utilise un système de fonctions référencées dans
+     * des variables globales pour la gestion des événements.
+     */
+    
+    window.onBabPlayerReady = function() {
+        _this.onReady();
+    };
+    window.onBabStateChange = function(_state) {
+        _this.onStateChange(_state);
+    }
+    window.onBabVideoProgress = function(_progress) {
+        _this.onProgress(_progress);
+    }
+
+    var params = {
+        allowScriptAccess : "always",
+        wmode: "transparent",
+        quality: "high",
+        menu: true,
+        bgcolor: "#869ca7"
+    };
+    var atts = {
+        id : this.container
+    };
+    var flashvars = {
+        urlData: options.mashup_xml
+    };
+    swfobject.embedSWF(options.mashup_swf, this.container, options.width, options.height, "8", null, flashvars, params, atts);
+
+};
+
+IriSP.PopcornReplacement.mashup.prototype = new IriSP.PopcornReplacement.player("", {});
+
+IriSP.PopcornReplacement.mashup.prototype.onReady = function() {
+    
+    this.player = document.getElementById(this.container);
+    
+    this.callbacks.onReady();
+};
+
+IriSP.PopcornReplacement.mashup.prototype.onProgress = function(progressInfo) {
+    
+    this.callbacks.onTime({
+        position: progressInfo.mediaTime
+    });
+}
+
+IriSP.PopcornReplacement.mashup.prototype.onStateChange = function(state) {
+    
+    switch(state) {
+        case 1:
+            this.callbacks.onPlay();
+            break;
+
+        case 2:
+            this.callbacks.onPause();
+            break;
+
+        case 3:
+            this.callbacks.onSeek({
+                position: this.player.getCurrentTime()
+            });
+            break;
+    }
+    
+};/* Used when Putting annotations on the platform */
 
 if (typeof IriSP.serializers === "undefined") {
     IriSP.serializers = {}
 }
 
-IriSP.serializers.cinecast = {
+IriSP.serializers.ldt_annotate = {
     types :  {
-        media : {
-            serialized_name : "medias",
-            model_name : "media",
-            deserializer : function(_data, _source) {
-                var _res = new IriSP.Model.Media(_data.id, _source);
-                _res.video = _data.url;
-                _res.title = _data.meta.title;
-                _res.description = _data.meta.synopsis;
-                _res.setDuration(_data.meta.duration);
-                return _res;        
-            },
-            serializer : function(_data, _source) {
-                return {
-                    id : _source.unNamespace(_data.id),
-                    url : _data.video,
-                    meta : {
-                        title : _data.title,
-                        synopsis : _data.description,
-                        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.description;
-                return _res;        
-            },
-            serializer : function(_data, _source) {
-                return {
-                    id : _source.unNamespace(_data.id),
-                    meta : {
-                        description : _data.title
-                    }
-                }
-            }
-        },
-        annotationType : {
-            serialized_name : "annotation_types",
-            deserializer : function(_data, _source) {
-                var _res = new IriSP.Model.AnnotationType(_data.id, _source);
-                _res.title = _source.getNamespaced(_data.id).name;
-                _res.description = _data.meta.description;
-                return _res;        
-            },
+        annotation : {
+            serialized_name : "annotations",
             serializer : function(_data, _source) {
                 return {
-                    id : _source.unNamespace(_data.id),
-                    meta : {
-                        description : _data.description
-                    }
-                }
-            }
-        },
-        annotation : {
-            serialized_name : "annotations",
-            deserializer : function(_data, _source) {
-                var _res = new IriSP.Model.Annotation(_data.id, _source);
-                _res.title = _data.meta.creator_name;
-                _res.description = _data.content.data;
-                _res.created = IriSP.Model.isoToDate(_data.meta.created);
-                _res.setMedia(_data.media, _source);
-                _res.setAnnotationType(_data.type);
-                _res.setTags(IriSP._(_data.tags).map(function(_t) {
-                    if (typeof _source.contents.tag === "undefined") {
-                        _source.contents.tag = new IriSP.Model.List(_source.directory);
-                    }
-                    if (_source.contents.tag.hasId(_t)) {
-                        return _t;
-                    } else {
-                        var _id = _t.toLowerCase()
-                            .replace(/#/g,'')
-                            .replace(/^(\d)/,'_$1')
-                            .replace(/[áâäàã]/g,'a')
-                            .replace(/ç/g,'c')
-                            .replace(/[éèêë]/g,'e')
-                            .replace(/[íìîï]/g,'i')
-                            .replace(/ñ/g,'n')
-                            .replace(/[óòôöõ]/g,'o')
-                            .replace(/œ/g,'oe')
-                            .replace(/[úùûü]/g,'u')
-                            .replace(/ÿ/g,'y')
-                            .replace(/[^A-Za-z0-9_]/g,''),
-                            _tag = new IriSP.Model.Tag(_id, _source);
-                        _tag.title = _t;
-                        _source.contents.tag.push(_tag);
-                        return _id;
-                    }
-                }));
-                _res.setBegin(_data.begin);
-                _res.setEnd(_data.end);
-                _res.creator = _data.meta.creator;
-                return _res;
-            },
-            serializer : function(_data, _source) {
-                return {
-                    id : _source.unNamespace(_data.id),
-                    content : {
-                        data : _data.description
+                    begin: _data.begin.milliseconds,
+                    end: _data.end.milliseconds,
+                    content: {
+                        data: _data.description
                     },
-                    begin : _data.begin.milliseconds,
-                    end : _data.begin.milliseconds,
-                    media : _source.unNamespace(_data.media.id),
-                    type : _source.unNamespace(_data.annotationType.id),
-                    meta : {
-                        created : IriSP.Model.dateToIso(_data.created),
-                        creator : _data.creator,
-                        creator_name : _data.title
-                    },
-                    tags : _data.tag.id.map(function(_id) {
-                        return _source.unNamespace(_id)
-                    })
+                    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 = {
-                format : "http://advene.org/ns/cinelab/"
-            },
-            _this = this,
-            _nsls = _source.listNamespaces(true);
-        _res.imports = [];
-        for (var _i = 0; _i < _nsls.length; _i++) {
-           if (typeof _source.directory.namespaces[_nsls[_i]] !== "undefined") {
-               _res.imports.push({
-                   id : _nsls[_i],
-                   url : _source.directory.namespaces[_nsls[_i]]
-               })
-           } 
-        }
+        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) {
@@ -1959,44 +2076,13 @@
                 });
             }
         });
-        return _res;
-    },
-    loadData : function(_url, _callback) {
-        IriSP.jQuery.getJSON(_url, _callback)
-    },
-    deSerialize : function(_data, _source) {
-        if (typeof _data !== "object" || _data === null) {
-            return;
-        }
-        if (typeof _data.imports !== "undefined") {
-            IriSP._(_data.imports).forEach(function(_import) {
-                _source.directory.namespaces[_import.id] = _import.url;
-            })
+        _res.meta = {
+            creator: _source.creator,
+            created: _source.created
         }
-        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" && typeof _data.meta.main_media !== "undefined" && typeof _data.meta.main_media["id-ref"] !== "undefined") {
-            _source.setCurrentMediaId(_data.meta.id);
-        }
-        _source.setDefaultCurrentMedia();
+        return JSON.stringify(_res);
     }
-}
-
-/* LDT Platform Serializer */
+}/* LDT Platform Serializer */
 
 if (typeof IriSP.serializers === "undefined") {
     IriSP.serializers = {}
@@ -2006,7 +2092,6 @@
     types :  {
         media : {
             serialized_name : "medias",
-            model_name : "media",
             deserializer : function(_data, _source) {
                 var _res = new IriSP.Model.Media(_data.id, _source);
                 _res.video = (
@@ -2103,6 +2188,8 @@
             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
@@ -2114,13 +2201,34 @@
                         "dc:creator" : _data.creator,
                         project : _source.projectId
                     },
-                    tags : IriSP._(_data.tag.id).map(function(_d) {
+                    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) {
@@ -2133,7 +2241,7 @@
                 });
             }
         });
-        return _res;
+        return JSON.stringify(_res);
     },
     loadData : function(_url, _callback) {
         IriSP.jQuery.getJSON(_url, _callback)