首页 > 编程 > Python > 正文

用Python的Django框架完成视频处理任务的教程

2020-02-23 00:29:52
字体:
来源:转载
供稿:网友

Stickyworld 的网页应用已经支持视频拨放一段时间,但都是通过YouTube的嵌入模式实现。我们开始提供新的版本支持视频操作,可以让我们的用户不用受制于YouTube的服务。

我过去曾经参与过一个项目,客户需要视频转码功能,这实在不是个容易达成的需求。需要大量的读取每一个视频、音讯与视频容器的格式再输出符合网页使用与喜好的视频格式。

考虑到这一点,我们决定将转码的工作交给 Encoding.com 。这个网站可以免费让你编码1GB大小的视频,超过1GB容量的文件将采取分级计价收费。

开发的代码如下,我上传了一个178KB容量的两秒视频来测试代码是否成功运作。当测试过程没有发生任何的例外错误后,我继续测试其它更大的外部文件。

 
阶段一:用户上传视频文件

现在这的新的代码段提供了一个基于 HTML5且可以快速上手的 的上传机制。用CoffeeScript撰写的代码,可以从客户端上传文件到服务器端。
 

$scope.upload_slide = (upload_slide_form) ->  file = document.getElementById("slide_file").files[0]  reader = new FileReader()  reader.readAsDataURL file  reader.onload = (event) ->   result = event.target.result   fileName = document.getElementById("slide_file").files[0].name   $.post "/world/upload_slide",    data: result    name: fileName    room_id: $scope.room.id    (response_data) ->     if response_data.success? is not yes      console.error "There was an error uploading the file", response_data     else      console.log "Upload successful", response_data  reader.onloadstart = ->   console.log "onloadstart"  reader.onprogress = (event) ->   console.log "onprogress", event.total, event.loaded, (event.loaded / event.total) * 100  reader.onabort = ->   console.log "onabort"  reader.onerror = ->   console.log "onerror"  reader.onloadend = (event) ->   console.log "onloadend", event

最好可以通过 (“slide_file”).files 且经由独立的POST上传每个文件,而不是由一个POST需求上传所有文件。稍后我们会解释这点。

 
阶段二:验证并上传至 Amazon S3

后端我们运行了Django与RabbitMQ。主要的模块如下:
 

$ pip install 'Django>=1.5.2' 'django-celery>=3.0.21' /  'django-storages>=1.1.8' 'lxml>=3.2.3' 'python-magic>=0.4.3'我建立了两个模块:SlideUploadQueue 用来储存每一次上传的数据,SlideVideoMedia 则是用来储存每个要上传影片的数据。 class SlideUploadQueue(models.Model):  created_by = models.ForeignKey(User)  created_time = models.DateTimeField(db_index=True)  original_file = models.FileField(    upload_to=filename_sanitiser, blank=True, default='')  media_type = models.ForeignKey(MediaType)  encoding_com_tracking_code = models.CharField(    default='', max_length=24, blank=True)   STATUS_AWAITING_DATA = 0  STATUS_AWAITING_PROCESSING = 1  STATUS_PROCESSING = 2  STATUS_AWAITING_3RD_PARTY_PROCESSING = 5  STATUS_FINISHED = 3  STATUS_FAILED = 4   STATUS_LIST = (    (STATUS_AWAITING_DATA, 'Awaiting Data'),    (STATUS_AWAITING_PROCESSING, 'Awaiting processing'),    (STATUS_PROCESSING, 'Processing'),    (STATUS_AWAITING_3RD_PARTY_PROCESSING,      'Awaiting 3rd-party processing'),    (STATUS_FINISHED, 'Finished'),    (STATUS_FAILED, 'Failed'),  )   status = models.PositiveSmallIntegerField(    default=STATUS_AWAITING_DATA, choices=STATUS_LIST)   class Meta:    verbose_name = 'Slide'    verbose_name_plural = 'Slide upload queue'   def save(self, *args, **kwargs):    if not self.created_time:      self.created_time = /        datetime.utcnow().replace(tzinfo=pytz.utc)     return super(SlideUploadQueue, self).save(*args, **kwargs)   def __unicode__(self):    if self.id is None:      return 'new <SlideUploadQueue>'    return '<SlideUploadQueue> %d' % self.id class SlideVideoMedia(models.Model):  converted_file = models.FileField(    upload_to=filename_sanitiser, blank=True, default='')   FORMAT_MP4 = 0  FORMAT_WEBM = 1  FORMAT_OGG = 2  FORMAT_FL9 = 3  FORMAT_THUMB = 4   supported_formats = (    (FORMAT_MP4, 'MPEG 4'),    (FORMAT_WEBM, 'WebM'),    (FORMAT_OGG, 'OGG'),    (FORMAT_FL9, 'Flash 9 Video'),    (FORMAT_THUMB, 'Thumbnail'),  )   mime_types = (    (FORMAT_MP4, 'video/mp4'),    (FORMAT_WEBM, 'video/webm'),    (FORMAT_OGG, 'video/ogg'),    (FORMAT_FL9, 'video/mp4'),    (FORMAT_THUMB, 'image/jpeg'),  )   format = models.PositiveSmallIntegerField(    default=FORMAT_MP4, choices=supported_formats)   class Meta:    verbose_name = 'Slide video'    verbose_name_plural = 'Slide videos'   def __unicode__(self):    if self.id is None:      return 'new <SlideVideoMedia>'    return '<SlideVideoMedia> %d' % self.id            
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表