Python 如何在django中使用ffmpeg压缩base64解码视频数据

Python 如何在django中使用ffmpeg压缩base64解码视频数据,python,django,ffmpeg,django-channels,Python,Django,Ffmpeg,Django Channels,我想在我的django频道项目中上传视频/音频文件。所以我从websocket连接上传了视频(base64编码url)。它工作得很好。但现在在解码base64视频数据后,我想使用ffmpeg压缩该视频。但它显示了类似这样的错误。 ''Raw:没有这样的文件或目录 我在consumers.py文件中使用了“AsyncJsonWebsocketConsumer”。以下是我的代码: consumers.py: async def send_file_to_room(self, room_id, dat

我想在我的django频道项目中上传视频/音频文件。所以我从websocket连接上传了视频(base64编码url)。它工作得很好。但现在在解码base64视频数据后,我想使用ffmpeg压缩该视频。但它显示了类似这样的错误。 ''Raw:没有这样的文件或目录 我在consumers.py文件中使用了“AsyncJsonWebsocketConsumer”。以下是我的代码: consumers.py:

async def send_file_to_room(self, room_id, dataUrl, filename):
        # decoding base64 data
        format, datastr = dataUrl.split(';base64,')
        ext = format.split('/')[-1]
        file = ContentFile(base64.b64decode(datastr), name=filename)
        print(f'file: {file}')
        # It prints 'Raw content'
        output_file_name = filename + '_temp.' + ext
        ff = f'ffmpeg -i {file} -vf "scale=iw/5:ih/5" {output_file_name}'
        subprocess.run(ff,shell=True) 
可能是ffmpeg无法识别要压缩的文件。我还尝试使用post\u save信号解决这个问题

signals.py:

@receiver(post_save, sender=ChatRoomMessage)
def compress_video_or_audio(sender, instance, created, **kwargs):
    print("Inside signal")
    if created:
        if instance.id is None:
            print("Instance is not present")
        else:
            video_full_path = f'{instance.document.path}'
            print(video_full_path)
   // E:\..\..\..\Personal Chat Room\media\PersonalChatRoom\file\VID_20181219_134306_w5ow8F7.mp4
            output_file_name = filename + '_temp.' + extension
            ff = f'ffmpeg -i {filename} -vf "scale=iw/5:ih/5" {output_file_name}'
            subprocess.run(ff,shell=True)
            instance.document = output_file_name
            instance.save()
from django.db.models.signals import post_save, pre_save
from django.dispatch import receiver

import os
import subprocess

from chat.models import ChatRoomMessage

@receiver(post_save, sender=ChatRoomMessage)
def compress_video_or_audio(sender, instance, created, **kwargs):
    if created:
        if instance.id is None:
            print("Instance is not present")
        else:
            media_in = '.' + instance.document.url
            filename, extension = os.path.splitext(media_in)
            media_out = filename + '_temp' + extension
            output_file_name = media_out.split('./media/')[-1]
            subprocess.run('ffmpeg -i ' + media_in + ' -vf "scale=iw/4:ih/4" ' +  media_out, shell=True)
            instance.document = output_file_name
            instance.save()
           
它还导致“E:..\Django\New\u Projects\Personal:没有这样的文件或目录”
我如何解决这个问题?任何建议。如果可以在将对象保存到数据库之前对其进行压缩,则会更有帮助。事先谢谢。

经过一番努力,我已经在这里解决了这个问题。我不知道这是不是一个好的解决方案,但对我来说,它已经奏效了。我在这里使用了post_save信号。所以文件已经保存好了。我首先尝试instance.document.path将文件路径传递给ffmpeg。但是ffmpeg无法识别该文件

video_full_path = f'{instance.document.path}'
print(video_full_path)
# E:\..\..\..\Personal Chat Room\media\PersonalChatRoom\file\VID_20181219_134306_w5ow8F7.mp4
错误是:

"E:..\Django\New_Projects\Personal: No such file or directory"
我想这是因为“个人聊天室”里面的空间。后来我试了一下

media_in = instance.document.url
print(media_in)
# /media/PersonalChatRoom-2/file/VID_20181219_134306_jS7H8fL.mp4
ffmpeg仍然无法识别媒体中的文件。 对我来说,成功的诀窍是:

media_in = '.' + instance.document.url
print(media_in)
# ./media/PersonalChatRoom-2/file/VID_20181219_134306_jS7H8fL.mp4
filename, extension = os.path.splitext(media_in)
media_out = filename + '_temp' + extension
print(media_out)
# ./media/PersonalChatRoom-2/file/VID_20181219_134306_jS7H8fL_temp.mp4
subprocess.run('ffmpeg -i ' + media_in + ' -vf "scale=iw/4:ih/4" ' +  media_out,  shell=True)
现在,这一次ffmpeg识别了文件,并将输出保存在media/中。 我面临的下一个问题是

instance.document = media_out
instance.save()
print(instance.document.url)
# /media/media/PersonalChatRoom-1/file/VID_20181219_134306_jS7H8fL_temp.mp4
浏览器无法从该位置找到文件,因为在保存额外文件后 “/media/”已添加路径。 为了解决这个问题,

output_file_name = media_out.split('./media/')[-1]
print(output_file_name)
# PersonalChatRoom-1/file/VID_20181219_134306_jS7H8fL_temp.mp4
...
...
instance.document = output_file_name
instance.save()
这次它工作得很好

完整代码:signals.py:

@receiver(post_save, sender=ChatRoomMessage)
def compress_video_or_audio(sender, instance, created, **kwargs):
    print("Inside signal")
    if created:
        if instance.id is None:
            print("Instance is not present")
        else:
            video_full_path = f'{instance.document.path}'
            print(video_full_path)
   // E:\..\..\..\Personal Chat Room\media\PersonalChatRoom\file\VID_20181219_134306_w5ow8F7.mp4
            output_file_name = filename + '_temp.' + extension
            ff = f'ffmpeg -i {filename} -vf "scale=iw/5:ih/5" {output_file_name}'
            subprocess.run(ff,shell=True)
            instance.document = output_file_name
            instance.save()
from django.db.models.signals import post_save, pre_save
from django.dispatch import receiver

import os
import subprocess

from chat.models import ChatRoomMessage

@receiver(post_save, sender=ChatRoomMessage)
def compress_video_or_audio(sender, instance, created, **kwargs):
    if created:
        if instance.id is None:
            print("Instance is not present")
        else:
            media_in = '.' + instance.document.url
            filename, extension = os.path.splitext(media_in)
            media_out = filename + '_temp' + extension
            output_file_name = media_out.split('./media/')[-1]
            subprocess.run('ffmpeg -i ' + media_in + ' -vf "scale=iw/4:ih/4" ' +  media_out, shell=True)
            instance.document = output_file_name
            instance.save()
           

这里给出的答案是,在保存对象后压缩视频文件(在保存之前仍然不知道如何压缩)。因此,在媒体文件夹中为每个对象创建了两个视频文件。object.document.url现在正在引用第二个。因此,第一个可以稍后删除。

检查文件系统。文件是否位于那里?在post_保存信号的情况下,它存在,因为对象已保存就绪。您可以看到该文件吗?错误表示找不到该文件,因此检查该文件是否确实存在于您希望保存的文件系统中非常重要,因为该文件保存在该文件的确切位置。我手动检查过了。我认为问题在于找到文件的路径。这意味着它没有保存在数据库中存储的路径中。因此,这可能是一个如何在模型中指定路径的问题。发布您的模型代码