From 632185979656633a8b79098f815a544306862d47 Mon Sep 17 00:00:00 2001 From: j <0x006A@0x2620.org> Date: Sat, 15 Feb 2014 16:13:43 +0000 Subject: [PATCH] support uploading videos in any of the supported resolutions, to avoid upscaling --- pandora/archive/models.py | 14 ++++++++++---- pandora/archive/tasks.py | 5 +++-- pandora/archive/views.py | 15 +++++++++++---- static/js/uploadVideoDialog.js | 22 +++++++++++++++++----- 4 files changed, 41 insertions(+), 15 deletions(-) diff --git a/pandora/archive/models.py b/pandora/archive/models.py index 76a378e46..1a7c36e99 100644 --- a/pandora/archive/models.py +++ b/pandora/archive/models.py @@ -308,13 +308,19 @@ class File(models.Model): return True return False - def save_chunk_stream(self, chunk, chunk_id=-1, done=False): + def stream_resolution(self): + config = settings.CONFIG['video'] + height = self.info['video'][0]['height'] if self.info.get('video') else None + for resolution in sorted(config['resolutions']): + if height and height <= resolution: + return resolution + return resolution + + def save_chunk_stream(self, chunk, chunk_id, resolution, format, done): if not self.available: config = settings.CONFIG['video'] stream, created = Stream.objects.get_or_create( - file=self, - resolution=max(config['resolutions']), - format=config['formats'][0]) + file=self, resolution=resolution, format=format) if created: stream.media.name = stream.path(stream.name()) ox.makedirs(os.path.dirname(stream.media.path)) diff --git a/pandora/archive/tasks.py b/pandora/archive/tasks.py index 828024c34..216c3d8c8 100644 --- a/pandora/archive/tasks.py +++ b/pandora/archive/tasks.py @@ -112,9 +112,10 @@ def extract_stream(fileId): file = models.File.objects.get(id=fileId) if file.data: config = settings.CONFIG['video'] + resolution = file.stream_resolution() stream, created = models.Stream.objects.get_or_create( - file=file, resolution=max(config['resolutions']), - format=config['formats'][0]) + file=file, resolution=resolution, format=config['formats'][0] + ) if created: stream.media.name = stream.path(stream.name()) stream.encode() diff --git a/pandora/archive/views.py b/pandora/archive/views.py index 4663911dc..b01a848eb 100644 --- a/pandora/archive/views.py +++ b/pandora/archive/views.py @@ -224,7 +224,13 @@ def firefogg_upload(request): profile = request.GET['profile'] oshash = request.GET['id'] config = settings.CONFIG['video'] - video_profile = "%sp.%s" % (max(config['resolutions']), config['formats'][0]) + + resolution, format = profile.split('p.') + resolution = int(resolution) + if resolution not in config['resolutions'] \ + or format not in config['formats']: + response = json_response(status=500, text='invalid profile') + return render_to_json_response(response) #handle video upload if request.method == 'POST': @@ -232,14 +238,15 @@ def firefogg_upload(request): if 'chunk' in request.FILES and oshash: f = get_object_or_404(models.File, oshash=oshash) form = ChunkForm(request.POST, request.FILES) - if form.is_valid() and profile == video_profile and f.editable(request.user): + if form.is_valid() and f.editable(request.user): c = form.cleaned_data['chunk'] chunk_id = form.cleaned_data['chunkId'] response = { 'result': 1, 'resultUrl': request.build_absolute_uri('/%s'%f.item.itemId) } - if not f.save_chunk_stream(c, chunk_id, form.cleaned_data['done']): + if not f.save_chunk_stream(c, chunk_id, resolution, format, + form.cleaned_data['done']): response['result'] = -1 elif form.cleaned_data['done']: f.uploading = False @@ -255,7 +262,7 @@ def firefogg_upload(request): response['done'] = 1 return render_to_json_response(response) #init upload - elif oshash and profile == video_profile: + elif oshash: #404 if oshash is not know, files must be registered via update api first f = get_object_or_404(models.File, oshash=oshash) if f.editable(request.user): diff --git a/static/js/uploadVideoDialog.js b/static/js/uploadVideoDialog.js index 069cc3f90..88ddf61ff 100644 --- a/static/js/uploadVideoDialog.js +++ b/static/js/uploadVideoDialog.js @@ -156,7 +156,7 @@ pandora.ui.uploadVideoDialog = function(data) { } setTimeout(function() { $info.html('' + filename + '
' + Ox._('uploading...')); - uploadStream(item, oshash, file); + uploadStream(item, info, file); }); }, function(progress) { @@ -167,9 +167,21 @@ pandora.ui.uploadVideoDialog = function(data) { }); } - function uploadStream(item, oshash, file) { - var format = pandora.site.video.formats[0], - resolution = Ox.max(pandora.site.video.resolutions); + function getResolution(info) { + var height = info.video && info.video.length + ? info.video[0].height + : Ox.max(pandora.site.video.resolutions), + resolution = pandora.site.video.resolutions + .sort().filter(function(resolution) { + return height <= resolution; + })[0] || Ox.max(pandora.site.video.resolutions); + return resolution; + } + + function uploadStream(item, info, file) { + var oshash = info.oshash, + format = pandora.site.video.formats[0], + resolution = getResolution(info); pandora.$ui.upload = pandora.chunkupload({ file: file, url: '/api/upload/?profile=' + resolution + 'p.' + format + '&id=' + oshash, @@ -273,7 +285,7 @@ pandora.ui.uploadVideoDialog = function(data) { format = pandora.site.video.formats[0], fps, options = {}, - resolution = Ox.max(pandora.site.video.resolutions); + resolution = getResolution(info); if (format == 'webm') { options.videoCodec = 'vp8'; options.audioCodec = 'vorbis';