如何获取视频的长度以便在上传开始之前验证 django 表单?

Get*_*one 1 python django ffmpeg django-forms

我有一个在 Heroku 上运行的应用程序,允许用户上传视频,然后我使用 ffmpeg 使用 celery 和 redis-to-go 执行 3 个任务:

1) Check the format and if it isn't already mp4, convert it to mp4.
2) Extract a 3 minute clip, in mp4 format
3) Grab an image from the video
Run Code Online (Sandbox Code Playgroud)

问题是我想在上传视频之前验证视频长度并运行三个任务,因为我想确保所有视频至少为 15 分钟,如果不是,我想引发 ValidationError。因此,在验证表单时,我想做这样的事情:

def clean(self, *args, **kwargs):        
    data = super(ContentTypeRestrictedVideoField, self).clean(*args, **kwargs)

    file = data.file
    try:
        content_type = file.content_type
        main, extension = content_type.split('/')
        if content_type in self.content_types:
            if file._size > self.max_upload_size:
                raise forms.ValidationError(_('Please keep filesize under %s. Current filesize %s') % (filesizeformat(self.max_upload_size), filesizeformat(file._size)))
            if VIDEO_LENGTH < MINIMUM_LENGTH:
                raise forms.ValidationError(_('Please make sure video file is at least %s. Current video length %s') % (MINIMUM_LENGTH, VIDEO_LENGTH)
        else:
            raise forms.ValidationError(_('File type is not supported. File must be mov, flv, avi, mpeg, wmv, or mp4.'))
    except AttributeError:
        pass        

    return data
Run Code Online (Sandbox Code Playgroud)

对于 VIDEO_LENGTH 和 MINIMUM_LENGTH 我该怎么办?我读到 ffprobe 可用于获取持续时间,但它不适用于我正在使用的构建包,而且我非常缺乏经验。我不能只验证文件大小,因为它可能会因多种因素而有很大差异。有人对我可以尝试什么有任何解决方案吗?谢谢

tom*_*mmy 5

我能够使用 moviepy 来完成此任务。

我的用例有点不同,但原理应该是相同的。

from moviepy.editor import *


def video_form_upload(request):
if request.method == 'POST':
    form = VideoForm(request.POST, request.FILES)

    if form.is_valid():
        obj = form.save(commit=False)
        # 'upload' is the name of the input field
        vid = request.FILES['upload']
        clip = VideoFileClip(vid.temporary_file_path())
        obj.duration = clip.duration
        obj.save()
        return HttpResponseRedirect("/video/")
else:
    form = VideoForm()
context = {
    "form": form
}
return render(request, 'html/media/upload.html', context)
Run Code Online (Sandbox Code Playgroud)