From 28bd146972af4f9f76e909dce15bbb215d1315ec Mon Sep 17 00:00:00 2001 From: Paulo R Date: Tue, 17 Jun 2014 01:36:21 -0300 Subject: [PATCH 1/3] Adds support for uploading your own videos --- dj_elastictranscoder/admin.py | 19 +++- dj_elastictranscoder/management/__init__.py | 0 .../management/commands/__init__.py | 0 .../management/commands/et_create_job.py | 13 +++ .../management/commands/et_read_job.py | 13 +++ ...dd_output__add_unique_output_job_preset.py | 93 +++++++++++++++++++ dj_elastictranscoder/models.py | 66 ++++++++++++- dj_elastictranscoder/transcoder.py | 22 +++-- dj_elastictranscoder/utils.py | 30 ++++++ 9 files changed, 244 insertions(+), 12 deletions(-) create mode 100644 dj_elastictranscoder/management/__init__.py create mode 100644 dj_elastictranscoder/management/commands/__init__.py create mode 100644 dj_elastictranscoder/management/commands/et_create_job.py create mode 100644 dj_elastictranscoder/management/commands/et_read_job.py create mode 100644 dj_elastictranscoder/migrations/0002_auto__add_job__add_upload__add_output__add_unique_output_job_preset.py create mode 100644 dj_elastictranscoder/utils.py diff --git a/dj_elastictranscoder/admin.py b/dj_elastictranscoder/admin.py index c7ad991..6465879 100644 --- a/dj_elastictranscoder/admin.py +++ b/dj_elastictranscoder/admin.py @@ -1,7 +1,24 @@ from django.contrib import admin -from .models import EncodeJob +from .models import EncodeJob, Upload, Job, Output + + +class OutputInline(admin.StackedInline): + model = Output + + +class JobAdmin(admin.ModelAdmin): + inlines = (OutputInline, ) + + +admin.site.register(Job, JobAdmin) + + +admin.site.register(Upload) + class EncodeJobAdmin(admin.ModelAdmin): list_display = ('id', 'state', 'message') list_filters = ('state',) + + admin.site.register(EncodeJob, EncodeJobAdmin) diff --git a/dj_elastictranscoder/management/__init__.py b/dj_elastictranscoder/management/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dj_elastictranscoder/management/commands/__init__.py b/dj_elastictranscoder/management/commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dj_elastictranscoder/management/commands/et_create_job.py b/dj_elastictranscoder/management/commands/et_create_job.py new file mode 100644 index 0000000..8d3d057 --- /dev/null +++ b/dj_elastictranscoder/management/commands/et_create_job.py @@ -0,0 +1,13 @@ +from django.core.management.base import BaseCommand + +from dj_elastictranscoder.models import Job +from dj_elastictranscoder.utils import et_create_job + + +class Command(BaseCommand): + help = "Sends Jobs to be executed remotely." + + def handle(self, *args, **options): + for pk in args: + job = Job.objects.get(pk=pk) + et_create_job(job) diff --git a/dj_elastictranscoder/management/commands/et_read_job.py b/dj_elastictranscoder/management/commands/et_read_job.py new file mode 100644 index 0000000..5c107a6 --- /dev/null +++ b/dj_elastictranscoder/management/commands/et_read_job.py @@ -0,0 +1,13 @@ +from django.core.management.base import BaseCommand + +from dj_elastictranscoder.models import Job +from dj_elastictranscoder.utils import et_read_job + + +class Command(BaseCommand): + help = "Reads Jobs and update it's info on Database." + + def handle(self, *args, **options): + for pk in args: + job = Job.objects.get(pk=pk) + et_read_job(job) diff --git a/dj_elastictranscoder/migrations/0002_auto__add_job__add_upload__add_output__add_unique_output_job_preset.py b/dj_elastictranscoder/migrations/0002_auto__add_job__add_upload__add_output__add_unique_output_job_preset.py new file mode 100644 index 0000000..033f1b1 --- /dev/null +++ b/dj_elastictranscoder/migrations/0002_auto__add_job__add_upload__add_output__add_unique_output_job_preset.py @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding model 'Job' + db.create_table(u'dj_elastictranscoder_job', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('pipeline_id', self.gf('django.db.models.fields.CharField')(default='1402976603358-rwcmfz', max_length=32)), + ('upload', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dj_elastictranscoder.Upload'])), + ('et_job_id', self.gf('django.db.models.fields.CharField')(max_length=100, blank=True)), + )) + db.send_create_signal(u'dj_elastictranscoder', ['Job']) + + # Adding model 'Upload' + db.create_table(u'dj_elastictranscoder_upload', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('video', self.gf('django.db.models.fields.files.FileField')(max_length=100)), + )) + db.send_create_signal(u'dj_elastictranscoder', ['Upload']) + + # Adding model 'Output' + db.create_table(u'dj_elastictranscoder_output', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('job', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dj_elastictranscoder.Job'])), + ('preset', self.gf('django.db.models.fields.CharField')(max_length=20)), + ('video', self.gf('django.db.models.fields.files.FileField')(max_length=100, blank=True)), + )) + db.send_create_signal(u'dj_elastictranscoder', ['Output']) + + # Adding unique constraint on 'Output', fields ['job', 'preset'] + db.create_unique(u'dj_elastictranscoder_output', ['job_id', 'preset']) + + + def backwards(self, orm): + # Removing unique constraint on 'Output', fields ['job', 'preset'] + db.delete_unique(u'dj_elastictranscoder_output', ['job_id', 'preset']) + + # Deleting model 'Job' + db.delete_table(u'dj_elastictranscoder_job') + + # Deleting model 'Upload' + db.delete_table(u'dj_elastictranscoder_upload') + + # Deleting model 'Output' + db.delete_table(u'dj_elastictranscoder_output') + + + models = { + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + u'dj_elastictranscoder.encodejob': { + 'Meta': {'object_name': 'EncodeJob'}, + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.CharField', [], {'max_length': '100', 'primary_key': 'True'}), + 'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'message': ('django.db.models.fields.TextField', [], {}), + 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'state': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0', 'db_index': 'True'}) + }, + u'dj_elastictranscoder.job': { + 'Meta': {'object_name': 'Job'}, + 'et_job_id': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'pipeline_id': ('django.db.models.fields.CharField', [], {'default': "'1402976603358-rwcmfz'", 'max_length': '32'}), + 'upload': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['dj_elastictranscoder.Upload']"}) + }, + u'dj_elastictranscoder.output': { + 'Meta': {'unique_together': "(('job', 'preset'),)", 'object_name': 'Output'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'job': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['dj_elastictranscoder.Job']"}), + 'preset': ('django.db.models.fields.CharField', [], {'max_length': '20'}), + 'video': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}) + }, + u'dj_elastictranscoder.upload': { + 'Meta': {'object_name': 'Upload'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'video': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}) + } + } + + complete_apps = ['dj_elastictranscoder'] \ No newline at end of file diff --git a/dj_elastictranscoder/models.py b/dj_elastictranscoder/models.py index ee35afc..79d4588 100644 --- a/dj_elastictranscoder/models.py +++ b/dj_elastictranscoder/models.py @@ -1,7 +1,64 @@ +# coding: utf-8 + from django.db import models from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.generic import GenericForeignKey +from storages.backends.s3boto import S3BotoStorage + + +storage = S3BotoStorage() + + +class Upload(models.Model): + video = models.FileField(storage=storage, upload_to="videos/upload") + + def __unicode__(self): + return self.video.name + + +class Output(models.Model): + PRESET = ( + ('1351620000001-100070', 'Web: Facebook, SmugMug, Vimeo, YouTube'), + ) + + job = models.ForeignKey("Job") + preset = models.CharField(max_length=20, choices=PRESET) + video = models.FileField( + blank=True, + storage=storage, + upload_to="videos/output", + ) + + class Meta: + unique_together = ('job', 'preset', ) + + def __unicode__(self): + if self.video: + return u"%s as %s DONE" % (self.job, self.get_preset_display()) + return u"%s as %s" % (self.job, self.get_preset_display()) + + +class Job(models.Model): + PIPELINE_ID = ( + ('1402976603358-rwcmfz', 'Mediacenter'), + ) + + pipeline_id = models.CharField( + choices=PIPELINE_ID, + default=PIPELINE_ID[0][0], + max_length=32) + + upload = models.ForeignKey("Upload") + + et_job_id = models.CharField( + blank=True, + max_length=100, + ) + + def __unicode__(self): + return u"%s on %s" % (self.upload, self.pipeline_id) + class EncodeJob(models.Model): STATE_CHOICES = ( @@ -11,10 +68,17 @@ class EncodeJob(models.Model): (3, 'Warning'), (4, 'Complete'), ) + id = models.CharField(max_length=100, primary_key=True) content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() - state = models.PositiveIntegerField(choices=STATE_CHOICES, default=0, db_index=True) + + state = models.PositiveIntegerField( + choices=STATE_CHOICES, + db_index=True, + default=0, + ) + content_object = GenericForeignKey() message = models.TextField() created_at = models.DateTimeField(auto_now_add=True) diff --git a/dj_elastictranscoder/transcoder.py b/dj_elastictranscoder/transcoder.py index 0d5062d..403cd6c 100644 --- a/dj_elastictranscoder/transcoder.py +++ b/dj_elastictranscoder/transcoder.py @@ -7,7 +7,8 @@ class Transcoder(object): - def __init__(self, pipeline_id, region=None, access_key_id=None, secret_access_key=None): + def __init__(self, pipeline_id, region=None, access_key_id=None, + secret_access_key=None): self.pipeline_id = pipeline_id if not region: @@ -19,10 +20,10 @@ def __init__(self, pipeline_id, region=None, access_key_id=None, secret_access_k self.aws_access_key_id = access_key_id if not secret_access_key: - secret_access_key = getattr(settings, 'AWS_SECRET_ACCESS_KEY', None) + secret_access_key = \ + getattr(settings, 'AWS_SECRET_ACCESS_KEY', None) self.aws_secret_access_key = secret_access_key - if self.aws_access_key_id is None: assert False, 'Please provide AWS_ACCESS_KEY_ID' @@ -32,21 +33,22 @@ def __init__(self, pipeline_id, region=None, access_key_id=None, secret_access_k if self.aws_region is None: assert False, 'Please provide AWS_REGION' - def encode(self, input_name, outputs): - encoder = elastictranscoder.connect_to_region( - self.aws_region, + et = self.get_et() + self.message = \ + et.create_job(self.pipeline_id, input_name, outputs=outputs) + + def get_et(self): + return elastictranscoder.connect_to_region( + self.aws_region, aws_access_key_id=self.aws_access_key_id, aws_secret_access_key=self.aws_secret_access_key) - self.message = encoder.create_job(self.pipeline_id, input_name, outputs=outputs) - - def create_job_for_object(self, obj): content_type = ContentType.objects.get_for_model(obj) - job = EncodeJob() job.id = self.message['Job']['Id'] job.content_type = content_type job.object_id = obj.id job.save() + return job.id diff --git a/dj_elastictranscoder/utils.py b/dj_elastictranscoder/utils.py new file mode 100644 index 0000000..eda8c59 --- /dev/null +++ b/dj_elastictranscoder/utils.py @@ -0,0 +1,30 @@ +from django.utils.text import slugify + +from .transcoder import Transcoder + + +def et_create_job(job): + qs = job.output_set.filter(video="") + if qs.exists(): + outputs = [] + for output in qs: + outputs.append({ + 'Key': 'outputs/%s.mp4' % slugify(unicode(output)), + 'PresetId': output.preset + }) + + transcoder = Transcoder(job.pipeline_id) + transcoder.encode({'Key': job.upload.video.name}, outputs) + job.et_job_id = transcoder.create_job_for_object(job) + job.save(update_fields=['et_job_id']) + + +def et_read_job(job): + transcoder = Transcoder(job.pipeline_id) + et = transcoder.get_et() + data = et.read_job(job.et_job_id) + for output in data['Job']['Outputs']: + if output['Status'] == 'Complete': + obj = job.output_set.get(preset=output['PresetId']) + obj.video = output['Key'] + obj.save(update_fields=['video']) From 5750ed98ea181729057999ae04c07db39c81f538 Mon Sep 17 00:00:00 2001 From: Paulo R Date: Mon, 23 Jun 2014 21:51:37 -0300 Subject: [PATCH 2/3] Changes return --- dj_elastictranscoder/transcoder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dj_elastictranscoder/transcoder.py b/dj_elastictranscoder/transcoder.py index 403cd6c..c0e392b 100644 --- a/dj_elastictranscoder/transcoder.py +++ b/dj_elastictranscoder/transcoder.py @@ -51,4 +51,4 @@ def create_job_for_object(self, obj): job.content_type = content_type job.object_id = obj.id job.save() - return job.id + return self.message['Job']['Id'] From dbb0eaadd307f8f7075f357909a46a6944405763 Mon Sep 17 00:00:00 2001 From: Paulo R Date: Tue, 24 Jun 2014 17:53:47 -0300 Subject: [PATCH 3/3] Changes model logic --- dj_elastictranscoder/admin.py | 8 +--- .../management/commands/et_cron.py | 15 +++++++ ...t.py => 0002_auto__add_job__add_upload.py} | 35 +++++---------- dj_elastictranscoder/models.py | 45 +++++++++---------- dj_elastictranscoder/utils.py | 18 +++----- 5 files changed, 56 insertions(+), 65 deletions(-) create mode 100644 dj_elastictranscoder/management/commands/et_cron.py rename dj_elastictranscoder/migrations/{0002_auto__add_job__add_upload__add_output__add_unique_output_job_preset.py => 0002_auto__add_job__add_upload.py} (73%) diff --git a/dj_elastictranscoder/admin.py b/dj_elastictranscoder/admin.py index 6465879..af090b2 100644 --- a/dj_elastictranscoder/admin.py +++ b/dj_elastictranscoder/admin.py @@ -1,13 +1,9 @@ from django.contrib import admin -from .models import EncodeJob, Upload, Job, Output - - -class OutputInline(admin.StackedInline): - model = Output +from .models import EncodeJob, Upload, Job class JobAdmin(admin.ModelAdmin): - inlines = (OutputInline, ) + pass admin.site.register(Job, JobAdmin) diff --git a/dj_elastictranscoder/management/commands/et_cron.py b/dj_elastictranscoder/management/commands/et_cron.py new file mode 100644 index 0000000..2812086 --- /dev/null +++ b/dj_elastictranscoder/management/commands/et_cron.py @@ -0,0 +1,15 @@ +from django.core.management.base import BaseCommand + +from dj_elastictranscoder.models import Job +from dj_elastictranscoder.utils import et_create_job, et_read_job + + +class Command(BaseCommand): + help = "Sends and receive jobs" + + def handle(self, *args, **options): + for job in Job.objects.filter(et_job_id=""): + et_create_job(job) + + for job in Job.objects.filter(output=""): + et_read_job(job) diff --git a/dj_elastictranscoder/migrations/0002_auto__add_job__add_upload__add_output__add_unique_output_job_preset.py b/dj_elastictranscoder/migrations/0002_auto__add_job__add_upload.py similarity index 73% rename from dj_elastictranscoder/migrations/0002_auto__add_job__add_upload__add_output__add_unique_output_job_preset.py rename to dj_elastictranscoder/migrations/0002_auto__add_job__add_upload.py index 033f1b1..d5de9ef 100644 --- a/dj_elastictranscoder/migrations/0002_auto__add_job__add_upload__add_output__add_unique_output_job_preset.py +++ b/dj_elastictranscoder/migrations/0002_auto__add_job__add_upload.py @@ -13,10 +13,15 @@ def forwards(self, orm): (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ('pipeline_id', self.gf('django.db.models.fields.CharField')(default='1402976603358-rwcmfz', max_length=32)), ('upload', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dj_elastictranscoder.Upload'])), + ('preset', self.gf('django.db.models.fields.CharField')(default='1351620000001-100070', max_length=20)), ('et_job_id', self.gf('django.db.models.fields.CharField')(max_length=100, blank=True)), + ('output', self.gf('django.db.models.fields.files.FileField')(max_length=100, blank=True)), )) db.send_create_signal(u'dj_elastictranscoder', ['Job']) + # Adding unique constraint on 'Job', fields ['upload', 'preset'] + db.create_unique(u'dj_elastictranscoder_job', ['upload_id', 'preset']) + # Adding model 'Upload' db.create_table(u'dj_elastictranscoder_upload', ( (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), @@ -24,22 +29,10 @@ def forwards(self, orm): )) db.send_create_signal(u'dj_elastictranscoder', ['Upload']) - # Adding model 'Output' - db.create_table(u'dj_elastictranscoder_output', ( - (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('job', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dj_elastictranscoder.Job'])), - ('preset', self.gf('django.db.models.fields.CharField')(max_length=20)), - ('video', self.gf('django.db.models.fields.files.FileField')(max_length=100, blank=True)), - )) - db.send_create_signal(u'dj_elastictranscoder', ['Output']) - - # Adding unique constraint on 'Output', fields ['job', 'preset'] - db.create_unique(u'dj_elastictranscoder_output', ['job_id', 'preset']) - def backwards(self, orm): - # Removing unique constraint on 'Output', fields ['job', 'preset'] - db.delete_unique(u'dj_elastictranscoder_output', ['job_id', 'preset']) + # Removing unique constraint on 'Job', fields ['upload', 'preset'] + db.delete_unique(u'dj_elastictranscoder_job', ['upload_id', 'preset']) # Deleting model 'Job' db.delete_table(u'dj_elastictranscoder_job') @@ -47,9 +40,6 @@ def backwards(self, orm): # Deleting model 'Upload' db.delete_table(u'dj_elastictranscoder_upload') - # Deleting model 'Output' - db.delete_table(u'dj_elastictranscoder_output') - models = { u'contenttypes.contenttype': { @@ -70,19 +60,14 @@ def backwards(self, orm): 'state': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0', 'db_index': 'True'}) }, u'dj_elastictranscoder.job': { - 'Meta': {'object_name': 'Job'}, + 'Meta': {'unique_together': "(('upload', 'preset'),)", 'object_name': 'Job'}, 'et_job_id': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'output': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}), 'pipeline_id': ('django.db.models.fields.CharField', [], {'default': "'1402976603358-rwcmfz'", 'max_length': '32'}), + 'preset': ('django.db.models.fields.CharField', [], {'default': "'1351620000001-100070'", 'max_length': '20'}), 'upload': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['dj_elastictranscoder.Upload']"}) }, - u'dj_elastictranscoder.output': { - 'Meta': {'unique_together': "(('job', 'preset'),)", 'object_name': 'Output'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'job': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['dj_elastictranscoder.Job']"}), - 'preset': ('django.db.models.fields.CharField', [], {'max_length': '20'}), - 'video': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}) - }, u'dj_elastictranscoder.upload': { 'Meta': {'object_name': 'Upload'}, u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), diff --git a/dj_elastictranscoder/models.py b/dj_elastictranscoder/models.py index 79d4588..ace7ab6 100644 --- a/dj_elastictranscoder/models.py +++ b/dj_elastictranscoder/models.py @@ -17,33 +17,15 @@ def __unicode__(self): return self.video.name -class Output(models.Model): - PRESET = ( - ('1351620000001-100070', 'Web: Facebook, SmugMug, Vimeo, YouTube'), - ) - - job = models.ForeignKey("Job") - preset = models.CharField(max_length=20, choices=PRESET) - video = models.FileField( - blank=True, - storage=storage, - upload_to="videos/output", - ) - - class Meta: - unique_together = ('job', 'preset', ) - - def __unicode__(self): - if self.video: - return u"%s as %s DONE" % (self.job, self.get_preset_display()) - return u"%s as %s" % (self.job, self.get_preset_display()) - - class Job(models.Model): PIPELINE_ID = ( ('1402976603358-rwcmfz', 'Mediacenter'), ) + PRESET = ( + ('1351620000001-100070', 'Web: Facebook, SmugMug, Vimeo, YouTube'), + ) + pipeline_id = models.CharField( choices=PIPELINE_ID, default=PIPELINE_ID[0][0], @@ -51,13 +33,30 @@ class Job(models.Model): upload = models.ForeignKey("Upload") + preset = models.CharField( + choices=PRESET, + default=PRESET[0][0], + max_length=20, + ) + et_job_id = models.CharField( blank=True, max_length=100, ) + output = models.FileField( + blank=True, + storage=storage, + upload_to="videos/output", + ) + + class Meta: + unique_together = ("upload", "preset", ) + def __unicode__(self): - return u"%s on %s" % (self.upload, self.pipeline_id) + if self.output: + return u"%s as %s DONE" % (self.upload, self.get_preset_display()) + return u"%s as %s" % (self.upload, self.get_preset_display()) class EncodeJob(models.Model): diff --git a/dj_elastictranscoder/utils.py b/dj_elastictranscoder/utils.py index eda8c59..02bfd31 100644 --- a/dj_elastictranscoder/utils.py +++ b/dj_elastictranscoder/utils.py @@ -4,14 +4,11 @@ def et_create_job(job): - qs = job.output_set.filter(video="") - if qs.exists(): - outputs = [] - for output in qs: - outputs.append({ - 'Key': 'outputs/%s.mp4' % slugify(unicode(output)), - 'PresetId': output.preset - }) + if not job.output: + outputs = [{ + 'Key': 'outputs/%s.mp4' % slugify(unicode(job)), + 'PresetId': job.preset + }] transcoder = Transcoder(job.pipeline_id) transcoder.encode({'Key': job.upload.video.name}, outputs) @@ -25,6 +22,5 @@ def et_read_job(job): data = et.read_job(job.et_job_id) for output in data['Job']['Outputs']: if output['Status'] == 'Complete': - obj = job.output_set.get(preset=output['PresetId']) - obj.video = output['Key'] - obj.save(update_fields=['video']) + job.output = output['Key'] + job.save(update_fields=['output'])