support uploading videos in any of the supported resolutions, to avoid upscaling

This commit is contained in:
j 2014-02-15 16:13:43 +00:00
parent 00cf921782
commit 6321859796
4 changed files with 41 additions and 15 deletions

View file

@ -308,13 +308,19 @@ class File(models.Model):
return True return True
return False 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: if not self.available:
config = settings.CONFIG['video'] config = settings.CONFIG['video']
stream, created = Stream.objects.get_or_create( stream, created = Stream.objects.get_or_create(
file=self, file=self, resolution=resolution, format=format)
resolution=max(config['resolutions']),
format=config['formats'][0])
if created: if created:
stream.media.name = stream.path(stream.name()) stream.media.name = stream.path(stream.name())
ox.makedirs(os.path.dirname(stream.media.path)) ox.makedirs(os.path.dirname(stream.media.path))

View file

@ -112,9 +112,10 @@ def extract_stream(fileId):
file = models.File.objects.get(id=fileId) file = models.File.objects.get(id=fileId)
if file.data: if file.data:
config = settings.CONFIG['video'] config = settings.CONFIG['video']
resolution = file.stream_resolution()
stream, created = models.Stream.objects.get_or_create( stream, created = models.Stream.objects.get_or_create(
file=file, resolution=max(config['resolutions']), file=file, resolution=resolution, format=config['formats'][0]
format=config['formats'][0]) )
if created: if created:
stream.media.name = stream.path(stream.name()) stream.media.name = stream.path(stream.name())
stream.encode() stream.encode()

View file

@ -224,7 +224,13 @@ def firefogg_upload(request):
profile = request.GET['profile'] profile = request.GET['profile']
oshash = request.GET['id'] oshash = request.GET['id']
config = settings.CONFIG['video'] 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 #handle video upload
if request.method == 'POST': if request.method == 'POST':
@ -232,14 +238,15 @@ def firefogg_upload(request):
if 'chunk' in request.FILES and oshash: if 'chunk' in request.FILES and oshash:
f = get_object_or_404(models.File, oshash=oshash) f = get_object_or_404(models.File, oshash=oshash)
form = ChunkForm(request.POST, request.FILES) 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'] c = form.cleaned_data['chunk']
chunk_id = form.cleaned_data['chunkId'] chunk_id = form.cleaned_data['chunkId']
response = { response = {
'result': 1, 'result': 1,
'resultUrl': request.build_absolute_uri('/%s'%f.item.itemId) '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 response['result'] = -1
elif form.cleaned_data['done']: elif form.cleaned_data['done']:
f.uploading = False f.uploading = False
@ -255,7 +262,7 @@ def firefogg_upload(request):
response['done'] = 1 response['done'] = 1
return render_to_json_response(response) return render_to_json_response(response)
#init upload #init upload
elif oshash and profile == video_profile: elif oshash:
#404 if oshash is not know, files must be registered via update api first #404 if oshash is not know, files must be registered via update api first
f = get_object_or_404(models.File, oshash=oshash) f = get_object_or_404(models.File, oshash=oshash)
if f.editable(request.user): if f.editable(request.user):

View file

@ -156,7 +156,7 @@ pandora.ui.uploadVideoDialog = function(data) {
} }
setTimeout(function() { setTimeout(function() {
$info.html('<b>' + filename + '</b><br>' + Ox._('uploading...')); $info.html('<b>' + filename + '</b><br>' + Ox._('uploading...'));
uploadStream(item, oshash, file); uploadStream(item, info, file);
}); });
}, },
function(progress) { function(progress) {
@ -167,9 +167,21 @@ pandora.ui.uploadVideoDialog = function(data) {
}); });
} }
function uploadStream(item, oshash, file) { function getResolution(info) {
var format = pandora.site.video.formats[0], var height = info.video && info.video.length
resolution = Ox.max(pandora.site.video.resolutions); ? 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({ pandora.$ui.upload = pandora.chunkupload({
file: file, file: file,
url: '/api/upload/?profile=' + resolution + 'p.' + format + '&id=' + oshash, url: '/api/upload/?profile=' + resolution + 'p.' + format + '&id=' + oshash,
@ -273,7 +285,7 @@ pandora.ui.uploadVideoDialog = function(data) {
format = pandora.site.video.formats[0], format = pandora.site.video.formats[0],
fps, fps,
options = {}, options = {},
resolution = Ox.max(pandora.site.video.resolutions); resolution = getResolution(info);
if (format == 'webm') { if (format == 'webm') {
options.videoCodec = 'vp8'; options.videoCodec = 'vp8';
options.audioCodec = 'vorbis'; options.audioCodec = 'vorbis';