forked from 0x2620/pandora
support merged download for specific resolution,format fixes #2353
This commit is contained in:
parent
6b58767d31
commit
c055c220e2
3 changed files with 50 additions and 62 deletions
|
@ -2,15 +2,16 @@
|
|||
# vi:si:et:sw=4:sts=4:ts=4
|
||||
from __future__ import division, with_statement
|
||||
|
||||
from datetime import datetime
|
||||
import os.path
|
||||
import subprocess
|
||||
from glob import glob
|
||||
import shutil
|
||||
import uuid
|
||||
import unicodedata
|
||||
from urllib import quote
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
import unicodedata
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
from glob import glob
|
||||
from urllib import quote
|
||||
|
||||
from django.db import models, transaction
|
||||
from django.db.models import Q, Sum, Max
|
||||
|
@ -451,6 +452,30 @@ class Item(models.Model):
|
|||
other.save()
|
||||
#FIXME: update poster, stills and streams after this
|
||||
|
||||
def merge_streams(self, output, resolution=None, format="webm"):
|
||||
streams = [s.get(resolution, format).media.path for s in self.streams()]
|
||||
if len(streams) > 1:
|
||||
if format == "webm":
|
||||
first = True
|
||||
cmd = ['mkvmerge', '-o', output]
|
||||
cmd += [streams[0]] + ['+' + s for s in streams[1:]]
|
||||
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
p.wait()
|
||||
return True
|
||||
elif format == "mp4":
|
||||
fd, tmp_output = tempfile.mkstemp('.mp4')
|
||||
shutil.copy(streams[0], tmp_output)
|
||||
for s in streams[1:]:
|
||||
cmd = ['MP4Box', '-cat', s, tmp_output]
|
||||
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
p.wait()
|
||||
shutil.copy(tmp_output, output)
|
||||
os.unlink(tmp_output)
|
||||
return True
|
||||
else:
|
||||
return None
|
||||
return streams[0] if streams else None
|
||||
|
||||
def get_posters(self):
|
||||
url = self.prefered_poster_url()
|
||||
external_posters = self.external_data.get('posters', {})
|
||||
|
@ -1191,18 +1216,6 @@ class Item(models.Model):
|
|||
Q(file__is_audio=True)|Q(file__is_video=True)
|
||||
).order_by('file__part', 'file__sort_path')
|
||||
|
||||
def merge_streams(self, output):
|
||||
first = True
|
||||
cmd = ['mkvmerge', '-o', output]
|
||||
streams = [s.media.path for s in self.streams()]
|
||||
if len(streams) > 1:
|
||||
cmd += [streams[0]] + ['+' + s for s in streams[1:]]
|
||||
print cmd
|
||||
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
p.wait()
|
||||
return True
|
||||
return streams[0] if streams else None
|
||||
|
||||
def update_timeline(self, force=False, async=True):
|
||||
streams = self.streams()
|
||||
self.make_timeline()
|
||||
|
|
|
@ -12,6 +12,11 @@ urlpatterns = patterns("item.views",
|
|||
(r'^(?P<id>[A-Z0-9].*)/timeline(?P<mode>[a-z]*)(?P<size>\d+)p(?P<position>\d+)\.(?P<format>png|jpg)$', 'timeline'),
|
||||
(r'^(?P<id>[A-Z0-9].*)/timeline(?P<mode>[a-z]*)(?P<size>\d+)p\.(?P<format>png|jpg)$', 'timeline'),
|
||||
|
||||
#download
|
||||
(r'^(?P<id>[A-Z0-9].*)/download$', 'download'),
|
||||
(r'^(?P<id>[A-Z0-9].*)/download/$', 'download'),
|
||||
(r'^(?P<id>[A-Z0-9].*)/download/(?P<resolution>\d+)p\.(?P<format>webm|ogv|mp4)$', 'download'),
|
||||
|
||||
#video
|
||||
(r'^(?P<id>[A-Z0-9].*)/(?P<resolution>\d+)p(?P<index>\d*)\.(?P<format>webm|ogv|mp4)$', 'video'),
|
||||
|
||||
|
@ -19,9 +24,6 @@ urlpatterns = patterns("item.views",
|
|||
(r'^(?P<id>[A-Z0-9].*)/torrent$', 'torrent'),
|
||||
(r'^(?P<id>[A-Z0-9].*)/torrent/(?P<filename>.*?)$', 'torrent'),
|
||||
|
||||
#download
|
||||
(r'^(?P<id>[A-Z0-9].*)/download/$', 'download'),
|
||||
|
||||
#export
|
||||
(r'^(?P<id>[A-Z0-9].*)/json$', 'item_json'),
|
||||
(r'^(?P<id>[A-Z0-9].*)/xml$', 'item_xml'),
|
||||
|
|
|
@ -840,51 +840,24 @@ def timeline(request, id, size, position=-1, format='jpg', mode=None):
|
|||
response.allow_access()
|
||||
return response
|
||||
|
||||
def download(request, id, index=1):
|
||||
def download(request, id, resolution=None, format='webm'):
|
||||
print 'download', id, resolution, format
|
||||
item = get_object_or_404(models.Item, itemId=id)
|
||||
if not resolution or int(resolution) not in settings.CONFIG['video']['resolutions']:
|
||||
resolution = max(settings.CONFIG['video']['resolutions'])
|
||||
format = 'webm'
|
||||
|
||||
if not item.access(request.user):
|
||||
return HttpResponseForbidden()
|
||||
if index:
|
||||
index = int(index) - 1
|
||||
else:
|
||||
index = 0
|
||||
streams = item.streams()
|
||||
if index + 1 > streams.count():
|
||||
raise Http404
|
||||
stream = streams[index].get(resolution, format)
|
||||
if not stream.available or not stream.media:
|
||||
raise Http404
|
||||
path = stream.media.path
|
||||
content_type = mimetypes.guess_type(path)[0]
|
||||
ext = os.path.splitext(path)[-1]
|
||||
filename = "%s - %s %s%s" % (
|
||||
item.get('title'),
|
||||
settings.SITENAME,
|
||||
item.itemId,
|
||||
ext
|
||||
)
|
||||
response = HttpFileResponse(path, content_type=content_type)
|
||||
response['Content-Disposition'] = "attachment; filename*=UTF-8''%s" % quote(filename.encode('utf-8'))
|
||||
return response
|
||||
|
||||
def download(request, id):
|
||||
item = get_object_or_404(models.Item, itemId=id)
|
||||
resolution = max(settings.CONFIG['video']['resolutions'])
|
||||
resolution = int(resolution)
|
||||
if not item.access(request.user) or not item.rendered:
|
||||
return HttpResponseForbidden()
|
||||
ext = '.webm'
|
||||
filename = "%s - %s %s%s" % (
|
||||
item.get('title'),
|
||||
settings.SITENAME,
|
||||
item.itemId,
|
||||
ext
|
||||
)
|
||||
ext = '.%s' % format
|
||||
parts = ['%s - %s ' % (item.get('title'), settings.SITENAME), item.itemId]
|
||||
if resolution != max(settings.CONFIG['video']['resolutions']):
|
||||
parts.append('.%dp' % resolution)
|
||||
parts.append(ext)
|
||||
filename = ''.join(parts)
|
||||
video = NamedTemporaryFile(suffix=ext)
|
||||
content_type = mimetypes.guess_type(video.name)[0]
|
||||
r = item.merge_streams(video.name)
|
||||
r = item.merge_streams(video.name, resolution, format)
|
||||
if not r:
|
||||
return HttpResponseForbidden()
|
||||
elif r == True:
|
||||
|
|
Loading…
Reference in a new issue