Django ImageFiled миниатюра из видеоролика

Мне нужно сделать миниатюру из видео и сохранить ее в Django ImageField.

У меня уже есть рабочий код, который сохраняет миниатюру в указанную папку, но я хочу перенаправить вывод FFmpeg непосредственно в Imagefield (или в загруженный в память файл, а затем в Imagefield)

Вот мой текущий код:

def clean(self):
    file = self.files['file']
    output_thumb = os.path.join(settings.MEDIA_ROOT, 'post/videos/thumbs', file.name)
    video_input_path = file.temporary_file_path()
    subprocess.call(
        ['ffmpeg', '-i', video_input_path, '-ss', '00:00:01', '-vf', 'scale=200:220', 
        '-vframes', '1', output_thumb])
    self.instance.video = self.files['file']
    self.instance.video_thumb = output_thumb

Я бы хотел сделать так, чтобы мне не нужно было указывать папку, в которую сохранять палец (output_thumb в коде), а чтобы Django сохранял его автоматически, используя опцию upload_to='post/videos/thumbs в определении модели

Пожалуйста, направьте меня в правильном направлении, как это сделать.

Посмотрев на свой самоответ, вы можете немного уплотнить свой код:

file.seek(0)
args = ['ffmpeg', '-i', 'pipe:0', '-ss', '00:00:01', '-vf', 'scale=200:220',
        '-vframes', '1', '-f', 'image2pipe', '-c', 'mjpeg', 'pipe:1']
content = subprocess.run(args, input=file, stdout=subprocess.PIPE)
self.instance.video = self.files['file']
self.instance.video_thumb = ContentFile(content=output_stream[0], name=filename)

[оригинальный ответ ниже]

Вот частичный ответ. Чтобы получить вывод ffmpeg в виде bytes, укажите формат изображения и кодек и передайте его в stdout:

bytes = subprocess.run(
        ['ffmpeg', '-i', video_input_path, '-ss', '00:00:01', '-vf', 'scale=200:220', 
        '-vframes', '1', -f image2pipe -c mjpeg -],stdout=subprocess.PIPE)

Я не знаю Django, чтобы прокомментировать, что делать с этими данными дальше

Кажется, мне удалось заставить его работать. Не уверен, что это правильный способ сделать это, но похоже, что это работает. Буду благодарен, если кто-нибудь добавит что-нибудь по этому поводу.

file.seek(0)
args = ['ffmpeg', '-i', 'pipe:0', '-ss', '00:00:01', '-vf', 'scale=200:220',
        '-vframes', '1', '-f', 'image2pipe', '-c', 'mjpeg', 'pipe:1']
ffmpeg_process = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
output_stream = ffmpeg_process.communicate(file.read())
self.instance.video = self.files['file']
self.instance.video_thumb = ContentFile(content=output_stream[0], name=filename)
Вернуться на верх