如何在django中使用ffmpeg压缩base64解码视频数据
How to compress base64 decoded video data using ffmpeg in django
我想在我的 django-channels 项目中上传 video/audio 文件。所以我从 websocket 连接上传了视频(base64 编码 url)。它工作正常。但现在在解码 base64 视频数据后,我想使用 ffmpeg 压缩该视频。但它显示这样的错误。
''原始:没有这样的文件或目录''
我在 consumers.py file.Here 中使用了 '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_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()
它也导致 “E:..\Django\New_Projects\Personal: 没有那个文件或目录”。
我该如何解决这个问题?如果可以在将对象保存到数据库之前对其进行压缩,任何 suggetions.It 都会更有帮助。提前致谢。
经过一番努力,我已经解决了这里的问题。我不知道这是否是一个好的解决方案,但对我来说它已经奏效了。我在这里使用了 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"
我认为是因为'Personal Chat Room'里面的space。后来我尝试了
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:
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 现在引用第二个。所以,第一个可以稍后删除。
我想在我的 django-channels 项目中上传 video/audio 文件。所以我从 websocket 连接上传了视频(base64 编码 url)。它工作正常。但现在在解码 base64 视频数据后,我想使用 ffmpeg 压缩该视频。但它显示这样的错误。 ''原始:没有这样的文件或目录'' 我在 consumers.py file.Here 中使用了 '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_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()
它也导致 “E:..\Django\New_Projects\Personal: 没有那个文件或目录”。 我该如何解决这个问题?如果可以在将对象保存到数据库之前对其进行压缩,任何 suggetions.It 都会更有帮助。提前致谢。
经过一番努力,我已经解决了这里的问题。我不知道这是否是一个好的解决方案,但对我来说它已经奏效了。我在这里使用了 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"
我认为是因为'Personal Chat Room'里面的space。后来我尝试了
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:
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 现在引用第二个。所以,第一个可以稍后删除。