python-3.x - 使用 ffmpeg 和 celery 编码后,编码视频的路径在数据库中发生更改,并且在没有 celery 的情况下正常工作

标签 python-3.x django django-models ffmpeg django-rest-framework

我有这段代码可以对视频进行转码,它在没有 celery 的情况下也能正常工作。使用 celery,文件在数据库中的路径显示不同的路径,无法在浏览器中播放视频,但它会将文件保存在 pc 中的正确位置。

如果我不使用celery,那么数据库中的文件路径是media/videos/videos/<filename>.mp4并且文件也保存在这里。这样模板就可以播放视频了。但如果我使用 celery ,输出将保存在 media/videos/videos/<filename>.mp4 中但数据库中的路径将是 media/<filename>.mp4不知何故,因此模板无法播放视频。

是因为我的页面在任务之前更新了吗?没有得到正确保存?

View .py

def post(self, *args, **kwargs):
    form = VideoPostForm(self.request.POST or None, self.request.FILES or None)
    if form.is_valid():
        video = form.save(commit=False)
        video.user = self.request.user
        video.save()
        form.save_m2m()
        # task_video_encoding(video.id)
        task_video_encoding.delay(video.id)
        return redirect('videos:my_video_home')
    else:
        raise ValidationError('Check all form fields.')

编码.py

def encode_video(video_id):
    video = VideoPost.objects.get(id = video_id)
    input_file_path = video.temp_file.path
    # print(input_file_path)
    input_file_name = video.title
    #get the filename (without extension)
    filename = os.path.basename(input_file_path)
    # print(filename)
    # path to the new file, change it according to where you want to put it
    output_file_name = os.path.join('{}.mp4'.format(filename))
    # print(output_file_name)
    # output_file_path = os.path.join(settings.MEDIA_ROOT, output_file_name)
    output_file_path = os.path.join(settings.MEDIA_ROOT, 'videos', 'videos', output_file_name)
    # print(output_file_path)

    for i in range(1):
        subprocess.call([settings.VIDEO_ENCODING_FFMPEG_PATH, '-i', input_file_path, '-codec:v', 'libx264', '-crf', '-preset',
                    '-b:v', '3000k', '-maxrate', '-bufsize', '6000k', '-vf', 'scale=-2:720',
                    '-codec:a', 'aac', '128k', '-strict', '-2', output_file_path])
    # Save the new file in the database
    video.file = output_file_name
    video.save(update_fields=['file'])
    print(video.file)
    video.temp_file.delete()

模型

class VideoPost(models.Model):
    user                = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, blank=True, null=True)
    title               = models.TextField(max_length=1000)
    temp_file           = models.FileField(upload_to='videos/temp_videos/', validators=[validate_file_extension], null=True)
    file                = models.FileField(upload_to='videos/videos/', validators=[validate_file_extension], blank=True, max_length=255)
    post_date           = models.DateTimeField(auto_now_add=True, verbose_name="Date Posted")
    updated             = models.DateTimeField(auto_now_add=True, verbose_name="Date Updated")
    slug                = models.SlugField(blank=True, unique=True, max_length=255)

任何人都可以帮助我如何更改此代码以在模板中正确显示转换后的视频。

最佳答案

您可以使用 print(video.file) 进行调试查看输出是否为 <filename>.mp4videos/videos/<filename>.mp4 .我怀疑它只会打印出文件名而不是 url 路径,而这正是您所需要的。

一些建议:

  1. 在你的template : 更改 {{ video.file }}{{ video.file.url }} .看看它打印出什么。

  2. 您当前的 output_file_path = os.path.join(settings.MEDIA_ROOT, output_file_name)将类似于 media/<filename>.mp4 .您注释掉的那个将给出输出 media/videos/videos/<filename>.mp4 .我不确定你的 subprocess功能与output_file_path有关,但您可以查看它是否存在任何问题。

关于python-3.x - 使用 ffmpeg 和 celery 编码后,编码视频的路径在数据库中发生更改,并且在没有 celery 的情况下正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63751696/

相关文章:

python-3.x - 属性错误 : module 'tensorflow' has no attribute 'Graph'

python - Django过滤器manytomanyfield排除与另一个模型相关的对象

django - AbstractUser Django 完整示例

python-3.x - UPSERT 语法错误链接到 PostgreSQL 中的更新(python)

python-3.x - 如何将 Pandas 数据帧写入 HDF5 数据集

python - 使用 QDataWidgetMapper 立即更改模型

python - 关闭 Django 中的空白修剪

django - 在汇总中使用模型方法

python - Django--表单验证(为什么我不能手动清理一个Integer Form Field)

django - 在 Django 2.0 中按字段值排序