如何使用 Django 在 Amazon S3 中存储图像文件,在 Vimeo 中存储视频

How to store image files in Amazon S3 and Videos in Vimeo using Django

我想在我的 django 项目中将图像文件存储在 S3 中,将视频文件存储在 Vimeo 中。我是 Django-storageS3Boto3Storage 作为存储后端。由于 Vimeo 负责视频文件的压缩和内容交付,而且与 S3 相比它便宜,我想将它用于视频文件。

我想过使用django模型FileField中的upload_to属性将文件上传到Vimeo,但是我无法获取视频文件的绝对路径方法。

这里是我对upload_to方法的实现,

import vimeo


def vimeo_client():
    client = vimeo.VimeoClient(
        token=settings.VIMEO_ACCESS_TOKEN,
        key=settings.VIMEO_CLIENT_ID,
        secret=settings.VIMEO_CLIENT_SECRET
    )
    return client

def get_media_path(instance, filename):
    new_filename = '{}.{}'.format(uuid.uuid4(), filename.split('.')[-1])
    if instance.type == 'image':
        file_path = 'posts/media/images/{filename}'.format(
            filename=new_filename)
    else:
        client = vimeo_client()
        file_path = client.upload(
            filename,
            data={
                'name': instance.title,
                'description': instance.description
            }
        )
    logger.info("File uploaded to: [{}]".format(file_path))
    return file_path

但是它给我这个错误

OSError: [Errno 2] No such file or directory: 'videoplayback.mp4'

或者我可以根据自己的目的自定义 S3Boto3Storage。我想知道什么是更好的解决方案。

编辑 这是完整的堆栈跟踪

Traceback (most recent call last):
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/core/handlers/wsgi.py", line 157, in __call__
response = self.get_response(request)
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/core/handlers/base.py", line 124, in get_response
response = self._middleware_chain(request)
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/core/handlers/exception.py", line 43, in inner
response = response_for_exception(request, exc)
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/core/handlers/exception.py", line 93, in response_for_exception
response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info())
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/core/handlers/exception.py", line 139, in handle_uncaught_exception
return debug.technical_500_response(request, *exc_info)
File "/Users/rohanroy/development/django/zappa/appcore/src/appcore/wsgi.py", line 24, in null_technical_500_response
six.reraise(exc_type, exc_value, tb)
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/core/handlers/base.py", line 249, in _legacy_get_response
response = self._get_response(request)
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/contrib/admin/options.py", line 551, in wrapper
return self.admin_site.admin_view(view)(*args, **kwargs)
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/utils/decorators.py", line 149, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/views/decorators/cache.py", line 57, in _wrapped_view_func
response = view_func(request, *args, **kwargs)
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/contrib/admin/sites.py", line 224, in inner
return view(request, *args, **kwargs)
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/contrib/admin/options.py", line 1508, in add_view
return self.changeform_view(request, None, form_url, extra_context)
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/utils/decorators.py", line 67, in _wrapper
return bound_func(*args, **kwargs)
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/utils/decorators.py", line 149, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/utils/decorators.py", line 63, in bound_func
return func.__get__(self, type(self))(*args2, **kwargs2)
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/contrib/admin/options.py", line 1408, in changeform_view
return self._changeform_view(request, object_id, form_url, extra_context)
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/contrib/admin/options.py", line 1448, in _changeform_view
self.save_model(request, new_object, form, not add)
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/contrib/admin/options.py", line 979, in save_model
obj.save()
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/db/models/base.py", line 808, in save
force_update=force_update, update_fields=update_fields)
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/db/models/base.py", line 838, in save_base
updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/db/models/base.py", line 924, in _save_table
result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/db/models/base.py", line 963, in _do_insert
using=using, raw=raw)
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/db/models/query.py", line 1076, in _insert
return query.get_compiler(using=using).execute_sql(return_id)
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 1112, in execute_sql
for sql, params in self.as_sql():
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 1065, in as_sql
for obj in self.query.objs
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 1014, in pre_save_val
return field.pre_save(obj, add=True)
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/db/models/fields/files.py", line 296, in pre_save
file.save(file.name, file.file, save=False)
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/db/models/fields/files.py", line 93, in save
name = self.field.generate_filename(self.instance, name)
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/django/db/models/fields/files.py", line 327, in generate_filename
filename = self.upload_to(instance, filename)
File "/Users/rohanroy/development/django/zappa/appcore/src/utils/common.py", line 50, in get_media_path
'description': instance.description
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/vimeo/upload.py", line 49, in upload
filesize = self.__get_file_size(filename)
File "/Users/rohanroy/development/django/zappa/arete/lib/python2.7/site-packages/vimeo/upload.py", line 163, in __get_file_size
return os.path.getsize(filename)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/genericpath.py", line 57, in getsize
return os.stat(filename).st_size
OSError: [Errno 2] No such file or directory: 'videoplayback.mp4'

Vimeo API 支持讨论的 3 种视频上传策略 heretus 方法假设视频文件在本地系统中。要从浏览器上传视频,需要使用 form-based uploads 方法,这对仅 API 的服务器没有用。有两种选择可以解决这个问题,

  1. Upload the video from the client-side to the API server using your own API endpoint and then use vimeo.py to upload it to the Vimeo and delete the actual video file from the server.

  2. Use vimeo.js to upload the video file from the client side and then store the returned video_uri in the backend.