IriSP.tagplayer = function(opts) {
var directory = new IriSP.Model.Directory(),
project = directory.remoteSource({
url: IriSP.endpoints.mashup_by_tag,
url_params: {
tag: '"' + opts.tag + '"',
sort: "weight"
},
serializer: IriSP.serializers.ldt
}),
apidirectory = new IriSP.Model.Directory(),
mashup,
currentIndex = 0,
currentSegment,
currentMedia,
globalTags = {},
seqCount,
mediasInDom = [],
MAX_LOADED_VIDEOS = 2;
var ratio = 2.37;
if (typeof window.localStorage !== "undefined" && window.localStorage.getItem !== "undefined") {
var resolution = window.localStorage.getItem("resolution") || "SD";
} else {
var resolution = "SD";
}
var video_url_transform = function(url) {
return url.replace(/[SH]D(\.[a-z0-9]+)$/,resolution + "$1");
}
function resizeVideo() {
var currentwidth = $(window).width(),
maxheight = $(window).height() - 220,
height = Math.min(maxheight, currentwidth / ratio),
width = ratio * height;
$("#video_sequence").css({
width: Math.floor(width),
height: Math.floor(height)
});
}
$(window).on("resize", resizeVideo);
resizeVideo();
var timeSlider = $("#progressBar"),
slidersRange = 1000,
wasPaused = true,
lastVal = 0;
timeSlider.slider({
range: "min",
value: 0,
min: 0,
max: slidersRange,
slide: function(event, ui) {
var t = currentSegment.begin + ( currentSegment.getDuration() * ui.value / slidersRange );
currentMedia.setCurrentTime(t);
}
});
$("#btnBck").click(function() {
var newn = currentIndex ? ( currentIndex - 1 ) : ( seqCount - 1 );
goToPart(newn);
return false;
});
$("#btnFwd").click(function() {
var newn = ( 1 + currentIndex ) % seqCount;
goToPart(newn);
return false;
});
function playOrPause() {
if (currentMedia) {
if (currentMedia.paused) {
currentMedia.play();
} else {
currentMedia.pause();
}
}
}
$(".video-wait, #btnPlayPause").click(function() {
playOrPause();
return false;
});
var segmentdragout = $("#title_sequence"),
segmentdragin = segmentdragout.find("ul")
segmentdragging = false;
function resizeSegmentDrag() {
var segmentdelta = segmentdragout.width() - segmentdragin.width();
segmentdragin.draggable("option","containment",segmentdelta < 0 ? [ segmentdelta - 20, 0, 20, 0 ] : "parent");
if (segmentdelta < 0 && $("#title_sequence li").length) {
var x = $("#title_sequence li[data-segment-index='" + currentIndex + "']").offset().left - segmentdragin.offset().left;
segmentdragin.css("left", Math.max(segmentdelta - 20, Math.min( 20, 36 - x)))
}
}
segmentdragin.draggable({
axis: "x",
start: function() {
segmentdragging = true;
},
stop: function() {
segmentdragging = false;
}
});
$(window).on("resize", resizeSegmentDrag);
resizeSegmentDrag();
segmentdragin.on("mouseup", "li", function() {
if (!segmentdragging) {
goToPart(parseInt($(this).attr("data-segment-index")));
}
}).click(function() {
return false;
});
var tagsdragout = $("#tag_sequence"),
tagsdragin = tagsdragout.find("ul")
tagsdragging = false;
function resizeTagsDrag(toRight) {
var tagsdelta = tagsdragout.width() - tagsdragin.width();
tagsdragin.draggable("option","containment",tagsdelta < 0 ? [ tagsdelta - 20, 0, 20, 0 ] : "parent");
tagsdragin.css("left",(toRight && tagsdelta < 0) ? tagsdelta - 20 : Math.floor(tagsdelta/2));
}
tagsdragin.draggable({
axis: "x",
start: function() {
tagsdragging = true;
},
stop: function() {
tagsdragging = false;
}
});
$(window).on("resize", resizeTagsDrag);
resizeTagsDrag();
var taginput = $("#form_tag input[type=text]"),
replacerx;
taginput.autocomplete({
source: function(params, response) {
var charsub = [ '[aáàâä]', '[cç]', '[eéèêë]', '[iíìîï]', '[oóòôö]' ],
term = params.term.replace(/([\\\*\+\?\|\{\[\}\]\(\)\^\$\.\#\/])/gm, '\\$1');
_(charsub).each(function(chars) {
var tmprx = new RegExp(chars,"gim");
term = term.replace(tmprx, chars);
});
var searchrx = new RegExp("(^|\\s)" + term, "i");
replacerx = new RegExp("(^|\\s)(" + term + ")", "gi");
response(
_(globalTags)
.chain()
.keys()
.filter(function(tag) {
return searchrx.test(tag)
})
.sortBy(_.identity)
.value()
);
}
}).data("autocomplete")._renderItem = function(ul, item) {
return $( "<li>" )
.data( "item.autocomplete", item )
.append( "<a>" + item.label.replace(replacerx, '$1<b>$2</b>') + "</a>" )
.appendTo( ul );
};
taginput.on("keyup input paste", function() {
taginput.val(taginput.val().toUpperCase());
});
$("#form_tag").on("submit", function() {
var _tagvalue = taginput.val().toUpperCase();
taginput.val("");
if (_tagvalue && currentSegment) {
/* Création d'une liste d'annotations contenant une annotation afin de l'envoyer au serveur */
var _exportedAnnotations = new IriSP.Model.List(directory),
/* Création d'un objet source utilisant un sérialiseur spécifique pour l'export */
_export = directory.newLocalSource({
serializer: IriSP.serializers.ldt_annotate
}),
/* Création d'une annotation dans cette source avec un ID généré à la volée (param. false) */
_annotation = new IriSP.Model.Annotation(false, _export),
/* Si le Type d'Annotation n'existe pas, il est créé à la volée */
_annotationType = new IriSP.Model.AnnotationType(false, _export),
/* L'objet Tag qui sera envoyé */
_tag = new IriSP.Model.Tag(false, _export);
/* L'objet Tag doit avoir pour titre le texte du tag envoyé */
_tag.title = _tagvalue;
/* Si nous avons dû générer un ID d'annotationType à la volée... */
_annotationType.dont_send_id = true;
/* Il faut inclure le titre dans le type d'annotation */
_annotationType.title = "Contribution";
_annotation.setMedia(currentSegment.getMedia().id);
_annotation.setBegin(currentSegment.begin);
_annotation.setEnd(currentSegment.end);
_annotation.setAnnotationType(_annotationType.id);
_annotation.title = currentSegment.title;
_annotation.created = new Date(); /* Date de création de l'annotation */
_annotation.description = _tagvalue;
_annotation.setTags([_tag.id]); /*Liste des ids de tags */
_annotation.creator = "theend";
_annotation.created = new Date();
/* Ajout de l'annotation à la liste à exporter */
_exportedAnnotations.push(_annotation);
/* Ajout de la liste à exporter à l'objet Source */
_export.addList("annotation",_exportedAnnotations);
var segmentAtPost = currentSegment;
IriSP.jQuery.ajax({
url: IriSP.endpoints.post_annotation,
type: "POST",
contentType: 'application/json',
data: _export.serialize(), /* L'objet Source est sérialisé */
success: function(_data) {
var n = 1 + (segmentAtPost.__tags[_tagvalue] || 0)
segmentAtPost.__tags[_tagvalue] = n;
showCurrentTags(_tagvalue);
},
error: function(_xhr, _error, _thrown) {
console.log("Error when sending annotation", _thrown);
}
});
}
return false;
});
project.onLoad(function() {
mashup = project.getMashups()[0];
if (!mashup) {
return;
}
mashup.getMedias().forEach(function(m) {
addMedia(m);
});
seqCount = mashup.segments.length;
var html = mashup.segments.map(function(s, i) {
return '<li data-segment-index="' + i + '"><a href="#">' + s.title + ' </a> </li>'
}).join("");
segmentdragin.html(html);
resizeSegmentDrag();
goToPart(0);
mashup.segments.forEach(function(s) {
var url = IriSP.endpoints.annotations_by_timecode
.replace('__CONTENT_ID__', s.getMedia().id)
.replace('__BEGIN__', s.annotation.begin.valueOf())
.replace('__END__', s.annotation.end.valueOf());
var proj = apidirectory.remoteSource({
url: url,
serializer: IriSP.serializers.ldt
});
proj.__segment = s.annotation;
proj.onLoad(function() {
proj.__segment.__tags = {};
proj.getAnnotations().forEach(function(a) {
var tags = a.getTagTexts();
_(tags).each(function(t) {
var upt = t.toUpperCase(),
nl = 1 + (proj.__segment.__tags[upt] || 0),
ng = 1 + (globalTags[upt] || 0);
proj.__segment.__tags[upt] = nl;
globalTags[upt] = ng;
});
if (proj.__segment === currentSegment) {
showCurrentTags();
}
});
});
});
});
function goToPart(n) {
if (currentMedia) {
currentMedia.pause();
}
currentIndex = n;
currentSegment = mashup.segments[n].annotation;
currentMedia = currentSegment.getMedia();
var followingMedias = [];
for (var i = n; i < mashup.segments.length; i++) {
followingMedias.push(mashup.segments[i].getMedia());
}
followingMedias = _(followingMedias).uniq().slice(0, MAX_LOADED_VIDEOS);
var mediasToRemove = _(mediasInDom).difference(followingMedias);
_(mediasToRemove).each(function(m) {
m.removeFromDom();
});
followingMedias = _(followingMedias).difference(mediasInDom);
_(followingMedias).each(function(m) {
m.addToDom();
});
mashup.getMedias().forEach(function(m) {
if (m === currentMedia) {
m.show();
} else {
m.hide();
}
});
console.log("There are now",mediasInDom.length,'~',$("video").length,"<video>s in DOM");
$("#title_sequence li").removeClass("here");
$("#title_sequence li[data-segment-index='" + n + "']").addClass("here");
resizeSegmentDrag();
$("#duration").text(currentSegment.getDuration().toString());
if (currentSegment.__tags) {
showCurrentTags();
}
timeSlider.slider("value",0);
currentMedia.setCurrentTime(currentSegment.begin);
if (!currentMedia.loaded) {
$(".video-wait").show();
$("#btnPlayPause, .video-wait").removeClass("pause");
}
currentMedia.play();
}
function showCurrentTags(tagToShow) {
var vals = _(currentSegment.__tags).values(),
max = Math.max.apply(Math, vals),
min = Math.min(max - 1, Math.min.apply(Math, vals)),
b = 160 / (max - min),
tagList = _(currentSegment.__tags).map(function(v, k) {
return {
label: k,
weight: v
}
});
tagList = _(tagList).shuffle();
if (tagToShow && currentSegment.__tags[tagToShow]) {
tagList = tagList.filter(function(t) {
return (t.label !== tagToShow);
});
tagList.push({
label: tagToShow,
weight: currentSegment.__tags[tagToShow]
});
}
var html = tagList.reduce(
function(memo, tag) {
var c = Math.floor( 95 + (tag.weight - min) * b );
return memo + '<li><a href="'
+ IriSP.endpoints.tag_page.replace("__TAG__",encodeURIComponent(tag.label))
+ '" style="color: rgb('
+ [c,c,c].join(",")
+ ')">'
+ tag.label
+ ' </a> </li>';
},
"");
tagsdragin.html(html);
resizeTagsDrag(!!tagToShow);
}
var can_play_mp4 = !!document.createElement('video').canPlayType('video/mp4');
function addMedia(media) {
if (media.is_added) {
return;
}
media.is_added = true;
var videourl = video_url_transform(media.video),
videoid = "video_" + media.id,
mp4_file = videourl.replace(/\.webm$/i,'.mp4'),
webm_file = videourl.replace(/\.mp4$/i,'.webm'),
video_file = can_play_mp4 ? mp4_file : webm_file,
videoEl = undefined,
mediaEl = undefined;
media.addToDom = function() {
if (videoEl) {
return;
}
console.log("Adding to DOM",media.title);
mediasInDom.push(media);
mediasInDom = _(mediasInDom).uniq();
media.loaded = false;
media.paused = true;
videoEl = $('<video>');
mediaEl = videoEl[0];
videoEl.attr({
src : video_file,
id : videoid
}).css({
position : "absolute",
left: 0,
top: 0,
width : "100%",
height : "100%",
display: "none"
});
$("#video_sequence").append(videoEl);
// Binding DOM events to media
function getVolume() {
media.muted = mediaEl.muted;
media.volume = mediaEl.volume;
}
videoEl.on("loadedmetadata", function() {
getVolume();
media.loaded = true;
media.trigger("loadedmetadata");
media.trigger("volumechange");
})
videoEl.on("timeupdate", function() {
media.trigger("timeupdate", new IriSP.Model.Time(1000*mediaEl.currentTime));
});
videoEl.on("volumechange", function() {
getVolume();
media.trigger("volumechange");
})
videoEl.on("play", function() {
media.trigger("play");
});
videoEl.on("pause", function() {
media.trigger("pause");
});
videoEl.on("seeking", function() {
media.trigger("seeking");
});
videoEl.on("seeked", function() {
media.trigger("seeked");
});
}
media.removeFromDom = function() {
console.log("Removing from DOM",media.title);
videoEl.remove();
videoEl = undefined;
mediaEl = undefined;
mediasInDom = _(mediasInDom).without(media);
}
media.show = function() {
if (!videoEl) {
media.addToDom();
}
console.log("Showing media",media.title);
videoEl.show();
}
media.hide = function() {
if (videoEl) {
videoEl.hide();
}
}
// Binding functions to Media Element Functions
media.on("setcurrenttime", function(_milliseconds) {
try {
mediaEl.currentTime = (_milliseconds / 1000);
}
catch (err) {}
});
media.on("setvolume", function(_vol) {
try {
media.volume = _vol;
mediaEl.volume = _vol;
}
catch (err) {}
});
media.on("setmuted", function(_muted) {
try {
media.muted = _muted;
mediaEl.muted = _muted;
}
catch (err) {}
});
media.on("setplay", function() {
try {
mediaEl.play();
}
catch (err) {}
});
media.on("setpause", function() {
if (!mediaEl) {
return;
}
try {
mediaEl.pause();
}
catch (err) {}
});
// Binding UI Events and Mashup Playing to Media
media.on("play", function() {
if (media === currentMedia) {
$("#btnPlayPause, .video-wait").addClass("pause");
}
});
media.on("pause", function() {
if (media === currentMedia) {
$("#btnPlayPause, .video-wait").removeClass("pause");
}
});
media.on("timeupdate", function(_time) {
if (media === currentMedia) {
if ( _time < currentSegment.end ) {
var t = 0;
if ( _time >= ( currentSegment.begin - 40 ) ) { // Add one frame of tolerance
t = Math.max(0, _time - currentSegment.begin);
} else {
media.setCurrentTime(currentSegment.begin);
}
$("#current").text(new IriSP.Model.Time(t).toString());
timeSlider.slider("value", slidersRange * t / currentSegment.getDuration());
} else {
media.pause();
if (currentIndex < seqCount - 1) {
goToPart(currentIndex + 1)
} else {
document.location = $(".link_prev").attr("href");
}
}
}
});
}
$(".sdhdgroup").addClass(resolution);
$(".sdhdbtn").click(function() {
var newres = $(this).attr("title");
if (resolution !== newres) {
window.localStorage.setItem("resolution", newres);
document.location.reload();
}
return false;
});
$("#btnInfo, .lightBoxClose").click(function() {
$(".lightBoxWrap").toggle();
return false;
});
}