Создание эскизов видео, отправленных из frontend flask

#python #opencv #flask #video #ffmpeg

#python #opencv #flask #Видео #ffmpeg

Вопрос:

Я хочу сгенерировать миниатюру (скажем, извлечь кадр за 1 секунду) для видео, загруженных пользователем и отправленных обратно из интерфейса. user_upload = request.files['file'] Как правильно это сделать? Можно ли извлечь кадр без сохранения файла локально и сначала прочитать?

 subprocess.call(['ffmpeg', '-i', user_upload, '-ss',
                     '00:00:00.000', '-vframes', '1', output_dir])
  

или

      vidcap = cv2.VideoCapture(user_upload)
     success, image = vidcap.read()
     count = 0
     while success and count < 1:
         cv2.imwrite("frame%d.jpg" % count, image)     # save frame as JPEG file
         success, image = vidcap.read()
         print('Read a new frame: ', success)
         count  = 1
  

оба FFmpeg и cv2 требуют чтения в a Path , а не a FileStorage .

   File "/Users/glwang/bikan/yc2020/eb-flask/siyu/utils.py", line 8, in capture_thumnail
    '00:00:00.000', '-vframes', '1', output_dir])
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/subprocess.py", line 267, in call
    with Popen(*popenargs, **kwargs) as p:
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/subprocess.py", line 709, in __init__
    restore_signals, start_new_session)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/subprocess.py", line 1275, in _execute_child
    restore_signals, start_new_session, preexec_fn)
TypeError: expected str, bytes or os.PathLike object, not FileStorage
  

Кроме того, когда я попытался сначала сохранить файл локально и использовать FFmpeg для извлечения кадра,
user_upload.save('path/to/somewhere')
он показывает

 File "/siyu/utils.py", line 7, in capture_thumnail
    video_input.save(video_input.filename)
  File "/Users/lib/python3.6/site-packages/werkzeug/datastructures.py", line 3070, in save
    copyfileobj(self.stream, dst, buffer_size)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/shutil.py", line 79, in copyfileobj
    buf = fsrc.read(length)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/tempfile.py", line 738, in read
    return self._file.read(*args)
ValueError: read of closed file
  

Ответ №1:

Создание эскизов видео, отправленных из frontend flask

для этого вы не можете использовать у request.files.get('file') вас есть два способа сделать это

  1. Вы можете сохранить request.files.get('file') во временном файле, а затем использовать ссылку path для создания эскизов. вот пример

     video = request.files['video']
    video_bytes = video.read()
    
    with open("filename.mp4","wb") as f:
         f.write(video_bytes)
         f.close()
    
    #get thumbnail from video
    cmd = f'ffmpeg -i "filename.mp4" -ss 00:00:01.000 -vframes 1  -s 640x360  "thumbnail.png"'
    
    subprocess.check_output(cmd, shell=True)
    
    #for deleting the video file
    #os.remove("filename.mp4")
      
  2. Из URL-адреса URL-адреса видео

     cmd = f'ffmpeg -i "video file url" -ss 00:00:01.000 -vframes 1  -s 640x360  "thumbnail_file_name.png"'
    print(cmd)
    subprocess.check_output(cmd, shell=True)