diff --git a/pandora/archive/extract.py b/pandora/archive/extract.py index 859fb9e99..66a43c7f7 100644 --- a/pandora/archive/extract.py +++ b/pandora/archive/extract.py @@ -298,7 +298,7 @@ def divide(num, by): arr = [] div = int(num / by) mod = num % by - for i in range(by): + for i in range(int(by)): arr.append(div + (i > by - 1 - mod)) return arr @@ -313,7 +313,7 @@ def timeline_strip(movie, cuts, info, prefix): timeline_height = 64 timeline_width = 1500 fps = 25 - frames = duration * fps + frames = int(duration * fps) if cuts[0] != 0: cuts.insert(0, 0) @@ -327,31 +327,33 @@ def timeline_strip(movie, cuts, info, prefix): timeline_image = Image.new('RGB', (timeline_width, timeline_height)) if frame in cuts: c = cuts.index(frame) - duration = cuts[c + 1] - cuts[c] - stills = math.ceil(duration / (video_width * timeline_height / video_height)) - widths = divide(duration, stills) - still = frame - if _debug: - print widths, duration, stills, cuts[c], cuts[c + 1] - for s in range(int(stills)): - still_ratio = widths[s] / timeline_height - if video_ratio > still_ratio: - width = int(round(video_height * still_ratio)) - left = int((video_width - width) / 2) - box = (left, 0, left + width, video_height) - else: - height = int(round(video_width / still_ratio)) - top = int((video_height - height) / 2) - box = (0, top, video_width, top + height) + if c +1 < len(cuts): + duration = cuts[c + 1] - cuts[c] + stills = math.ceil(duration / (video_width * timeline_height / video_height)) + widths = divide(duration, stills) + still = frame if _debug: - print frame, 'cut', c, 'still', s, still, 'width', widths[s], box - #FIXME: why does this have to be still+1? - frame_image = Image.open(movie.frame((still+1)/fps)) - frame_image = frame_image.crop(box).resize((widths[s], timeline_height), Image.ANTIALIAS) - for x_ in range(widths[s]): - line_image.append(frame_image.crop((x_, 0, x_ + 1, timeline_height))) - still += widths[s] - timeline_image.paste(line_image[frame], (x, 0)) + print widths, duration, stills, cuts[c], cuts[c + 1] + for s in range(int(stills)): + still_ratio = widths[s] / timeline_height + if video_ratio > still_ratio: + width = int(round(video_height * still_ratio)) + left = int((video_width - width) / 2) + box = (left, 0, left + width, video_height) + else: + height = int(round(video_width / still_ratio)) + top = int((video_height - height) / 2) + box = (0, top, video_width, top + height) + if _debug: + print frame, 'cut', c, 'still', s, still, 'width', widths[s], box + #FIXME: why does this have to be still+1? + frame_image = Image.open(movie.frame((still+1)/fps)) + frame_image = frame_image.crop(box).resize((widths[s], timeline_height), Image.ANTIALIAS) + for x_ in range(widths[s]): + line_image.append(frame_image.crop((x_, 0, x_ + 1, timeline_height))) + still += widths[s] + if len(line_image) > frame: + timeline_image.paste(line_image[frame], (x, 0)) if x == timeline_width - 1: timeline_file = '%sstrip.64.%04d.png' % (prefix, i) if _debug: diff --git a/pandora/archive/migrations/0008_available.py b/pandora/archive/migrations/0008_available.py new file mode 100644 index 000000000..dfab018d2 --- /dev/null +++ b/pandora/archive/migrations/0008_available.py @@ -0,0 +1,148 @@ +# encoding: utf-8 +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + +class Migration(SchemaMigration): + + def forwards(self, orm): + + # Deleting field 'File.video_available' + db.delete_column('archive_file', 'video_available') + + + def backwards(self, orm): + + # Adding field 'File.video_available' + db.add_column('archive_file', 'video_available', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True), keep_default=False) + + + models = { + 'archive.file': { + 'Meta': {'object_name': 'File'}, + 'audio_codec': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'bits_per_pixel': ('django.db.models.fields.FloatField', [], {'default': '-1'}), + 'channels': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'data': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'display_aspect_ratio': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'duration': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'episode': ('django.db.models.fields.IntegerField', [], {'default': '-1'}), + 'framerate': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'height': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'info': ('oxdjango.fields.DictField', [], {'default': '{}'}), + 'is_audio': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'is_extra': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'is_main': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'is_subtitle': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'is_version': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'is_video': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'language': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '8'}), + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'movie': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'files'", 'to': "orm['backend.Movie']"}), + 'name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '2048'}), + 'oshash': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '16'}), + 'part': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}), + 'pixel_format': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pixels': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'samplerate': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'season': ('django.db.models.fields.IntegerField', [], {'default': '-1'}), + 'size': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'sort_name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '2048'}), + 'verified': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'version': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}), + 'video': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'video_codec': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'width': ('django.db.models.fields.IntegerField', [], {'default': '0'}) + }, + 'archive.fileinstance': { + 'Meta': {'unique_together': "(('name', 'folder', 'volume'),)", 'object_name': 'FileInstance'}, + 'atime': ('django.db.models.fields.IntegerField', [], {'default': '1283966008'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'ctime': ('django.db.models.fields.IntegerField', [], {'default': '1283966008'}), + 'file': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'instances'", 'to': "orm['archive.File']"}), + 'folder': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'mtime': ('django.db.models.fields.IntegerField', [], {'default': '1283966008'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '2048'}), + 'volume': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'files'", 'to': "orm['archive.Volume']"}) + }, + 'archive.frame': { + 'Meta': {'unique_together': "(('file', 'position'),)", 'object_name': 'Frame'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'file': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'frames'", 'to': "orm['archive.File']"}), + 'frame': ('django.db.models.fields.files.ImageField', [], {'default': 'None', 'max_length': '100', 'null': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'position': ('django.db.models.fields.FloatField', [], {}) + }, + 'archive.volume': { + 'Meta': {'unique_together': "(('user', 'name'),)", 'object_name': 'Volume'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'volumes'", 'to': "orm['auth.User']"}) + }, + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'backend.movie': { + 'Meta': {'object_name': 'Movie'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'imdb': ('oxdjango.fields.DictField', [], {'default': '{}'}), + 'json': ('oxdjango.fields.DictField', [], {'default': '{}'}), + 'metadata': ('oxdjango.fields.DictField', [], {'default': '{}'}), + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'movieId': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128', 'blank': 'True'}), + 'oxdbId': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '42', 'blank': 'True'}), + 'poster': ('django.db.models.fields.files.ImageField', [], {'default': 'None', 'max_length': '100', 'blank': 'True'}), + 'poster_frame': ('django.db.models.fields.FloatField', [], {'default': '-1'}), + 'poster_height': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'poster_url': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'poster_width': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'published': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'stream_aspect': ('django.db.models.fields.FloatField', [], {'default': '1.3333333333333333'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + } + } + + complete_apps = ['archive'] diff --git a/pandora/archive/models.py b/pandora/archive/models.py index 1741f73ea..bcee8b6a8 100644 --- a/pandora/archive/models.py +++ b/pandora/archive/models.py @@ -140,7 +140,6 @@ class File(models.Model): return r #upload and data handling - video_available = models.BooleanField(default=False) video = models.FileField(null=True, blank=True, upload_to=lambda f, x: file_path(f, '%s.webm'%settings.VIDEO_PROFILE)) data = models.FileField(null=True, blank=True, upload_to=lambda f, x: file_path(f, 'data.raw')) @@ -154,7 +153,7 @@ class File(models.Model): return True def save_chunk(self, chunk, chunk_id=-1): - if not self.video_available: + if not self.available: if not self.video: self.video.save('%s.webm'%settings.VIDEO_PROFILE, chunk) else: @@ -202,11 +201,10 @@ class FileInstance(models.Model): def movieId(self): return File.objects.get(oshash=self.oshash).movieId -def frame_path(f, name): +def frame_path(frame, name): ext = os.path.splitext(name)[-1] - name = "%s%s" % (f.position, ext) - h = f.file.oshash - return os.path.join('frame', h[:2], h[2:4], h[4:6], name) + name = "%s%s" % (frame.position, ext) + return file_path(frame.file, name) class Frame(models.Model): class Meta: diff --git a/pandora/archive/views.py b/pandora/archive/views.py index ecacf1bf0..0e6519ea9 100644 --- a/pandora/archive/views.py +++ b/pandora/archive/views.py @@ -170,6 +170,7 @@ def api_upload(request): ''' user = request.user f = get_object_or_404(models.File, oshash=request.POST['oshash']) + print request.FILES if 'frame' in request.FILES: if f.frames.count() == 0: for frame in request.FILES.getlist('frame'): @@ -230,7 +231,7 @@ def firefogg_upload(request): if f.editable(request.user): if f.video: f.video.delete() - f.video_available = False + f.available = False f.save() response = { #is it possible to no hardcode url here? diff --git a/pandora/backend/models.py b/pandora/backend/models.py index 2f136e9dd..e6510b78b 100644 --- a/pandora/backend/models.py +++ b/pandora/backend/models.py @@ -71,16 +71,6 @@ def getMovie(info): movie.save() return movie -def movie_path(f, size): - name = "%s.%s" % (size, 'ogv') - url_hash = f.movieId - return os.path.join('movie', url_hash[:2], url_hash[2:4], url_hash[4:6], name) - -def poster_path(f): - name = "%s.%s" % (f.movieId, 'jpg') - url_hash = f.movieId - return os.path.join('poster', url_hash[:2], url_hash[2:4], url_hash[4:6], name) - class Movie(models.Model): person_keys = ('director', 'writer', 'producer', 'editor', 'cinematographer', 'actor', 'character') facet_keys = person_keys + ('country', 'language', 'genre', 'keyword') @@ -137,7 +127,7 @@ class Movie(models.Model): self.imdb = ox.web.imdb.Imdb(self.movieId) self.save() - poster = models.ImageField(default=None, blank=True, upload_to=lambda f, x: poster_path(f)) + poster = models.ImageField(default=None, blank=True, upload_to=lambda m, x: os.path.join(movieid_path(m.movieId), "poster.jpg")) poster_url = models.TextField(blank=True) poster_height = models.IntegerField(default=0) poster_width = models.IntegerField(default=0) @@ -395,7 +385,7 @@ class Movie(models.Model): n = self.files.count() * 3 frame = int(math.floor(n/2)) part = 1 - for f in self.files.filter(is_main=True, video_available=True): + for f in self.files.filter(is_main=True, available=True): for frame in f.frames.all(): path = os.path.abspath(os.path.join(settings.MEDIA_ROOT, poster_path(self))) path = path.replace('.jpg', '%s.%s.jpg'%(part, frame.pos)) @@ -415,11 +405,11 @@ class Movie(models.Model): @property def timeline_prefix(self): - return os.path.join(settings.MEDIA_ROOT, 'stream', movieid_path(self.movieId), 'timeline') + return os.path.join(settings.MEDIA_ROOT, movieid_path(self.movieId), 'timeline') def updateStreams(self): files = {} - for f in self.files.filter(is_main=True, video_available=True): + for f in self.files.filter(is_main=True, available=True): files[utils.sort_title(f.name)] = f.video.path #FIXME: how to detect if something changed? @@ -429,24 +419,23 @@ class Movie(models.Model): cmd = [] for f in sorted(files): - if not cmd: - cmd.append(files[f]) - else: - cmd.append('+') - cmd.append(files[f]) + cmd.append('+') + cmd.append(files[f]) if not os.path.exists(os.path.dirname(stream.video.path)): os.makedirs(os.path.dirname(stream.video.path)) - cmd = [ 'mkvmerge', '-o', stream.video.path ] + cmd - subprocess.Popen(cmd) + cmd = [ 'mkvmerge', '-o', stream.video.path ] + cmd[1:] + p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + p.wait() stream.save() - extract.timeline(stream.video.path, self.timeline_prefix) - - extract.timeline_strip(self, self.metadata['cuts'], stream.info, self.timeline_prefix[:-8]) + if 'video' in stream.info: + extract.timeline(stream.video.path, self.timeline_prefix) + self.stream_aspect = stream.info['video'][0]['width']/stream.info['video'][0]['height'] + self.metadata['cuts'] = extract.cuts(self.timeline_prefix) + self.metadata['average_color'] = extract.average_color(self.timeline_prefix) + extract.timeline_strip(self, self.metadata['cuts'], stream.info, self.timeline_prefix[:-8]) stream.extract_derivatives() - self.metadata['cuts'] = extract.cuts(self.timeline_prefix) - self.metadata['average_color'] = extract.average_color(self.timeline_prefix) #something with poster self.available = True self.save() @@ -719,10 +708,10 @@ class Collection(models.Model): def movieid_path(h): - return os.path.join(h[:2], h[2:4], h[4:6], h[6:]) -def stream_path(f): - h = f.movie.movieId - return os.path.join('stream', movieid_path(h), f.profile) + return os.path.join('movie', h[:2], h[2:4], h[4:6], h[6:]) + +def stream_path(stream): + return os.path.join(movieid_path(stream.movie.movieId), stream.profile) class Stream(models.Model): class Meta: diff --git a/pandora/static/js/pandora.js b/pandora/static/js/pandora.js index e882069f3..c4c6196fe 100755 --- a/pandora/static/js/pandora.js +++ b/pandora/static/js/pandora.js @@ -59,7 +59,7 @@ var app = new Ox.App({ Ox.print('requestStop') app.$ui.loadingIcon.stop(); }); - + $.each(app.afterLaunch, function(i, f) { f() }); }); diff --git a/pandora/static/js/pandora.local.js b/pandora/static/js/pandora.local.js index 78d2d3568..9bab40685 100644 --- a/pandora/static/js/pandora.local.js +++ b/pandora/static/js/pandora.local.js @@ -1,4 +1,6 @@ -$(function() { +if(typeof(app.afterLaunch) == "undefined") + app.afterLaunch = []; +app.afterLaunch.push(function() { if (typeof(OxFF) == 'undefined') return; app.local = { @@ -53,6 +55,7 @@ $(function() { if(!cb) return null; return function(result) { + Ox.print("you called upload", result); var data = JSON.parse(result); cb(data) } @@ -211,41 +214,58 @@ $(function() { }); } else { app.local.files(name, function(result) { + var fileInfo = result.info; app.request('update', { 'volume': name, 'files': result.files }, function(result) { var videos = {}; - $.each(result.data.data, function(i, oshash) { - $.each(folder_ids, function(i, ids) { - if($.inArray(oshash, ids) > -1) { - if(!videos[i]) { - videos[i] = []; - var button = new Ox.Button({ - id: 'upload_' + oshash, - title: 'Upload', - width: 48 - }).bindEvent('click', function(fid) { return function(event, data) { - Ox.print(videos[fid]); - //$($('#'+fid).find('.OxCell')[2]).html('extracting data...'); - app.local.uploadVideos( - videos[fid], - function(data) { - $($('#'+fid).find('.OxCell')[2]).html('done'); - }, - function(data) { - $($('#'+fid).find('.OxCell')[2]).html(data.status +': '+ data.progress); - } - ); - }}(i)); - $($('#'+i).find('.OxCell')[2]).html(button.$element); - $('#'+i).css({'font-weight': 'bold'}); + function parseResult(result) { + $.each(result.data.data, function(i, oshash) { + $.each(folder_ids, function(i, ids) { + if($.inArray(oshash, ids) > -1) { + if(!videos[i]) { + videos[i] = []; + var button = new Ox.Button({ + id: 'upload_' + oshash, + title: 'Upload', + width: 48 + }).bindEvent('click', function(fid) { return function(event, data) { + Ox.print(videos[fid]); + //$($('#'+fid).find('.OxCell')[2]).html('extracting data...'); + app.local.uploadVideos( + videos[fid], + function(data) { + $($('#'+fid).find('.OxCell')[2]).html('done'); + }, + function(data) { + $($('#'+fid).find('.OxCell')[2]).html(data.status +': '+ data.progress); + } + ); + }}(i)); + $($('#'+i).find('.OxCell')[2]).html(button.$element); + $('#'+i).css({'font-weight': 'bold'}); + } + videos[i].push(oshash); + //add some double click callback here to trigger video upload + return false; } - videos[i].push(oshash); - //add some double click callback here to trigger video upload - return false; + }); + }); + }; + if (result.data.info.length>0) { + var post = {'info': {}}; + $.each(result.data.info, function(i, oshash) { + if(fileInfo[oshash]) { + post.info[oshash] = fileInfo[oshash]; } }); - }); + app.request('update', post, function(result) { + parseResult(result); + }); + } else { + parseResult(result); + } + }); var data = { items: [] @@ -303,10 +323,5 @@ $(function() { return url; }, }; - - if(typeof(app.afterLaunch) == "undefined") - app.afterLaunch = []; - app.afterLaunch.push(function() { - app.local.loadVolumes(); - }); + app.local.loadVolumes(); }); diff --git a/pandora/static/js/timeline.js b/pandora/static/js/timeline.js index 11664a5f4..395b2651e 100644 --- a/pandora/static/js/timeline.js +++ b/pandora/static/js/timeline.js @@ -23,7 +23,7 @@ $(function() { posterFrame = 1515, points = [2059, 2748], videoId = document.location.hash.substring(1), - videoUrl = "/" + videoId + "/96p." + ($.support.video.webm ? "webm": "mp4"). + videoUrl = "/" + videoId + "/96p." + ($.support.video.webm ? "webm": "mp4"), stripTimeline = false; $.getJSON("/" + videoId + "/data/video.json", function(video) { diff --git a/pandora/templates/index.html b/pandora/templates/index.html index 171ff3dae..d491379d4 100644 --- a/pandora/templates/index.html +++ b/pandora/templates/index.html @@ -12,6 +12,7 @@ +