10000 Adds support for uploading your own videos · mauler/django-elastic-transcoder@28bd146 · GitHub
[go: up one dir, main page]

Skip to content

Commit 28bd146

Browse files
committed
Adds support for uploading your own videos
1 parent 9b3e633 commit 28bd146

File tree

9 files changed

+244
-12
lines changed

9 files changed

+244
-12
lines changed

dj_elastictranscoder/admin.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,24 @@
11
from django.contrib import admin
2-
from .models import EncodeJob
2+
from .models import EncodeJob, Upload, Job, Output
3+
4+
5+
class OutputInline(admin.StackedInline):
6+
model = Output
7+
8+
9+
class JobAdmin(admin.ModelAdmin):
10+
inlines = (OutputInline, )
11+
12+
13+
admin.site.register(Job, JobAdmin)
14+
15+
16+
admin.site.register(Upload)
17+
318

419
class EncodeJobAdmin(admin.ModelAdmin):
520
list_display = ('id', 'state', 'message')
621
list_filters = ('state',)
22+
23+
724
admin.site.register(EncodeJob, EncodeJobAdmin)

dj_elastictranscoder/management/__init__.py

Whitespace-only changes.

dj_elastictranscoder/management/commands/__init__.py

Whitespace-only changes.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from django.core.management.base import BaseCommand
2+
3+
from dj_elastictranscoder.models import Job
4+
from dj_elastictranscoder.utils import et_create_job
5+
6+
7+
class Command(BaseCommand):
8+
help = "Sends Jobs to be executed remotely."
9+
10+
def handle(self, *args, **options):
11+
for pk in args:
12+
job = Job.objects.get(pk=pk)
13+
et_create_job(job)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from django.core.management.base import BaseCommand
2+
3+
from dj_elastictranscoder.models import Job
4+
from dj_elastictranscoder.utils import et_read_job
5+
6+
7+
class Command(BaseCommand):
8+
help = "Reads Jobs and update it's info on Database."
9+
10+
def handle(self, *args, **options):
11+
for pk in args:
12+
job = Job.objects.get(pk=pk)
13+
et_read_job(job)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# -*- coding: utf-8 -*-
2+
import datetime
3+
from south.db import db
4+
from south.v2 import SchemaMigration
5+
from django.db import models
6+
7+
8+
class Migration(SchemaMigration):
9+
10+
def forwards(self, orm):
11+
# Adding model 'Job'
12+
db.create_table(u'dj_elastictranscoder_job', (
13+
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
14+
('pipeline_id', self.gf('django.db.models.fields.CharField')(default='1402976603358-rwcmfz', max_length=32)),
15+
('upload', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dj_elastictranscoder.Upload'])),
16+
('et_job_id', self.gf('django.db.models.fields.CharField')(max_length=100, blank=True)),
17+
))
18+
db.send_create_signal(u'dj_elastictranscoder', ['Job'])
19+
20+
# Adding model 'Upload'
21+
db.create_table(u'dj_elastictranscoder_upload', (
22+
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
23+
('video', self.gf('django.db.models.fields.files.FileField')(max_length=100)),
24+
))
25+
db.send_create_signal(u'dj_elastictranscoder', ['Upload'])
26+
27+
# Adding model 'Output'
28+
db.create_table(u'dj_elastictranscoder_output', (
29+
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
30+
('job', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dj_elastictranscoder.Job'])),
31+
('preset', self.gf('django.db.models.fields.CharField')(max_length=20)),
32+
('video', self.gf('django.db.models.fields.files.FileField')(max_length=100, blank=True)),
33+
))
34+
db.send_create_signal(u'dj_elastictranscoder', ['Output'])
35+
36+
# Adding unique constraint on 'Output', fields ['job', 'preset']
37+
db.create_unique(u'dj_elastictranscoder_output', ['job_id', 'preset'])
38+
39+
40+
def backwards(self, orm):
41+
# Removing unique constraint on 'Output', fields ['job', 'preset']
42+
db.delete_unique(u'dj_elastictranscoder_output', ['job_id', 'preset'])
43+
44+
# Deleting model 'Job'
45+
db.delete_table(u'dj_elastictranscoder_job')
46+
47+
# Deleting model 'Upload'
48+
db.delete_table(u'dj_elastictranscoder_upload')
49+
50+
# Deleting model 'Output'
51+
db.delete_table(u'dj_elastictranscoder_output')
52+
53+
54+
models = {
55+
u'contenttypes.contenttype': {
56+
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
57+
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
58+
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
59+
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
60+
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
61+
},
62+
u'dj_elastictranscoder.encodejob': {
63+
'Meta': {'object_name': 'EncodeJob'},
64+
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
65+
'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
66+
'id': ('django.db.models.fields.CharField', [], {'max_length': '100', 'primary_key': 'True'}),
67+
'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
68+
'message': ('django.db.models.fields.TextField', [], {}),
69+
'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
70+
'state': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0', 'db_index': 'True'})
71+
},
72+
u'dj_elastictranscoder.job': {
73+
'Meta': {'object_name': 'Job'},
74+
'et_job_id': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
75+
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
76+
'pipeline_id': ('django.db.models.fields.CharField', [], {'default': "'1402976603358-rwcmfz'", 'max_length': '32'}),
77+
'upload': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['dj_elastictranscoder.Upload']"})
78+
},
79+
u'dj_elastictranscoder.output': {
80+
'Meta': {'unique_together': "(('job', 'preset'),)", 'object_name': 'Output'},
81+
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
82+
'job': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['dj_elastictranscoder.Job']"}),
83+
'preset': ('django.db.models.fields.CharField', [], {'max_length': '20'}),
84+
'video': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'})
85+
},
86+
u'dj_elastictranscoder.upload': {
87+
'Meta': {'object_name': 'Upload'},
88+
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
89+
'video': ('django.db.models.fields.files.FileField', [], {'max_length': '100'})
90+
}
91+
}
92+
93+
complete_apps = ['dj_elastictranscoder']

dj_elastictranscoder/models.py

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,64 @@
1+
# coding: utf-8
2+
13
from django.db import models
24
from django.contrib.contenttypes.models import ContentType
35
from django.contrib.contenttypes.generic import GenericForeignKey
46

7+
from storages.backends.s3boto import S3BotoStorage
8+
9+
10+
storage = S3BotoStorage()
11+
12+
13+
class Upload(models.Model):
14+
video = models.FileField(storage=storage, upload_to="videos/upload")
15+
16+
def __unicode__(self):
17+
return self.video.name
18+
19+
20+
class Output(models.Model):
21+
PRESET = (
22+
('1351620000001-100070', 'Web: Facebook, SmugMug, Vimeo, YouTube'),
23+
)
24+
25+
job = models.ForeignKey("Job")
26+
preset = models.CharField(max_length=20, choices=PRESET)
27+
video = models.FileField(
28+
blank=True,
29+
storage=storage,
30+
upload_to="videos/output",
31+
)
32+
33+
class Meta:
34+
unique_together = ('job', 'preset', )
35+
36+
def __unicode__(self):
37+
if self.video:
38+
return u"%s as %s DONE" % (self.job, self.get_preset_display())
39+
return u"%s as %s" % (self.job, self.get_preset_display())
40+
41+
42+
class Job(models.Model):
43+
PIPELINE_ID = (
44+
('1402976603358-rwcmfz', 'Mediacenter'),
45+
)
46+
47+
pipeline_id = models.CharField(
48+
choices=PIPELINE_ID,
49+
default=PIPELINE_ID[0][0],
50+
max_length=32)
51+
52+
upload = models.ForeignKey("Upload")
53+
54+
et_job_id = models.CharField(
55+
blank=True,
56+
max_length=100,
57+
)
58+
59+
def __unicode__(self):
60+
return u"%s on %s" % (self.upload, self.pipeline_id)
61+
562

663
class EncodeJob(models.Model):
764
STATE_CHOICES = (
@@ -11,10 +68,17 @@ class EncodeJob(models.Model):
1168
(3, 'Warning'),
1269
(4, 'Complete'),
1370
)
71+
1472
id = models.CharField(max_length=100, primary_key=True)
1573
content_type = models.ForeignKey(ContentType)
1674
object_id = models.PositiveIntegerField()
17-
state = models.PositiveIntegerField(choices=STATE_CHOICES, default=0, db_index=True)
75+
76+
state = models.PositiveIntegerField(
77+
choices=STATE_CHOICES,
78+
db_index=True,
79+
default=0,
80+
)
81+
1882
content_object = GenericForeignKey()
1983
message = models.TextField()
2084
created_at = models.DateTimeField(auto_now_add=True)

dj_elastictranscoder/transcoder.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77

88

99
class Transcoder(object):
10-
def __init__(self, pipeline_id, region=None, access_key_id=None, secret_access_key=None):
10+
def __init__(self, pipeline_id, region=None, access_key_id=None,
11+
secret_access_key=None):
1112
self.pipeline_id = pipeline_id
1213

1314
if not region:
@@ -19,10 +20,10 @@ def __init__(self, pipeline_id, region=None, access_key_id=None, secret_access_k
1920
self.aws_access_key_id = access_key_id
2021

2122
if not secret_access_key:
22-
secret_access_key = getattr(settings, 'AWS_SECRET_ACCESS_KEY', None)
23+
secret_access_key = \
24+
getattr(settings, 'AWS_SECRET_ACCESS_KEY', None)
2325
self.aws_secret_access_key = secret_access_key
2426

25-
2627
if self.aws_access_key_id is None:
2728
assert False, 'Please provide AWS_ACCESS_KEY_ID'
2829

@@ -32,21 +33,22 @@ def __init__(self, pipeline_id, region=None, access_key_id=None, secret_access_k
3233
if self.aws_region is None:
3334
assert False, 'Please provide AWS_REGION'
3435

35-
3636
def encode(self, input_name, outputs):
37-
encoder = elastictranscoder.connect_to_region(
38-
self.aws_region,
37+
et = self.get_et()
38+
self.message = \
39+
et.create_job(self.pipeline_id, input_name, outputs=outputs)
40+
41+
def get_et(self):
42+
return elastictranscoder.connect_to_region(
43+
self.aws_region,
3944
aws_access_key_id=self.aws_access_key_id,
4045
aws_secret_access_key=self.aws_secret_access_key)
4146

42-
self.message = encoder.create_job(self.pipeline_id, input_name, outputs=outputs)
43-
44-
4547
def create_job_for_object(self, obj):
4648
content_type = ContentType.objects.get_for_model(obj)
47-
4849
job = EncodeJob()
4950
job.id = self.message['Job']['Id']
5051
job.content_type = content_type
5152
job.object_id = obj.id
5253
job.save()
54+
return job.id

dj_elastictranscoder/utils.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from django.utils.text import slugify
2+
3+
from .transcoder import Transcoder
4+
5+
6+
def et_create_job(job):
7+
qs = job.output_set.filter(video="")
8+
if qs.exists():
9+
outputs = []
10+
for output in qs:
11+
outputs.append({
12+
'Key': 'outputs/%s.mp4' % slugify(unicode(output)),
13+
'PresetId': output.preset
14+
})
15+
16+
transcoder = Transcoder(job.pipeline_id)
17+
transcoder.encode({'Key': job.upload.video.name}, outputs)
18+
job.et_job_id = transcoder.create_job_for_object(job)
19+
job.save(update_fields=['et_job_id'])
20+
21+
22+
def et_read_job(job):
23+
transcoder = Transcoder(job.pipeline_id)
24+
et = transcoder.get_et()
25+
data = et.read_job(job.et_job_id)
26+
for output in data['Job']['Outputs']:
27+
if output['Status'] == 'Complete':
28+
obj = job.output_set.get(preset=output['PresetId'])
29+
obj.video = output['Key']
30+
obj.save(update_fields=['video'])

0 commit comments

Comments
 (0)
0