+++ /dev/null
-# -*- coding: utf-8 -*-
-from distutils.core import setup
-from distutils.command.install import INSTALL_SCHEMES
-import os
-import sys
-
-def fullsplit(path, result=None):
- """
- Split a pathname into components (the opposite of os.path.join) in a
- platform-neutral way.
- """
- if result is None:
- result = []
- head, tail = os.path.split(path)
- if head == '':
- return [tail] + result
- if head == path:
- return result
- return fullsplit(head, [tail] + result)
-
-# Tell distutils to put the data_files in platform-specific installation
-# locations. See here for an explanation:
-# http://groups.google.com/group/comp.lang.python/browse_thread/thread/35ec7b2fed36eaec/2105ee4d9e8042cb
-for scheme in INSTALL_SCHEMES.values():
- scheme['data'] = scheme['purelib']
-
-# Compile the list of packages available, because distutils doesn't have
-# an easy way to do this.
-packages, data_files = [], []
-root_dir = os.path.dirname(__file__)
-if root_dir != '':
- os.chdir(root_dir)
-telemeta_dir = 'telemeta'
-
-for dirpath, dirnames, filenames in os.walk(telemeta_dir):
- # Ignore dirnames that start with '.'
- for i, dirname in enumerate(dirnames):
- if dirname.startswith('.'): del dirnames[i]
- if '__init__.py' in filenames:
- packages.append('.'.join(fullsplit(dirpath)))
- elif filenames:
- data_files.append([dirpath, [os.path.join(dirpath, f) for f in filenames]])
-
-# Dynamically calculate the version based on telemeta.VERSION.
-version = __import__('telemeta').__version__
-
-setup(
- name = "telemeta",
- url = "/http://svn.parisson.org/telemeta",
- description = "web frontend to backup, transcode and tag any audio content with metadata",
- author = ["Guillaume Pellerin, Olivier Guilyardi"],
- author_email = ["pellerin@parisson.com","olivier@samalyse.com"],
- version = version,
- packages = packages,
- data_files = data_files,
- long_description = """
-Telemeta is a web audio archiving program which introduces useful and secure methods to
-backup, index, transcode, analyse and publish any digitalized audio file with its metadata.
-It is dedicated to professionnals who wants to easily backup and publish documented sounds
-from collections of vinyls, magnetic tapes or audio CDs over a strong database, in accordance
-with open standards.
-
-Here are the main features of Telemeta:
-
- * Secure archiving, editing and publishing of audio files over internet.
- * User friendly web frontend including workflows and high level search methods
- * Smart dynamical and skinnable audio player (thanks to Timeside and soundmanager2)
- * "On the fly" analyzing, transcoding and metadata embedding based on an easy plugin architecture
- * Multi-format support : FLAC, OGG, MP3, WAV and more
- * GEO Navigator for audio geolocalization
- * DublinCore compatibility
- * OAI-PMH data provider
- * XML serialized backup
- * Strong SQL backend
-
-The Telemeta data model is based on 'collections' and 'items'. A collection is described
-by its metadata and includes original audio items (sounds) and its own metadata. This
-existing model has been designed to fit the one of the French Centre of Etnomusicology (CREM)
-but could be easily adapted/overrided to sue other data structures.
-
-See http://telemeta.org for more informations.
-"""
-)
}
#content {
+ margin-top: 1em;
+ margin-bottom: 0em;
+}
+
+#content, #content_header {
position: relative;
- margin: 1em 2em 0em 2em;
+ margin-left: 2em;
+ margin-right: 2em;
+}
+#content_header {
+ top:-.45em; /*must be header.margin_bottom (0.9em)*/
}
#content ul, #content ul ul, #content ol {
#content li a {
padding: .1em 0;
}
-#content h3 {
+#content h3, #content_header h3 {
color: #6a0307;
font-weight: bold;
display: inline;
#submenu {
position: relative;
margin: 5px 2em 0;
- height:3ex;
+ /*height:3ex;*/ /*no longer used, and it also shifts up the bottom content*/
z-index: 10;
}
-#submenu h3, #submenu div {
+/*#submenu h3, #submenu div {
min-height: 1.6em;
-}
+}*/
+
+
+
#submenu h3 {
margin-right: 80px;
}
font-weight: bold;
}*/
+#content_header table{
+ width:100%;
+}
+#content_header table td{
+ vertical-align: bottom;
+}
+
+#content_header td.rightcol a{
+ display:inline-block;
+ margin-top:0.5ex;
+}
+#content_header td.rightcol {
+ width:374px; /*must be width+2*padding, see #rightcol below*/
+}
#rightcol {
+ width: 362px; /**if u change this, change also width #content_header td.rightcol, see above*/
+ padding: 6px; /**if u change this, change also width #content_header td.rightcol, see above*/
position: relative;
z-index: 1;
float: right;
- width: 362px;
border: 1px solid #999;
- padding: 6px;
background-color: #eee;
-moz-border-radius: 8px 8px 8px 8px;
-webkit-border-radius: 8px 8px 8px 8px;
padding:.7ex .7ex .7ex .7ex;
background-color: #f9f9f9; /*#626262;*/
color:#444;
- /*border: 1px solid #eee;*/
text-decoration: none;
margin:0;
}
.button, .button:visited, .button:hover{
font-weight: bold;
- border-top: 1px solid #e1e1e1 !important;
+ border: 1px solid #e1e1e1;
+
+/* border-top: 1px solid #e1e1e1 !important;
border-left: 1px solid #e1e1e1 !important;
border-right: 1px solid #e1e1e1 !important;
- border-bottom: 1px solid #e1e1e1 !important;
+ border-bottom: 1px solid #e1e1e1 !important;*/
}
.button:hover{
return false; \r
});\r
}\r
+//returns the full path of the current url location removing the last slash '/' followed by one or more '#', if any\r
+function urlNormalized(){\r
+ var sPath = window.location.href;\r
+ sPath = sPath.replace(/\/#*$/,"");\r
+ return sPath;\r
+}\r
\r
\r
function setSelectedMenu(){\r
});\r
\r
//****************************************************************************\r
+//json(param, method, onSuccesFcn(data, textStatus, jqXHR), onErrorFcn(jqXHR, textStatus, errorThrown))\r
//global function to senbd/retrieve data with the server\r
//\r
//param: the data to be sent or retrieved.\r
position: 'absolute',\r
overflow:'auto', //necessary to properly display the content\r
display: 'none',\r
+ border: '1px solid #e1e1e1',\r
zIndex:1000\r
});\r
if(this.className){\r
},\r
\r
show:function(content, optionalEvent){\r
+ consolelog("showing popup:"+optionalEvent);\r
//if showing, hide\r
if(this.isShowing()){\r
this.hide();\r
var windowH = wdow.height();\r
var windowW = wdow.width();\r
var position = div.offset();\r
- var shadowOffset=5;\r
+ var shadowOffset=2;\r
var size = {\r
width:div.outerWidth(true)+shadowOffset,\r
height:div.outerHeight(true)+shadowOffset\r
position = invokerElement.offset();\r
position.top+= invokerElement.outerHeight(true);\r
}else{\r
- position.top = (windowH-size.height)/2;\r
- position.left = (windowW-size.width)/2;\r
+ position.top = wdow.scrollTop()+ (windowH-size.height)/2;\r
+ position.left = wdow.scrollLeft()+(windowW-size.width)/2;\r
}\r
//position div. This must be done immediately cause here below we want to get the div offset\r
//(div position in absolute - ie, document's - coordinates)\r
var divPadding = {\r
left: div.outerWidth()-div.width(),\r
top:div.outerHeight()-div.height()\r
- }; //setting width on a div means the width(),\r
+ }; //setting width on a div means the width(),\r
//but calculations here are made according to outerWidth(true), so we need this variable (se below)\r
\r
div.css({\r
});\r
}\r
}\r
- var divShadow = this._cfg_.divShadow().insertAfter(div);\r
- // //position div shadow:\r
- // var divShadow = this._cfg_.divShadow().css({\r
- // 'top': (position.top+shadowOffset),\r
- // 'left': (position.left+shadowOffset),\r
- // 'width': div.outerWidth(true),\r
- // 'height': div.outerHeight(true)\r
- // }).insertAfter(div).fadeTo(0,0.4);\r
- //\r
- // //set focus to the first input component, if any. Otherwise try with anchors, otherwise do nothing\r
- // var inputs = $J(div).find(':input');\r
- // if(inputs && inputs[0]){\r
- // inputs[0].focus();\r
- // }else{\r
- // inputs = $J(div).find('a');\r
- // if(inputs && inputs[0]){\r
- // inputs[0].focus();\r
- // }\r
- // }\r
- //\r
+ //var divShadow = this._cfg_.divShadow().insertAfter(div);\r
+\r
+ var divShadow = div.clone(false,false).empty().css({'zIndex':999,'borderColor':'#000','display':'none','backgroundColor':'#000'}).insertAfter(div);\r
+ \r
//store the divs to be removed\r
this._cfg_.divsToDelete = [div,divShadow];\r
//add a listener to the document. If one of the content children is clicked/keypressed,\r
hide.apply(me);\r
e.stopPropagation();\r
});\r
- div.show(300, function(){ //400: basically in between fast (200) and slow (600)\r
+ div.show(300, function(){ //basically in between fast (200) and slow (600)\r
//position div shadow:\r
- divShadow.css({\r
- 'top': (position.top+shadowOffset),\r
- 'left': (position.left+shadowOffset),\r
- 'width': div.outerWidth(true),\r
- 'height': div.outerHeight(true)\r
- }).fadeTo(0,0.4);\r
-\r
+ divShadow.show();\r
+ consolelog(div.outerHeight(true)+" "+div.outerHeight(false));\r
+ consolelog(divShadow.outerHeight(true)+" "+divShadow.outerHeight(false));\r
+ \r
//set focus to the first input component, if any. Otherwise try with anchors, otherwise do nothing\r
var inputs = $J(div).find(':input');\r
if(inputs && inputs[0]){\r
inputs[0].focus();\r
}\r
}\r
+\r
+ divShadow.fadeTo(0,0.4, function(){\r
+ divShadow.css({\r
+ 'top': (position.top+shadowOffset),\r
+ 'left': (position.left+shadowOffset),\r
+ 'width': div.outerWidth(true),\r
+ 'height': div.outerHeight(true)\r
+ });\r
+\r
+ });\r
});\r
return false; //to avoid scrolling if we clicked on an anchor\r
},\r
return onCancel();\r
}\r
};\r
- var subdiv = $J('<div/>').css({'padding':'1ex','float':'right'}).\r
- append(\r
+ var subdiv = $J('<div/>').css({\r
+ 'padding':'1ex',\r
+ 'float':'right'\r
+ }).\r
+ append(\r
$J('<a/>').\r
html('Ok').\r
addClass('component_icon').\r
}\r
\r
}\r
+\r
+\r
+//function loadScripts(scriptArrayName, callback){\r
+// if(!(scriptArrayName) && callback){\r
+// callback();\r
+// return;\r
+// }\r
+// var len = scriptArrayName.length;\r
+// var script = function(i){\r
+// if(i>=len){\r
+// if(callback){\r
+// callback();\r
+// return;\r
+// }\r
+// }\r
+// jQuery.getScript(scriptArrayName[i], function(){script(i+1)});\r
+// };\r
+// script(0);\r
+//}\r
+\r
+function loadScripts(scriptArray, callback, loadInSeries){\r
+ loadInSeries = false;\r
+ if(!scriptArray){\r
+ if(callback){\r
+ callback();\r
+ }\r
+ return;\r
+ }\r
+ var len = scriptArray.length;\r
+ var $J = jQuery;\r
+ var time = new Date().getTime();\r
+ if(loadInSeries){\r
+ var load = function(i){\r
+ if(i<len){\r
+ consolelog("loading "+scriptArray[i]+" "+new Date().getTime());\r
+ $J.getScript(scriptArray[i],function(){\r
+ load(i+1);\r
+ });\r
+ }else if(callback){\r
+ consolelog("EXECUTING CALLBACK ELAPSED TIME:"+(new Date().getTime()-time));\r
+ callback();\r
+ }\r
+ };\r
+ load(0);\r
+ }else{\r
+ var count=0;\r
+ var s;\r
+ for(var i=0; i <len; i++){\r
+ s = scriptArray[i];\r
+ consolelog("loading "+s+" "+new Date().getTime());\r
+ $J.getScript(s, function(){\r
+ count++;\r
+ if(count==len && callback){\r
+ consolelog("EXECUTING CALLBACK ELAPSED TIME:"+(new Date().getTime()-time));\r
+ callback();\r
+ }\r
+ });\r
+ }\r
+ }\r
+}\r
+\r
+function consolelog(text){\r
+ if(typeof console != 'undefined'){\r
+ var c = console;\r
+ if (c.log) {\r
+ c.log(text);\r
+ }\r
+ }\r
+}
\ No newline at end of file
-var sound = null;
-var soundUrl = null;
-var soundEngineReady = false;
+//var sound = null;
+//var soundUrl = null;
+//var soundEngineReady = false;
var map;
-var provider;
+//var provider;
var player;
var player_image_url = null;
+var controller;
function togglePlayerMaximization() {
+ consolelog('entered togglePlayerMaximization');
var view = $('#player');
$('#player_maximized, #player_minimized').css('display', 'none');
var ctr;
}, 100);
}
-function load_sound() {
- if (!sound && soundUrl && soundEngineReady) {
- sound = soundManager.createSound({
- id: 'sound',
- url: soundUrl
- });
-
- TimeSide.load(function() {
- provider.setSource(sound);
- player.updateVolumeAnchor(provider.getVolume());
- });
+function change_visualizer_clicked(){
+ var $J = jQuery;
+ var form = $J("#visualizer_id_form");
+ //var img = jQuery("<img/>").attr("src","/images/wait.gif").css('verticalAlign','middle');
- // sound.load(); // Auto-loading overloads the Django test server
+ var visId = $J("#visualizer_id");
+ visId.attr("disabled","disabled");
+ var img = $J(form.children()[0]);
+ var src = undefined;
+ if(img.attr('src')){
+ src = img.attr('src');
+ img.attr("src","/images/wait_small.gif");
}
+
+ //form.append(img);
+ setTimeout(function(){
+ change_visualizer();
+ //img.remove();
+ setTimeout(function(){
+ if(src){
+ img.attr('src',src);
+ }
+ visId.removeAttr("disabled");
+ },300);
+ },600);
}
function change_visualizer() {
+ consolelog('playerUtils.changeVisualizer');
set_player_image_url($('#visualizer_id').get(0).value);
if (player){
player.refreshImage();
return false;
}
-function load_player(duration) {
- $(document).ready(function () {
- if (!$('#player').length){
- return;
+
+
+
+function loadPlayer(analizerUrl, soundUrl){
+ var $J = jQuery;
+ var msgElm = $J('#loading_span_text'); //element to show messages
+ if(msgElm){
+ msgElm.html('Loading analyzer...');
+ }
+ var url = urlNormalized();
+ var tableBody = $J('#analyzer_div_id').find('table').find('tbody:last');
+ var load_player = this.load_player;
+ $J.ajax({
+ url: analizerUrl, //'analyze/xml',
+ dataType: 'xml',
+ success: function(data){
+ //populatetable
+ $J.each($J(data).find('data'),function(index,element){
+ var elm = $J(element);
+ tableBody.append('<tr><td>'+elm.attr('name')+'</td><td>'+elm.attr('value')+'</td><td>'
+ +elm.attr('unit')+'</td></tr>');
+ });
+ //loaded analizer, loading player
+ if(msgElm){
+ msgElm.html('Loading player...');
+ }
+ var duration = $J(data).find('#duration').attr('value');
+ duration = duration.split(":");
+ consolelog('analyzer loaded, duration: '+duration);
+ //format duration
+ var pin = parseInt;
+ var pfl = parseFloat;
+ var timeInMSecs=pin(duration[0])*3600+pin(duration[1])*60+pfl(duration[2]);
+ timeInMSecs = Math.round(timeInMSecs*1000);
+ load_player(soundUrl, timeInMSecs);
+ },
+ error:function(){
+ msgElm.parent().html("<img src='/images/dialog-error.png' style='vertical-align:middle'/><span class='login-error'>Error loading analyzer</span>");
}
- soundUrl = $('.ts-wave a').attr('href');
-
- $('.ts-wave a img').insertAfter('.ts-wave a');
- $('.ts-wave a').remove();
-
- TimeSide.load(function() {
- map = new TimeSide.MarkerMap();
- provider = new TimeSide.SoundProvider({
- duration: duration
- });
- player = new TimeSide.Player('#player', {
- image: get_player_image_src
- });
- controller = new TimeSide.Controller({
- player: player,
- soundProvider: provider,
- map: map
- });
- change_visualizer();
- player.resize();
- });
+ });
+}
+
- $('#visualizer_id').change(change_visualizer);
- $('#visualizer_id_form').submit(change_visualizer);
+//loads a player WAITING for the sound identified by soundUrl to be FULLY LOADED!!!!
+function load_player(soundUrl, durationInMsecs) {
+// if (!$('#player').length){
+// return;
+// }
+ consolelog('PlayerUtils.load_player: '+soundUrl+' '+durationInMsecs);
+ var load_player2 = this.load_player2;
- $('#player_maximized .toggle, #player_minimized .toggle').click(function() {
- togglePlayerMaximization();
- this.blur();
- return false;
+ //this variable can be changed to load a sound immediately or not
+ var loadImmediately = true;
+ if(durationInMsecs){
+ loadImmediately = false;
+ }
+ var sound = soundManager.createSound({
+ id: 'sound',
+ autoLoad: loadImmediately,
+ url: soundUrl,
+ onload: function() { //formerly was: whileloading
+ //PROBLEM/BUG: on chrome and firefox whileloading is the same as onload,
+ //ie it is not called at regular interval but when the whole file has loaded
+ if(loadImmediately){
+ consolelog('entering while loading setting up---------------'+this.bytesLoaded+' of '+this.bytesTotal);
+ loadImmediately=false;
+ load_player2(this, this.duration);
+ }
+ }
+ });
+ if(!loadImmediately){
+ load_player2(sound,durationInMsecs);
+ }
+}
+//NOTE: the sound MUST be FULLY LOADED!!!!!! otherwise the duration is null. This method is called from load_player
+function load_player2(sound, durationInMsec) {
+ if (!$('#player').length){
+ return;
+ }
+ consolelog("entered load_player2");
+
+ $('.ts-wave a img').insertAfter('.ts-wave a');
+ $('.ts-wave a').remove();
+
+ TimeSide.load(function() {
+ map = new TimeSide.MarkerMap();
+
+ player = new TimeSide.Player('#player', {
+ image: get_player_image_src,
+ 'sound': sound,
+ 'soundDurationInMsec': durationInMsec
});
+ change_visualizer();
+ controller = new TimeSide.Controller({
+ player: player,
+ map: map
+ });
+ });
- load_sound();
- });
-
- //old code valid for old version:
- // soundManager.onload = function() {
- // soundEngineReady = true;
- // load_sound();
- // }
- //replaced by:
- soundManager.onready(function() {
- // SM2 is ready to go!
- //alert('okkkk');
- map.debug('loaded sound manager');
- soundEngineReady = true;
- load_sound(); // soundManager.createSound(), etc.
+ var change_visualizer_click = change_visualizer_clicked;
+ $('#visualizer_id').change(change_visualizer_click);
+ //$('#visualizer_id_form').submit(change_visualizer_clicked);
+
+ $('#player_maximized .toggle, #player_minimized .toggle').click(function() {
+ togglePlayerMaximization();
+ this.blur();
+ return false;
});
-}
+}
function set_player_image_url(str) {
player_image_url = str;
}
return src;
}
+//======================================================================
+//OLD STUFF
+//======================================================================
+//TODO REMOVE NOTE: the sound MUST be FULLY LOADED!!!!!! otherwise the duration is null. This method is called from load_player
+function load_player2Old(sound) {
+ if (!$('#player').length){
+ return;
+ }
+ consolelog("entered load_player2");
+ // sound = soundManager.createSound({
+ // id: 'sound',
+ // url: soundUrl
+ // });
+ //soundUrl = $('.ts-wave a').attr('href');
+
+ $('.ts-wave a img').insertAfter('.ts-wave a');
+ $('.ts-wave a').remove();
+
+ TimeSide.load(function() {
+ map = new TimeSide.MarkerMap();
+ // provider = new TimeSide.SoundProvider({
+ // duration: sound.duration
+ // });
+ // provider.setSource(sound);
+ player = new TimeSide.Player('#player', {
+ image: get_player_image_src,
+ 'sound': sound
+ });
+ change_visualizer();
+ controller = new TimeSide.Controller({
+ player: player,
+ //soundProvider: provider,
+ map: map
+ });
+ //change_visualizer();
+ //player.resize();
+ //player.updateVolumeAnchor(provider.getVolume());
+ });
+
+ // $('#visualizer_id').change(change_visualizer);
+ // $('#visualizer_id_form').submit(change_visualizer);
+ $('#visualizer_id').change(change_visualizer_clicked);
+ $('#visualizer_id_form').submit(change_visualizer_clicked);
+
+ $('#player_maximized .toggle, #player_minimized .toggle').click(function() {
+ togglePlayerMaximization();
+ this.blur();
+ return false;
+ });
+
+
+}
+
+//TODO: REMOVE loads a player WAITING for the sound identified by soundUrl to be FULLY LOADED!!!!
+function load_playerOld(soundUrl) {
+ if (!$('#player').length){
+ return;
+ }
+ consolelog('PlayerUtils.load_player: '+soundUrl);
+ var callback = this.load_player2;
+
+ //this variable can be changed to load a sound immediately or not
+ var loadImmediately = true;
+ var sound = soundManager.createSound({
+ id: 'sound',
+ autoLoad: loadImmediately,
+ url: soundUrl,
+ whileloading: function() {
+ //PROBLEM/BUG: on chrome and firefox whileloading is the same as onload,
+ //ie it is not called at regular interval but when the whole file has loaded
+ if(loadImmediately){
+ consolelog('entering while loading setting up---------------'+this.bytesLoaded+' of '+this.bytesTotal);
+ loadImmediately=false;
+ callback(this);
+ }
+ }
+ });
+ if(!loadImmediately){
+ callback(sound);
+ }
+}
function log_globals(label) {
var g = get_globals();
if (log_globals.cache && label && typeof console != 'undefined') {
- console.log(label + ':');
- console.log(diff_array(log_globals.cache, g));
+ consolelog(label + ':');
+ consolelog(diff_array(log_globals.cache, g));
}
log_globals.cache = g;
}
}
.ts-pointer{
border: 1px solid #a10006 !important;
- -moz-border-radius: .5ex !important;
- -webkit-border-radius: .5ex !important;
- border-radius: .5ex !important;
+ -moz-border-radius: 1ex !important;
+ -webkit-border-radius: 1ex !important;
+ border-radius: 1ex !important;
color: #6A0307 !important;
}
height /**/:28px; /* for IE5/Win only */
margin-right: 0px;
}
-
-.ts-skin-lab .ts-player .ts-control .ts-playback a:hover {
+/*commented, apparently not used anymore, and it messes up the volume icon*/
+/*.ts-skin-lab .ts-player .ts-control .ts-playback a:hover {
background-position: 0 -28px;
-}
+}*/
-.ts-volume {
+.ts-volume, .ts-volume:hover, .ts-volume:visited {
background-image: url('img/volume.png');
background-repeat: no-repeat;
- background-position: 0px 0px !important;
+ /*background-position: 0px 0px !important;*/
width:60px !important;
}
this._setupPlayer();
//setting the divmarkers
//this.cfg.map.observe('add')
+ this.loadHTTP();
},
_setupPlayer: function() {
-
+ this.debug('_setupPlayer');
this.cfg.player
- .setSoundProvider(this.cfg.soundProvider)
+ //.setSoundProvider(this.cfg.soundProvider)
.setMarkerMap(this.cfg.map)
- .observe('play', $N.attachFunction(this.cfg.soundProvider, this.cfg.soundProvider.play))
- .observe('pause', $N.attachFunction(this.cfg.soundProvider, this.cfg.soundProvider.pause))
- .observe('move', this.attach(this._onMove))
+// .observe('play', $N.attachFunction(this.cfg.soundProvider, this.cfg.soundProvider.play))
+// .observe('pause', $N.attachFunction(this.cfg.soundProvider, this.cfg.soundProvider.pause))
+// .observe('move', this.attach(this._onMove))
.observe('markeradd', this.attach(this._onMarkerAdd))
//player markermove listens for changes of ruler markermove which listens
//foir changes in each marker move
.observe('markermove', this.attach(this._onMarkerMove))
- .draw();
- this.loadHTTP();
+// .draw();
+ ._setupInterface();
+ //this.loadHTTP();
this.cfg.map.observe('add',this.attach(this._onMarkerMapAdd));
this.cfg.map.observe('remove',this.attach(this._onMarkerMapRemove));
},
- _onMove: function(e, data) {
- this.cfg.soundProvider.seek(data.offset);
- },
+// _onMove: function(e, data) {
+// this.cfg.soundProvider.seek(data.offset);
+// },
//called whenever a marker is moved in the ruler BUT NOT in the map
_onMarkerMove: function(e, data) {
loadHTTP: function(){
-
- //itemid is the item (spund file) name
- var sPath = window.location.pathname;
- //remove last "/" or last "/#", if any...
- sPath = sPath.replace(/\/#*$/,"");
- var itemid = sPath.substring(sPath.lastIndexOf('/') + 1);
-
- //WARNING: use single quotes for the whole string!!
- //see http://stackoverflow.com/questions/4809157/i-need-to-pass-a-json-object-to-a-javascript-ajax-method-for-a-wcf-call-how-can
- var data2send = '{"id":"jsonrpc","params":["'+itemid+'"], "method":"telemeta.get_markers","jsonrpc":"1.0"}';
+ var itemId = ITEM_PUBLIC_ID;
var map = this.cfg.map;
var updateIndices = this.updateIndices;
+ //var setTabs = $N.Util.setUpTabs;
+ var util = $N.Util;
var me = this;
- $.ajax({
- type: "POST",
- url: '/json/',
- contentType: "application/json",
- data: data2send,
- dataType: "json",
- success: function(data) {
+ var onSuccess = function(data) {
var tabIndex = 0;
if(data){
if(data.result && data.result.length>0){
var result = data.result;
-
+
for(var i =0; i< result.length; i++){
map.add(result[i]);
}
updateIndices.apply(me);
tabIndex = result.length>0 ? 1 : 0;
}
-
+
}
- //We call mediaitem_detail.setUpTabs from controller once all markers have been loaded
- //this because setLabelDescription, which sets the label text according to the div width,
- //needs to have all elements visible.
- $N.Util.setUpTabs(tabIndex);
- //setUpTabs(); //which hides the marker div. Call with argument 1 to set up marker div
- //as visible as startup
- }
- });
- //var g = 9;
+ util.setUpTabs.apply(util, [tabIndex]);
+// setTabs(tabIndex);
+ };
+ //json(param, method, onSuccesFcn(data, textStatus, jqXHR), onErrorFcn(jqXHR, textStatus, errorThrown))
+ json([itemId],"telemeta.get_markers", onSuccess);
}
-
-
-
});
$N.notifyScriptLoad();
me:null,
markerMap:null,
+
initialize: function($super, markermap) {
$super();
//sets the fields required???? see ruler.js createPointer
markerDiv = $J('<div/>')
.append(this.e_header)
.append(this.e_descriptionText)
+ .attr('tabIndex',0)
//.append(this.e_okButton)
.append($J('<div/>') //.css('margin','1ex 0ex 0.1ex 0ex')
.append(this.e_okButton))
this.e_editButton.unbind('click').hide();
return false;
}
-
+
+
var remove = map.remove;
this.e_deleteButton.unbind('click').click( function(){
if(!(marker.isSavedOnServer) || confirm('delete the marker permanently?')){
return false; //avoid scrolling of the page on anchor click
})
-
+ this.e_addplaylistButton.unbind('click').bind('click',function(evtObj_){
+ playlistUtils.showPopupAddToPlaylist(evtObj_,'marker',""+marker.id,'marker added to selected playlist');return false;
+ });
//notifies controller.js
// this.fire('remove', {
// index: index
eB.hide();
utw.apply(divmarker,[tText]);
};
-
+
+// dText.unbind('focus').focus(function(){this.debug('dText focus')});
+// tText.unbind('focus').focus(function(){this.debug('tText focus')});
+// dText.unbind('blur').blur(function(){this.debug('dText blur')});
+// tText.unbind('blur').blur(function(){this.debug('tText blur')});
+
+
this.e_editButton.unbind('click').click( function(){
startEdit();
divmarker.focusOn();
},
elements: {},
ruler: null,
- soundProvider: null,
map: null,
container: null,
imageWidth: null,
imageHeight: null,
+ soundPosition: 0,
initialize: function($super, container, cfg) {
$super();
throw new $N.RequiredArgumentError(this, 'container');
}
this.container = $J(container);
+
this.configure(cfg, {
- image: null
+ image: null,
+ sound:null,
+ soundDurationInMsec:0
});
+ //if(this.cfg.sound && this.cfg.sound.)
},
free: function($super) {
this.elements = null;
this.container = null;
+ //this.sound.destruct(); //should be called here?
$super();
},
- setSoundProvider: function(soundProvider) {
- this.soundProvider = soundProvider;
- return this;
- },
setMarkerMap: function(map) {
this.map = map;
}
},
- draw: function() {
- this.debug('drawing');
- $N.domReady(this.attach(this._setupInterface));
- return this;
- },
+ // draw: function() {
+ // this.debug('drawing');
+ // $N.domReady(this.attach(this._setupInterface));
+ // return this;
+ // },
_setupInterface: function() {
+ consolelog('player _setupInterface sound.readyState:'+this.cfg.sound.readyState); //handle also cases 0 and 2????
+ //0 = uninitialised
+ //1 = loading
+ //2 = failed/error
+ //3 = loaded/success
+ if(this.cfg.sound.readyState==1){
+ var rsz = this.resize;
+ //attach an event when fully loaded and repaint all.
+ //For the moment we will display the ruler and other stuff
+ //based on durationEstimate property
+ this.cfg.sound.options.onload = function() {
+ rsz();
+ }
+ }
this.elements = $N.Util.loadUI(this.container, this.skeleton, this.defaultContents);
// IE apparently doesn't send the second mousedown on double click:
.click(function() {
return false;
});
- this.elements.pause.attr('href', '#').bind('click', this.attach(this._onPause));
- this.elements.play.attr('href', '#').bind('click', this.attach(this._onPlay));
+
//
- this.elements.volume.attr('href', '#').click(function(){return false;}).bind('mousedown', this.attach(
+ this.elements.volume.attr('href', '#').click(function(){
+ return false;
+ }).bind('mousedown', this.attach(
function(e){
if(e.which===1){ //left button
- this.changeVolume(e);
+ this.setVolume(e);
}
return false;
}
this.elements.setMarker.remove();
}
//creating the ruler
- this.ruler = new $N.Ruler({
+ var ruler = new $N.Ruler({
viewer: this.elements.viewer,
//map: this.map,
- soundProvider: this.soundProvider
+ sound: this.cfg.sound,
+ soundDurationInMsec: this.cfg.soundDurationInMsec
});
+ this.ruler = ruler;
//bind events to the ruler (see function observe in core.js, I guess,
//which overrides jQuery bind function):
//the first arg is basically the event name, the second
this.ruler
.observe('markermove', this.forwardEvent)
.observe('markeradd', this.forwardEvent)
- .observe('move', this.forwardEvent)
+ //.observe('move', this.forwardEvent)
.draw();
this.refreshImage();
- //this.resize(); //will be called in Timeside.load.
- var resizeTimer = null;
- $J(window).resize(this.attach(function() {
- if (resizeTimer){
- clearTimeout(resizeTimer);
+ this.resize();
+
+// var resizeTimer = null;
+// $J(window).resize(this.attach(function() {
+// if (resizeTimer){
+// clearTimeout(resizeTimer);
+// }
+// resizeTimer = setTimeout(this.attach(this.resize), 100);
+// }));
+
+ this.setSoundVolume(this.getSoundVolume());
+ //finally, binds events to play and pause. At the end cause this.ruler has to be fully initialized
+ var sound = this.cfg.sound;
+ this.elements.pause.attr('href', '#').bind('click', function(){
+ sound.pause();
+ return false;
+ });
+ //var r = this.ruler;
+ this.elements.play.attr('href', '#').bind('click', function(){
+ consolelog('playstate'+sound.playState);
+ if(sound.playState!=1 || sound.paused){
+ sound.play({
+ whileplaying: function(){
+ ruler._movePointer(this.position/1000);
+ //consolelog(this.ruler);
+ }
+ });
}
- resizeTimer = setTimeout(this.attach(this.resize), 100);
- }));
- //_updateVolumeChanged(this.soundProvider.getVolume());
- this.soundProvider.observe('volume',this.attach(this.onVolumeChanged));
- //this.container.resize(this.attach(this.resize)); // Can loop ?
+ return false;
+ });
},
resize: function(overrideHeight) {
this.ruler.resize();
return this;
},
+ //sound object methods
+
+ getSoundPosition :function(){
+ //note that this.cfg.sound.position is buggy. If we did not play, calling this.cfg.sound.setPosition(p)
+ //stores the position, but this.cfg.position returns zero.
+ //otherwise (we did play at least once) this.cfg.sound.position returns the good value
+ //to overcome this problem, we return the ruler position, NOTE that it is in seconds
+ return this.ruler.pointerPos;
+ // var s = this.cfg.sound;
+ // return s ? s.position/1000 : 0;
+ },
+
+ getSoundVolume :function(){
+ var s = this.cfg.sound;
+ return s ? s.volume : 0;
+ },
+
+ getSoundDuration :function(){
+ var s = this.cfg.sound;
+ return s ? s.duration/1000 : 0;
+ },
_onRewind: function() {
var offset = 0;
if (this.map) {
- var position = parseFloat(this.soundProvider.getPosition());
- // var marker = this.map.getPrevious(position);
- // if (marker && this.soundProvider.isPlaying()
- // && position - marker.offset < this.ruler.getUnitDuration())
- // marker = this.map.getPrevious(marker.offset)
- // if (marker) {
- // offset = marker.offset;
- // }
- //
+ var position = parseFloat(this.getSoundPosition());
var idx = this.map.indexOf(position)-1;
if(idx>=0){
var marker = this.map.get(idx);
}
}
}
- this.fire('move', {
- offset: offset
- });
+ this.ruler._movePointerAndUpdateSoundPosition(offset);
return false;
},
_onForward: function() {
- var offset = this.soundProvider.getDuration();
+ var offset = this.getSoundDuration();
if (this.map) {
- var position = parseFloat(this.soundProvider.getPosition());
+ var position = parseFloat(this.getSoundPosition());
var idx = this.map.insertionIndex(position);
if(idx>=0){ //the pointer is exactly on a marker, the index is the marker itself
//so increase by one otherwise and we wouldn't move ahead
offset = marker.offset;
}
}
- // var marker = this.map.getNext(this.soundProvider.getPosition());
- // if (marker) {
- // offset = marker.offset;
- // }
}
- this.fire('move', {
- offset: offset
- });
+ this.ruler._movePointerAndUpdateSoundPosition(offset);
+
return false;
},
- changeVolume: function(event){
+ //notified from a click event on the anchor
+ setVolume: function(event){
+
var ticks = [18,26,33,40,47];
var vol = event.layerX;
for(var i=0; i<ticks.length; i++){
if(vol<=ticks[i]){
//var index = i;
var volume = i*20;
- this.soundProvider.setVolume(volume);
+ this.setSoundVolume(volume);
+ this.debug('setting volume'+volume);
return false;
}
}
- this.soundProvider.setVolume(100);
-// var g = 9;
-// console.log(event.layerX);
+ this.setSoundVolume(100);
+ // var g = 9;
+ // console.log(event.layerX);
return false;
},
- onVolumeChanged: function(e, data){
- this.updateVolumeAnchor(data.volume);
- },
+ //TODO: remove unused
+ // onVolumeChanged: function(e, data){
+ // this.updateVolumeAnchor(data.volume);
+ // },
- updateVolumeAnchor: function(volume){
+ setSoundVolume: function(volume){
+
+ if(typeof volume != 'number'){ //note: typeof for primitive values, instanceof for the rest
+ //see topic http://stackoverflow.com/questions/472418/why-is-4-not-an-instance-of-number
+ volume = 100;
+ }
+ if(volume<0){
+ volume = 0;
+ }
+ if(volume>100){
+ volume = 100;
+ }
+ this.cfg.sound.setVolume(volume);
+ //update the anchor image:
var indices = [20,40,60,80,100,100000];
+
for(var i=0; i <indices.length; i++){
if(volume<indices[i]){
var pos = -28*i;
- pos = '0px '+ pos+ 'px !important';
+ pos = '0px '+ pos+ 'px'; //DO NOT SET !important as in FF3 DOES NOT WORK!!!!!
this.elements.volume.css('backgroundPosition',pos);
return;
}
}
- // this.elements.volume.css('backgroundPosition','0px 0px !important')
+ // this.elements.volume.css('backgroundPosition','0px 0px !important')
},
_onSetMarker: function() {
if (this.map) {
this.fire('markeradd', {
- offset: this.soundProvider.getPosition()
+ offset: this.getSoundPosition()
});
}
return false;
var playlistUtils = {
playlists : {},
- initialize: function(dictionary){
- this.playlists = dictionary;
- },
- addPlayList: function(name, id){
+
+ addPlaylist: function(name, id){
this.playlists[name]=id;
},
-
- // add : function(event){
- //
- // var $J = jQuery;
- //
- // var dText = $('<input/>')
- // .attr('type','text').val("");
- // var tText = $('<input/>')
- // .attr('type','text').val("");
- //
- // var table = $J('<table/>')
- // .append($J('<tr/>')
- // .append($J('<td/>').html('title'))
- // .append($J('<td/>').append(tText)))
- // .append($J('<tr/>')
- // .append($J('<td/>').html('description'))
- // .append($J('<td/>').append(dText)));
- //
- // var onOk= function(){
- // var pl = [{
- // "public_id":uniqid(),
- // "title":tText.val(),
- // "description":dText.val(),
- // user:CURRENT_USER_NAME
- // }];
- // json(pl,'telemeta.add_playlist',function(){
- // window.location.reload();
- // },true);
- // };
- // var onCancel= function(){
- // popup.hide();
- // return false;
- // };
- // var subdiv = $J('<div/>').append(
- // $J('<a/>').
- // html('Cancel').
- // css('float','right').
- // addClass('mediaitem_button').
- // addClass('mediaitem_button_cancel').
- // attr('href','#').
- // click(function(){
- // return onCancel();
- // })
- // ).append(
- // $J('<a/>').
- // html('Ok').
- // css('float','right').
- // addClass('mediaitem_button').
- // addClass('mediaitem_button_ok').
- // attr('href','#').
- // click(function(){
- // return onOk();
- // })
- // );
- // //popupDialog(element,table,onOk);
- // popup.show($J('<div/>').append(table).append(subdiv), event);
- // },
+
+ /*shows the popup for adding an item to the playlist*/
+ showPopupAddToPlaylist: function(event,resourceType,objectId, optionalMessage){
+ var $J = jQuery;
+ var content = $J('<div/>').addClass("_popup_add_to_playlist");
+ var addToPlaylist = this.addToPlaylist;
+ for(var p in this.playlists){
+ var id = this.playlists[p];
+
+ var a = $J('<a/>').
+ attr('href','#').
+ addClass("component_icon").
+ addClass("list_item icon_playlist").
+ html(p).
+ //by wrapping the addToPlaylist function in order to accept the id variable as an argument
+ //we avoid calling the function with id = number_of_playlists for all anchors
+ //by returning another function (basically create another closure) we avoid executing the function
+ //immediately
+ click(function(id_){
+ return function(){
+ addToPlaylist(id_,resourceType,objectId,optionalMessage);
+ return false;
+ }
+ }(id)
+ );
+ content.append(a);
+ }
+ return popup.show(content,event);
+ },
add : function(dictionary){
window.location.reload();
});
},
+
//resourceType can be: 'collection', 'item', 'marker'
- addToPlaylist: function(playlistId,resourceType,objectId){
+ addToPlaylist: function(playlistId,resourceType,objectId, optionalOkMessage){
+ consolelog(playlistId)
var send = {
'public_id':uniqid(),
'resource_type':resourceType,
};
json([playlistId,send],'telemeta.add_playlist_resource',function(){
var p = popup;
- p.show(jQuery('<div/>').html('<a style="border:0" class="component_icon button icon_ok">Ok</span>'));
- setTimeout(function(){p.hide()},600);
+ if(optionalOkMessage){
+ p.show(jQuery('<div/>').addClass("icon_ok").addClass("component_icon").html(optionalOkMessage));
+ setTimeout(function(){
+ p.hide();
+ },1000);
+ }else{
+ p.hide(); //to be sure
+ }
});
}
viewer: [null, 'required'],
fontSize: 10,
//map: null,
- soundProvider: [null, 'required']
+ sound: [null, 'required'],
+ soundDurationInMsec:0
});
this.cfg.viewer = $J(this.cfg.viewer);
this.container = this.cfg.viewer.find('.' + $N.cssPrefix + 'ruler');
this.waveContainer = this.cfg.viewer.find('.' + $N.cssPrefix + 'image-canvas');
- this._setDuration(this.cfg.soundProvider.getDuration());
+
+ //this.duration = this.cfg.sound.duration/1000; //TODO: improve this function!!
+ //note that soundmanager2 returns the duration in milliseconds, while here we compute the
+ //layout according to the duration in seconds. Changing all functions it's a pain and it's useless'
+
+ //initialize duration. If sound autoLoad=false, duration is zero and we must use durationEstimate
+ //this.duration = this.cfg.sound.duration ? this.cfg.sound.duration : this.cfg.sound.durationEstimate;
+ //this
+ this.duration = this.cfg.soundDurationInMsec/1000;
+ consolelog('duration - - '+this.cfg.sound.duration);
+ consolelog('duration -E- '+this.cfg.sound.bytesTotal);
+
var imgContainer = this.cfg.viewer.find('.' + $N.cssPrefix + 'image-container'); // for IE
this._observeMouseEvents(this.waveContainer.add(imgContainer));
- //if (this.cfg.map) {
- // this.cfg.map
- //.observe('add', this.attach(this._onMapAdd))
- //.observe('remove', this.attach(this._onMapRemove))
- //.observe('indexchange', this.attach(this._onMapIndexChange));
- //}
+
+ //this is a workaround: when moving the marker the first time sound.setPosition seems not to work
+ //after playing the first time, it works. Or after having set position explicitly, apparently
+ //this.cfg.sound.setPosition(0);
+ // this.sp = this._setPosition;
+
+ // this.cfg.sound.whileplaying(function(){
+ // sp(this.position/1000);
+ // });
+ // this.cfg.sound.onfinish(function(){ //when it reaches the end (naturally) force pointer to be at the end
+ // sp(this.duration);
+ // });
+
+ //if (this.cfg.map) {
+ // this.cfg.map
+ //.observe('add', this.attach(this._onMapAdd))
+ //.observe('remove', this.attach(this._onMapRemove))
+ //.observe('indexchange', this.attach(this._onMapIndexChange));
+ //}
- this.cfg.soundProvider.observe('update', this.attach(this._onSoundProviderUpdate));
+ //this.cfg.soundProvider.observe('update', this.attach(this._onSoundProviderUpdate));
+ //this.cfg.soundProvider.observe('play', this.attach(this._onSoundProviderPlaying));
},
free: function($super) {
_computeLayout: function() {
this.width = this.waveContainer.width();
-
this.debug('container width: ' + this.width);
var i, ii = this.sectionSteps.length;
this.timeLabelWidth = this._textWidth('00:00', this.cfg.fontSize);
for (i = 0; i < ii; i++) {
+ // this.debug('step: ' +i+' duration: '+this.sectionSteps[i][0]);
+ // this.debug('step: ' +i+' subdivision: '+this.sectionSteps[i][1]);
+ // this.debug('labelsNum: ' +i+' labelsNum (this.duration/duration): '+Math.floor(this.duration / duration));
+
var duration = this.sectionSteps[i][0];
var subDivision = this.sectionSteps[i][1];
var labelsNum = Math.floor(this.duration / duration);
this.fullSectionDuration = duration;
this.sectionSubDivision = subDivision;
this.sectionsNum = Math.floor(this.duration / this.fullSectionDuration);
+ this.debug('(in _computeLayout) this.fullSectionDuration: ' + this.fullSectionDuration);
+ this.debug('(in _computeLayout) sectionsNum: ' +this.sectionsNum);
+ this.debug('(in _computeLayout) duration: ' +this.duration);
break;
}
}
},
resize: function() {
- var pointerVisible = this.pointer && this.pointer.isVisible();
+ // var pointerVisible = this.pointer && this.pointer.isVisible();
+ // this.debug('resizing (pointer visible: :'+pointerVisible+':');
+ // alert(this.pointer.isVisible());
this._computeLayout();
+
this.draw();
- if (pointerVisible) {
- this.setPosition(this.cfg.soundProvider.getPosition());
- this.setBuffering(this.cfg.soundProvider.isBuffering() && this.cfg.soundProvider.isPlaying());
- this.pointer.show();
+ if(this.pointer){
+ if(!this.pointer.isVisible()){
+ this.pointer.show();
+ }
+ // }
+ // if (pointerVisible) {
+ // this.setPosition(this.cfg.soundProvider.getPosition());
+ // this.setBuffering(this.cfg.soundProvider.isBuffering() && this.cfg.soundProvider.isPlaying());
+
+ this._movePointer(this.cfg.sound.position/1000);
+ this.setBuffering(this.cfg.sound.isBuffering && this.cfg.sound.playState==1);
+ //Note that playState = 1 may not always guarantee that sound is being heard, given buffering and autoPlay status.
+ //(from soundmanager2 tutorial)
}
},
- _setDuration: function(duration) {
- this.duration = duration;
- this._computeLayout();
- },
-
- setDuration: function(duration) {
- if (duration == 0)
- duration = 60;
- if (this.duration != duration) {
- this._setDuration(duration);
- this.draw();
- }
- },
+// _setDuration: function(duration) {
+// this.debug('duration setting ruler: ' + duration);
+// this.duration = duration;
+// this._computeLayout();
+// },
+//
+// setDuration: function(durationInMillisecs) {
+// var duration = durationInMillisecs ? durationInMillisecs/1000 : 60;
+// if (this.duration != duration) {
+// this._setDuration(duration);
+// this.draw();
+// }
+// },
_createSection: function(timeOffset, pixelWidth) {
var section = $J('<div/>')
.observe('move', this.attach(this._onPointerMove));
},
- _movePointer: function(offset) {
- if (offset < 0){
- offset = 0;
- }else if (offset > this.duration){
- offset = this.duration;
- }
- pixelOffset = offset / this.duration * this.width;
- if (this.pointer) {
- this.pointer.move(pixelOffset);
- this.pointer.setText($N.Util.makeTimeLabel(offset));
- }
- this.pointerPos = offset;
- },
+ // _setPosition: function(offset) {
+ // this._movePointer(offset);
+ //// if (this.pointer) {
+ //// this.pointer.show();
+ //// }
+ // },
+
+
- _setPosition: function(offset) {
- this._movePointer(offset);
- if (this.pointer) {
- this.pointer.show();
- }
- },
+
- setPosition: function(offset) {
- if (!this.mouseDown) {
- this._setPosition(offset);
- }
- },
+ // setPosition: function(offset) {
+ // if (!this.mouseDown) {
+ // this._setPosition(offset);
+ // }
+ // },
- shiftPosition: function(delta) {
- this.setPosition(this.pointerPos + delta);
- },
+ // shiftPosition: function(delta) {
+ // this.setPosition(this.pointerPos + delta);
+ // },
hidePointer: function() {
if (this.pointer)
_onMouseDown: function(evt) {
this.mouseDown = true;
this._onMouseMove(evt);
- evt.preventDefault();
- },
-
- _onPointerMove: function(evt, data) {
- this.mouseDown = true;
- this._setPosition(data.offset / this.width * this.duration);
- if(data.finish) {
- this.fire('move', {
- offset: this.pointerPos
- });
- this.mouseDown = false;
- }
- return false;
+ evt.preventDefault(); //If this method is called, the default action of the event will not be triggered.
},
+
_onMouseMove: function(evt) {
if (this.mouseDown) {
var pixelOffset = evt.pageX - this.container.offset().left;
- this._setPosition(pixelOffset / this.width * this.duration);
+ this._movePointerAndUpdateSoundPosition(pixelOffset / this.width * this.duration);
+ //moves the pointer and fires onPointerMove
return false;
}
},
_onMouseUp: function(evt) {
-
if (this.mouseDown) {
this.mouseDown = false;
- this.fire('move', {
- offset: this.pointerPos
- });
- return false;
+ this.debug('_onMouseUp:'+this.pointerPos+' '+this.cfg.sound.position);
+ //this.debug("mousedup"+this.cfg.sound.position)
+ }
+ return false;
+ },
+ //called while playing, does not update sound position
+ _movePointer: function(offset) {
+
+ if (offset < 0){
+ offset = 0;
+ }else if (offset > this.duration){
+ offset = this.duration;
+ }
+ var pixelOffset = offset / this.duration * this.width;
+ if (this.pointer) {
+ this.pointer.move(pixelOffset); //does NOT fire any move method
+ this.pointer.setText($N.Util.makeTimeLabel(offset));
+ }
+ this.pointerPos = offset;
+ },
+ //called by everything else than playing, same as _movePointer but updates also the sound position accordingly
+ _movePointerAndUpdateSoundPosition: function(offset) {
+ this._movePointer(offset)
+ this.cfg.sound.setPosition(parseInt(1000*this.pointerPos));
+ },
+
+ _onPointerMove: function(evt, data) {
+ //this.debug('_onPointerMove:'+ this.pointerPos+' '+this.cfg.sound.position);
+
+ this.mouseDown = true;
+ this._movePointerAndUpdateSoundPosition(data.offset / this.width * this.duration);
+ if(data.finish) {
+ // this.fire('move', {
+ // offset: this.pointerPos
+ // });
+ this.mouseDown = false;
}
+ return false;
},
+
_observeMouseEvents: function(element) {
if(!(CURRENT_USER_NAME)){
return;
}
pixelOffset = marker.offset / this.duration * this.width;
-
+
m = new $N.RulerMarker({
rulerLayout: this.layout.get(0),
viewer: this.waveContainer,
tooltip: 'Move marker',
canMove: marker.isEditable
});
+
if(marker.isEditable){
m.observe('move', this.attach(this._onMarkerMove))
}
},
//it is assured that fromIndex!=toIndex and fromIndex!=toIndex+1 (see markermap.move)
-// move: function(fromIndex, toIndex){
-// var m = this.markers.splice(fromIndex,1)[0]; //remove
-// this.markers.splice(toIndex,0,m); //add
-// },
+ // move: function(fromIndex, toIndex){
+ // var m = this.markers.splice(fromIndex,1)[0]; //remove
+ // this.markers.splice(toIndex,0,m); //add
+ // },
updateMarkerIndices:function(fromIndex, toIndex){
for(var i=fromIndex; i<=toIndex; i++){
offset: offset
});
}
- },
-
- _onSoundProviderUpdate: function(e) {
- this.setDuration(this.cfg.soundProvider.getDuration());
- this.setPosition(this.cfg.soundProvider.getPosition());
- this.setBuffering(this.cfg.soundProvider.isBuffering() && this.cfg.soundProvider.isPlaying());
}
+
+ // , _onSoundProviderUpdate: function(e) {
+ // this.debug("spupdate");
+ //
+ // //this.setDuration(this.cfg.soundProvider.getDuration());
+ // this.setPosition(this.cfg.soundProvider.getPosition());
+ // this.setBuffering(this.cfg.soundProvider.isBuffering() && this.cfg.soundProvider.isPlaying());
+ // }
});
$N.notifyScriptLoad();
nodes: null,
mouseDown: false,
blinkAnimation: null,
+ mouseDownOffset:0,
initialize: function($super, cfg) {
$super();
if(cfg.index !== undefined && cfg.className!='pointer'){
this.setIndex(cfg.index);
}
+
},
setIndex: function(index){
if (this.cfg.tooltip){
this.label.attr('title', this.cfg.tooltip);
}
+
this.cfg.rulerLayout.append(this.label);
var height = this.cfg.viewer.height();
.each(function(i, node) {
node.originalPosition = parseInt($J(node).css('left'));
});
+
},
setText: function(text) {
_onMouseDown: function(evt) {
this.mouseDown = true;
- this._onMouseMove(evt);
+ this.mouseDownOffset = evt.pageX-(this.label.offset().left+this.label.outerWidth(true)/2);
+ //this._onMouseMove(evt);
return false;
},
_onMouseMove: function(evt) {
if (this.mouseDown) {
- var offset = (evt.pageX - this.cfg.rulerLayout.offset().left);
+ var offset = (evt.pageX - this.cfg.rulerLayout.offset().left)-this.mouseDownOffset;
+ this.debug(evt.pageX);
+ this.debug(this.label.outerWidth(true));
+ this.debug(this.cfg.rulerLayout.offset().left);
this.move(offset);
this.fire('move', { //calls move (see above)
offset: this.position,
this.state.position = 0;
this.update = this.attach(this._update);
this.timer = setInterval(this.update, 43);
+ this.init=true;
+ this._update();
+ this.init=false;
},
free: function($super) {
_update: function() {
this._retrieveState();
var updated = false;
+ var k;
if (this.lastState) {
for (k in this.state) {
if (this.state[k] != this.lastState[k]) {
updated = true;
}
if (updated) {
+ var fireevent = false;
for (k in this.state) {
+ if(k=='position' && this.lastState[k]!==undefined && this.lastState[k]!=this.state[k]){
+ //this.lastState[k]!==undefined because otherwise we are initializing
+ this.debug('fire-play-stop');
+ fireevent = true;
+ }else if(k=='playing' && this.lastState[k] && !this.state[k]){
+ //stop playing, fire again to move the cursor REALLY at the end
+ this.debug('fire-stop');
+ fireevent = true;
+ }
+ if(this.state[k] != this.lastState[k]){
+ this.debug('(soundprovider _update) '+k+': oldVal: '+this.lastState[k]+': val: '+this.state[k]);
+ }
this.lastState[k] = this.state[k];
+
+ }
+ if(fireevent){
+ this.debug('firing');
+ this.fire('update');
}
- this.fire('update');
}
},
if (!$N.isLoading) {
$N.isLoading = true;
var re = /(.*)timeside.js/;
- var root = '';
+ var root = '/timeside/src/'; //TODO: changed by me!!!!!
$J('head script').each(function(i, e) {
if ((match = re.exec(e.src))) {
root = match[1];
$N.loadScripts(root, ['core.js'], function() {
$N.loadScripts(root, ['util.js'], function() {
var scripts = ['controller.js', 'rulermarker.js', //'markerlist.js',
- 'markermap.js', 'player.js', 'ruler.js','divmarker.js',
- 'soundprovider.js'];
+ 'markermap.js', 'player.js', 'ruler.js','divmarker.js'];
+ //,'soundprovider.js'];
$N.loadScripts(root, scripts, function() {
$N.isLoaded = true;
setUpTabs:function(selIndex) {//called from within controller.js once all markers have been loaded.
//this is because we need all divs to be visible to calculate size. selIndex is optional, it defaults to 0
//
+
//declare variables:
var tabContainerHeight = '5ex'; //height for the tab container
var tabHeight = '3.5ex'; //height for the tab. Must be lower than tabContainerHeight
};
//end of variables declaration
+
+ //first of all, delete the span shown only onloading
+ var span = tabContainer.find('#loading_span');
+ if(span.length){
+ span.remove();
+ consolelog('removed span');
+ }
+
+
//tabContainer default css:
tabContainer.css({
'position':'relative',
});
//tabs default css:
tabs.css({
+ 'display':'', //reset the default value
'position':'absolute',
'height':tabHeight,
'bottom':tabBottom,
}
});
- },
+ }
}
<div id="submenu">
{% block submenu %}{% endblock %}
</div>
-
+<div id="content_header">
+{% block content_header %}{% endblock %}
+</div>
<div id="content">
{% block content %}{% endblock %}
<div class="nett"></div>
<script src="{% url telemeta-js "swfobject.js" %}" type="text/javascript"></script>
<script src="{% url telemeta-timeside "src/playlist.js" %}" type="text/javascript"></script>
<script>
+ var setupPlaylist = function(){
+ {% if user.is_authenticated %}
+ var p = playlistUtils;
+ {% for playlist in playlists %}
+ p.addPlaylist('{{ playlist.playlist.title }}','{{playlist.playlist.public_id}}');
+ {% endfor %}
+
+ {% endif %}
+ {% if collection %}
+ var anchor = jQuery('#_add_to_playlist');
+ if(anchor.length){
+ anchor.click(function(evtObj_){
+ p.showPopupAddToPlaylist(evtObj_,'collection','{{collection.public_id}}','Collection added to selected playlist');return false;
+ });
+ }
+ {% endif %}
+ };
jQuery(document).ready(function(){
- var content = $('#_popup_add_to_playlist').clone(true,true);
- $('#_add_to_playlist').click(function(e){return popup.show(content,e)});
+ setupPlaylist();
});
</script>
{% endblock %}
{% endif %}
{% if user.is_authenticated %}
<a href=# id ="_add_to_playlist" class="component_icon button icon_add">{% trans "Add to playlist" %}</a>
- <div id="_popup_add_to_playlist" style="display:none">
- {% for playlist in playlists %}
- <a href="#" class="component_icon list_item icon_playlist"
- onclick="playlistUtils.addToPlaylist('{{playlist.playlist.public_id}}','collection','{{collection.pk}}');">{{ playlist.playlist.title }}</a>
- {% endfor %}
- </div>
{% endif %}
{% endblock tools %}
<link rel="stylesheet" type="text/css" href="{% url telemeta-timeside "css/timeside.css" %}" />
<link rel="stylesheet" type="text/css" href="{% url telemeta-timeside "skins/lab/style.css" %}" />
<link rel="stylesheet" type="text/css" href="{% url telemeta-css "player.css" %}" />
-{% endblock %}
+ {% endblock %}
-{% block extra_javascript %}
-<script src="{% url telemeta-js "wz_jsgraphics.js" %}" type="text/javascript"></script>
+ {% block extra_javascript %}
+ <!--<script src="{% url telemeta-js "wz_jsgraphics.js" %}" type="text/javascript"></script>-->
<script src="{% url telemeta-js "soundmanager2.js" %}" type="text/javascript"></script>
-<script src="{% url telemeta-timeside "src/timeside.js" %}" type="text/javascript"></script>
-<script src="{% url telemeta-js "playerUtils.js" %}" type="text/javascript"></script>
<script src="{% url telemeta-timeside "src/playlist.js" %}" type="text/javascript"></script>
<script type="text/javascript">
soundManager.url = '{% url telemeta-swf "./" %}';
soundManager.flashVersion = 9;
soundManager.useMovieStar = true; // enable MP4/M4A/AAC
soundManager.debugMode = false;
- set_player_image_url('{% url telemeta-item-visualize item.public_id,visualizer_id,"WIDTH","HEIGHT" %}');
- load_player({{ item.approx_duration.as_seconds }});
+ soundManager.allowPolling = true;
- jQuery(document).ready(function(){
- var content = $('#_popup_add_to_playlist').clone(true,true);
- $('#_add_to_playlist').click(function(e){return popup.show(content,e)});
- });
+ var setupPlaylist = function(){
+ {% if user.is_authenticated %}
+ var p = playlistUtils;
+ {% for playlist in playlists %}
+ p.addPlaylist('{{ playlist.playlist.title }}','{{playlist.playlist.public_id}}');
+ {% endfor %}
+ {% endif %}
+ {% if item %}
+ var anchor = jQuery('#_add_to_playlist');
+ if(anchor.length){
+ anchor.click(function(evtObj_){
+ p.showPopupAddToPlaylist(evtObj_,'item','{{item.public_id}}','item added to selected playlist');return false;
+ });
+ }
+ {% endif %}
+ };
+
{% if item %}
- var ITEM_PUBLIC_ID = '{{item.public_id}}';
+ var ITEM_PUBLIC_ID = '{{item.public_id}}';
{% endif %}
+
+ var scripts = ["{% url telemeta-js "wz_jsgraphics.js" %}",
+ //"{% url telemeta-timeside "src/playlist.js" %}",
+ "{% url telemeta-timeside "src/timeside.js" %}","{% url telemeta-js "playerUtils.js" %}"];
+
+ var _sound_manager_loaded=false;
+ var _jQuery_loaded = false;
+
+ jQuery(document).ready(function(){
+ _jQuery_loaded=true;
+ if(_sound_manager_loaded){
+ loadScripts(scripts, function(){loadPlayer('{% url telemeta-item-analyze-xml item.public_id %}',$('.ts-wave a').attr('href'));setupPlaylist()});
+ }
+ });
+ //$('.ts-wave a').attr('href')
+ soundManager.onready(function() {
+ _sound_manager_loaded=true;
+ if(_jQuery_loaded){
+ loadScripts(scripts, function(){loadPlayer('{% url telemeta-item-analyze-xml item.public_id %}',$('.ts-wave a').attr('href'));setupPlaylist()});
+ }
+ });
</script>
+<!--item.approx_duration-->
{% endblock %}
{% if item %}
{% block submenu %}
-<div>
- {% block tools %}
- <a href="{% url telemeta-item-dublincore item.public_id %}" class="component_icon button icon_dublin_core">Dublin Core</a>
- {% if user.is_authenticated and perms.telemeta.change_mediaitem %}
- <a href="{% url telemeta-item-edit item.public_id %}" class="component_icon button icon_edit">{% trans "Edit" %}</a>
- <a href="{% url telemeta-item-copy item.public_id %}" class="component_icon button icon_copy">{% trans "Copy" %}</a>
- {% endif %}
- {% if user.is_authenticated %}
-
- <a id="_add_to_playlist" href=# class="component_icon button icon_add">{% trans "Add to playlist" %}</a>
- <div id="_popup_add_to_playlist" style="display:none">
- {% for playlist in playlists %}
- <a href="#" class="component_icon list_item icon_playlist"
- onclick="playlistUtils.addToPlaylist('{{playlist.playlist.public_id}}','item','{{item.pk}}');">{{ playlist.playlist.title }}</a>
- {% endfor %}
- </div>
+{% endblock %}
+{% block content_header %}
+<table><tr><td>
+ <h3><img src="images/item.png" style="vertical-align:middle" /> Item : {{ item }}</h3>
+ </td><td class="rightcol">
+ {% block tools %}
+ {% if user.is_authenticated and perms.telemeta.change_mediaitem %}
+ <a href="{% url telemeta-item-edit item.public_id %}" class="component_icon button icon_edit">{% trans "Edit" %}</a>
+ <a href="{% url telemeta-item-copy item.public_id %}" class="component_icon button icon_copy">{% trans "Copy" %}</a>
+ {% endif %}
+ {% if user.is_authenticated %}
+ <a id="_add_to_playlist" href='#' class="component_icon button icon_add">{% trans "Add to playlist" %}</a>
- {% endif %}
- <a href="{% url telemeta-item-detail previous %}" class="component_icon button icon_previous">{% trans "Previous" %}</a>
- <a href="{% url telemeta-item-detail next %}" class="component_icon button icon_next">{% trans "Next" %}</a>
- {% endblock tools %}
-</div>
+ {% endif %}
+ <a href="{% url telemeta-item-detail previous %}" class="component_icon button icon_previous">{% trans "Previous" %}</a>
+ <a href="{% url telemeta-item-detail next %}" class="component_icon button icon_next">{% trans "Next" %}</a>
+ <a href="{% url telemeta-item-dublincore item.public_id %}" class="component_icon button icon_dublin_core">Dublin Core</a>
+ {% endblock tools %}
+ </td></tr></table>
{% endblock %}
{% block content %}
-<h3><img src="images/item.png" style="vertical-align:middle" /> Item : {{ item }}</h3>
+<!--<div id="div_title" style="padding-bottom:2ex;padding-right:362px"><h3><img src="images/item.png" style="vertical-align:middle" /> Item : {{ item }}</h3></div>-->
<div class="{% if item.file %}{% if item.public_access == 'full' or public_access or user.is_staff %}with-rightcol{% endif %}{% endif %}">
- {% if item.file %}
+ {% if item.file %}
{% if public_access or user.is_staff %}
<div id="player_maximized" class="ts-skin-lab">
<a href="#" class="toggle">Minimize</a>
</div>
<div id="tabs_container">
- <!-- <ul class="tabs_" >
- <li><a href="#">Analysis</a></li>
- <li><a href="#">Markers</a></li>
- </ul>-->
- <a id="tab_analysis" name ="analyzer_div_id" href="#">{% trans "Analysis" %}</a>
- <a id="tab_markers" name="markers_div_id" href="#">{% trans "Markers" %}</a>
+ <!-- this div will be hidden when everything is fully loaded-->
+ <span id="loading_span" href="#"><img style="vertical-align:middle" src="/images/wait.gif"/>
+ <span id="loading_span_text">Loading...</span></span>
+ <a id="tab_analysis" style="display:none" name ="analyzer_div_id" href="#">{% trans "Analysis" %}</a>
+ <a id="tab_markers" style="display:none" name="markers_div_id" href="#">{% trans "Markers" %}</a>
</div>
- <!--<div class="tab_container_">-->
- <!-- <div id="tab1" class="tab_content">
- Content
- </div>
- <div id="tab2" class="tab_content">
- Content
- </div>
- </div>-->
+
<div class="markers" id="markers_div_id"></div>
<div class="analyzer" id="analyzer_div_id">
<td>{% trans "Value" %}</td>
<td>{% trans "Unit" %}</td>
</tr>
- {% for analyser in analysers %}
+ <!-- {% for analyser in analysers %}
<tr class="analyzer-line">
<td>
{{ analyser.name }}
{{ analyser.unit }}
</td>
</tr>
- {% endfor %}
+ {% endfor %}-->
</table>
</div>
<!--</div>-->
<p><img src="images/download.png" style="vertical-align:middle" /> {% trans "Download:" %}
{% for format in export_formats %}
<a href="{% url telemeta-item-export item.public_id,format.extension %}">
- <img src="images/{{ format.extension }}.png" style="vertical-align:middle" alt="{{ format.extension }}" /></a>
+ <img src="images/{{ format.extension }}.png" style="vertical-align:middle" alt="{{ format.extension }}" /></a>
{% endfor %}</p>
</div>
{% endif %}
</div>
{% endif %}
{% endif %}
-
+
{% block infos %}
<div class="infos">
{% block general_info %}
</div>
{% endblock technical_data %}
</div>
- {% endblock infos %}
+ {% endblock infos %}
</div> <!-- with-rightcol -->
{% endblock %}
{% else %}