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 76a378e4..1a7c36e9 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 828024c3..216c3d8c 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 4663911d..b01a848e 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 069cc3f9..88ddf61f 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';