我正在尝试将 .gif 上传到我的 django 3.2 api。我已经通过 Postman 进行了故障排除,并得出结论,我的 flutter 应用程序将其作为 .gif 发送,并以 .jpg 返回。问题出在后端。这是我的相关代码,用于检查 file_meme 子类型,然后该函数应将传入的 .gif 转换为视频:
def add_media(self, file, order=None):
check_can_add_media(post=self)
is_in_memory_file = isinstance(file, InMemoryUploadedFile) or isinstance(file, SimpleUploadedFile)
if is_in_memory_file:
file_mime = magic.from_buffer(file.read())
elif isinstance(file, TemporaryUploadedFile):
file_mime = magic.from_file(file.temporary_file_path())
else:
file_mime = magic.from_file(file.name)
check_mimetype_is_supported_media_mimetypes(file_mime)
# Mime check moved pointer
file.seek(0)
file_mime_types = file_mime.split('/')
file_mime_type = file_mime_types[0]
file_mime_subtype = file_mime_types[1]
temp_files_to_close = []
if file_mime_subtype == 'gif':
if is_in_memory_file:
file = write_in_memory_file_to_disk(file)
temp_dir = tempfile.gettempdir()
converted_gif_file_name = os.path.join(temp_dir, str(uuid.uuid4()) + '.mp4')
ff = ffmpy.FFmpeg(
inputs={file.temporary_file_path() if hasattr(file, 'temporary_file_path') else file.name: None},
outputs={converted_gif_file_name: None})
ff.run()
converted_gif_file = open(converted_gif_file_name, 'rb')
temp_files_to_close.append(converted_gif_file)
file = File(file=converted_gif_file)
file_mime_type = 'video'
has_other_media = self.media.exists()
if file_mime_type == 'image':
post_image = self._add_media_image(image=file, order=order)
if not has_other_media:
self.media_width = post_image.width
self.media_height = post_image.height
self.media_thumbnail = file
elif file_mime_type == 'video':
post_video = self._add_media_video(video=file, order=order)
if not has_other_media:
self.media_width = post_video.width
self.media_height = post_video.height
self.media_thumbnail = post_video.thumbnail.file
else:
raise ValidationError(
_('Unsupported media file type')
)
for file_to_close in temp_files_to_close:
file_to_close.close()
self.save()
我不确定问题出在哪里。根据我有限的理解,它只获取 .gif 的第一帧并将其作为图像上传。
如果在将 GIF 转换为 MP4 后代码未正确地将
file_mime_type
更新为“video
”,则可能会调用 _add_media_image
方法而不是 _add_media_video
。这将导致仅存储第一帧,因为它会将其视为图像。
elif file_mime_type == 'video':
post_video = self._add_media_video(video=file, order=order)
确保 GIF 转换后
file_mime_type
正确更新为“视频”,以便触发 _add_media_video
方法。
if file_mime_subtype == 'gif':
# conversion logic ...
file_mime_type = 'video'
换句话说,检查调试会话是否执行了
file_mime_type = 'video'
。
也有可能未正确执行从 GIF 到 MP4 的转换。您可能想要检查临时 MP4 文件以查看它是否包含所有帧或仅包含第一个帧。
ff.run()
converted_gif_file = open(converted_gif_file_name, 'rb')
如果 MIME 类型未正确更新,程序会将 MP4 视为图像,这可能会导致它只获取第一帧并将其另存为 JPEG。在发生这些操作的点进行调试可以提供对问题的更多见解。