serve frames and videos with X-Sendfile header

This commit is contained in:
j 2010-02-16 18:11:57 +05:30
parent 7c0e365a0a
commit 1354a1ddc5
6 changed files with 51 additions and 8 deletions

4
README
View File

@ -30,3 +30,7 @@ Development:
we are using django, http://docs.djangoproject.com/en/dev/ we are using django, http://docs.djangoproject.com/en/dev/
communication between webserver and background tasks is done via rabbitmq communication between webserver and background tasks is done via rabbitmq
http://github.com/ask/carrot/ for more info on the lib used to communicate http://github.com/ask/carrot/ for more info on the lib used to communicate
Apache setup:
sudo apt-get install libapache2-mod-wsgi libapache2-mod-xsendfile

View File

@ -8,16 +8,21 @@
Allow from all Allow from all
</Directory> </Directory>
Alias /.bzr /oxdb/.bzr <Location />
Alias /static __PREFIX__/oxdb/static XSendFile on
Alias /favicon.ico __PREFIX__/oxdb/static/favicon.ico XSendFileAllowAbove on
Alias /media __PREFIX__/oxdb/media </Location>
Alias /.bzr __PREFIX__/.bzr
Alias /static __PREFIX__/pandora/static
Alias /favicon.ico __PREFIX__/pandora/static/favicon.ico
Alias /media __PREFIX__/pandora/media
Alias /admin/media __PREFIX__/src/django/django/contrib/admin/media Alias /admin/media __PREFIX__/src/django/django/contrib/admin/media
Alias /static/js/jquery.js __PREFIX__/src/django/django/contrib/admin/media/js/jquery.min.js Alias /static/js/jquery.js __PREFIX__/src/django/django/contrib/admin/media/js/jquery.min.js
WSGIScriptAlias / __PREFIX__/wsgi/django.wsgi WSGIScriptAlias / __PREFIX__/wsgi/django.wsgi
WSGIDaemonProcess oxdb user=oxdb group=oxdb threads=25 python-path=__PREFIX__/lib/python2.6/site-packages/ WSGIDaemonProcess pandora user=pandora group=pandora threads=25 python-path=__PREFIX__/lib/python2.6/site-packages/
WSGIProcessGroup oxdb WSGIProcessGroup pandora
ServerSignature Off ServerSignature Off
</VirtualHost> </VirtualHost>

View File

@ -10,6 +10,7 @@ from django.db.models import Q
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.utils import simplejson as json from django.utils import simplejson as json
from django.conf import settings
from oxdjango import fields from oxdjango import fields
import oxlib import oxlib
@ -430,6 +431,11 @@ class Movie(models.Model):
self.get('series_title', ''), self.get('episode_title', ''), self.get('series_title', ''), self.get('episode_title', ''),
self.get('season', ''), self.get('episode', '')) self.get('season', ''), self.get('episode', ''))
def frame(self, position, width=128):
#FIXME: compute offset and so on
f = self.files.all()[0]
return f.frame(position, width)
def updateFind(self): def updateFind(self):
try: try:
f = self.find f = self.find
@ -1155,7 +1161,9 @@ class File(models.Model):
def frame(self, position, width=128): def frame(self, position, width=128):
videoFile = getattr(self, 'stream_%s'%settings.VIDEO_PROFILE).path videoFile = getattr(self, 'stream_%s'%settings.VIDEO_PROFILE).path
frameFolder = os.path.join(os.path.dirname(videoFile), 'frames') frameFolder = os.path.join(os.path.dirname(videoFile), 'frames')
extract.frame(videoFile, position, frameFolder, width) if position<= self.duration:
return extract.frame(videoFile, position, frameFolder, width)
return None
def editable(self, user): def editable(self, user):
''' '''

View File

@ -6,6 +6,8 @@ from django.conf.urls.defaults import *
urlpatterns = patterns("backend.views", urlpatterns = patterns("backend.views",
(r'^upload/$', 'firefogg_upload'), (r'^upload/$', 'firefogg_upload'),
(r'^frame/(?P<id>.*)/(?P<position>.*)\.(?P<size>\d+).jpg$', 'frame'),
(r'^stream/(?P<id>.*).(?P<quality>.*).ogv$', 'video'),
(r'^$', 'api'), (r'^$', 'api'),
) )

View File

@ -1,17 +1,19 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4 # vi:si:et:sw=4:sts=4:ts=4
from __future__ import division
import os.path import os.path
import re import re
from datetime import datetime from datetime import datetime
from urllib2 import unquote from urllib2 import unquote
import json import json
import mimetypes
from django import forms from django import forms
from django.core.paginator import Paginator from django.core.paginator import Paginator
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.db.models import Q, Avg, Count from django.db.models import Q, Avg, Count
from django.http import HttpResponse from django.http import HttpResponse, Http404
from django.shortcuts import render_to_response, get_object_or_404, get_list_or_404 from django.shortcuts import render_to_response, get_object_or_404, get_list_or_404
from django.template import RequestContext from django.template import RequestContext
from django.conf import settings from django.conf import settings
@ -23,6 +25,8 @@ except ImportError:
from oxdjango.decorators import login_required_json from oxdjango.decorators import login_required_json
from oxdjango.shortcuts import render_to_json_response, get_object_or_404_json, json_response from oxdjango.shortcuts import render_to_json_response, get_object_or_404_json, json_response
from oxdjango.http import HttpFileResponse
import oxlib
import models import models
import utils import utils
@ -630,6 +634,24 @@ def api_subtitles(request):
l = models.Subtitles.objects.filter(movie_file__oshash=oshash).values('language') l = models.Subtitles.objects.filter(movie_file__oshash=oshash).values('language')
response['data']['languages'] = [f['language'] for f in l] response['data']['languages'] = [f['language'] for f in l]
return render_to_json_response(response) return render_to_json_response(response)
def video(request, id, quality):
movie = get_object_or_404(models.Movie, movieId=id)
if quality not in settings.VIDEO_ENCODING:
raise Http404
stream = getattr(movie, 'stream_'+quality)
response = HttpFileResponse(stream.path, content_type='video/ogg')
#FIXME: movie needs duration field
#response['Content-Duration'] = movie.duration
return response
def frame(request, id, position, size):
movie = get_object_or_404(models.Movie, movieId=id)
position = oxlib.time2ms(position)/1000
frame = movie.frame(position, int(size))
if not frame:
raise Http404
return HttpFileResponse(frame, content_type='image/jpeg')
''' '''
GET list GET list

View File

@ -13,6 +13,8 @@ DEBUG = True
TEMPLATE_DEBUG = DEBUG TEMPLATE_DEBUG = DEBUG
JSON_DEBUG = False JSON_DEBUG = False
XSENDFILE = False
ADMINS = ( ADMINS = (
('j', 'j@mailb.org'), ('j', 'j@mailb.org'),
) )