使用签名 url 将大型视频上传到 GCS,但视频已损坏
Upload large video to GCS use signed url but video is broken
我有一个 Google App Engine(GAE) 的应用程序,在前端使用 Vue.js,在后端使用 Flask。
我的应用程序允许用户上传 large 视频并对其进行分析。但是由于GAE的上传大小限制是32MB,所以我允许用户使用signed url直接上传到Google Cloud Storage(GCS).
我遇到的问题是用户可以成功上传视频到GCS,但是在后台(flask)下载视频分析时,出现如下错误:
*** OSError: MoviePy error: failed to read the duration of file /tmp/source_video.mp4.
Here are the file infos returned by ffmpeg:
ffmpeg version 4.2.2-static https://johnvansickle.com/ffmpeg/ Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 8 (Debian 8.3.0-6)
configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gmp --enable-libgme --enable-gray --enable-libaom --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libdav1d --enable-libxvid --enable-libzvbi --enable-libzimg
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
libpostproc 55. 5.100 / 55. 5.100
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7444500] Format mov,mp4,m4a,3gp,3g2,mj2 detected only with low score of 1, misdetection possible!
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7444500] moov atom not found
/tmp/source_video.mp4: Invalid data found when processing input
Flask代码下载:
class Analyser:
def __init__(self):
self.gcs_bucket = 'bucket_name'
self.gcs_blob_video = 'videos/'
def __storage_bucket(self):
client = storage.Client()
bucket = client.get_bucket(self.gcs_bucket)
bucket.cors = [
{
"origin": ["*"],
"responseHeader": [
"Access-Control-Allow-Origin"
],
"method": ['PUT', 'POST', 'GET'],
"maxAgeSeconds": 3600
}
]
bucket.patch()
return bucket
def __generate_upload_signed_url(self, bucket, blob):
blob = bucket.blob(blob)
return blob.generate_signed_url(
version='v4',
expiration=datetime.timedelta(minutes=15),
method='PUT',
)
def analyze_video(self, pid):
src_filepath = '/tmp/source_video.mp4'
bucket = self.__storage_bucket()
blob = bucket.blob(self.gcs_blob_video + 'filename.mp4')
blob.download_to_filename(src_filepath)
#error is here
video = VideoFileClip(src_filepath)
Vuejs代码上传:
注意:上传成功,gcs上有文件要上传
async uploadVideo(_: any, video: File): Promise<string> {
signed_url = "https://storage.googleapis.com/bucket_name...." #signed url is return from flask
const formData = new FormData();
formData.append('file', video);
const response_upload_file = await fetch(
signed_url,
{
method: 'PUT',
body: formData
}
)
return true
}
我在 google 上搜索了很多,但仍然没有找到解决方案。
真不知道是上传的时候坏了还是下载分析的时候坏了。
如果有人可以建议我解决这个问题的解决方案,我将不胜感激。
感谢阅读。
您正在将 formData 与 HTTP PUT 方法一起使用,这会破坏上传,因为预期是二进制数据流,而不是 MIME 数据。
要使用表单数据:
我有一个 Google App Engine(GAE) 的应用程序,在前端使用 Vue.js,在后端使用 Flask。 我的应用程序允许用户上传 large 视频并对其进行分析。但是由于GAE的上传大小限制是32MB,所以我允许用户使用signed url直接上传到Google Cloud Storage(GCS).
我遇到的问题是用户可以成功上传视频到GCS,但是在后台(flask)下载视频分析时,出现如下错误:
*** OSError: MoviePy error: failed to read the duration of file /tmp/source_video.mp4.
Here are the file infos returned by ffmpeg:
ffmpeg version 4.2.2-static https://johnvansickle.com/ffmpeg/ Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 8 (Debian 8.3.0-6)
configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gmp --enable-libgme --enable-gray --enable-libaom --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libdav1d --enable-libxvid --enable-libzvbi --enable-libzimg
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
libpostproc 55. 5.100 / 55. 5.100
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7444500] Format mov,mp4,m4a,3gp,3g2,mj2 detected only with low score of 1, misdetection possible!
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7444500] moov atom not found
/tmp/source_video.mp4: Invalid data found when processing input
Flask代码下载:
class Analyser:
def __init__(self):
self.gcs_bucket = 'bucket_name'
self.gcs_blob_video = 'videos/'
def __storage_bucket(self):
client = storage.Client()
bucket = client.get_bucket(self.gcs_bucket)
bucket.cors = [
{
"origin": ["*"],
"responseHeader": [
"Access-Control-Allow-Origin"
],
"method": ['PUT', 'POST', 'GET'],
"maxAgeSeconds": 3600
}
]
bucket.patch()
return bucket
def __generate_upload_signed_url(self, bucket, blob):
blob = bucket.blob(blob)
return blob.generate_signed_url(
version='v4',
expiration=datetime.timedelta(minutes=15),
method='PUT',
)
def analyze_video(self, pid):
src_filepath = '/tmp/source_video.mp4'
bucket = self.__storage_bucket()
blob = bucket.blob(self.gcs_blob_video + 'filename.mp4')
blob.download_to_filename(src_filepath)
#error is here
video = VideoFileClip(src_filepath)
Vuejs代码上传:
注意:上传成功,gcs上有文件要上传
async uploadVideo(_: any, video: File): Promise<string> {
signed_url = "https://storage.googleapis.com/bucket_name...." #signed url is return from flask
const formData = new FormData();
formData.append('file', video);
const response_upload_file = await fetch(
signed_url,
{
method: 'PUT',
body: formData
}
)
return true
}
我在 google 上搜索了很多,但仍然没有找到解决方案。
真不知道是上传的时候坏了还是下载分析的时候坏了。 如果有人可以建议我解决这个问题的解决方案,我将不胜感激。
感谢阅读。
您正在将 formData 与 HTTP PUT 方法一起使用,这会破坏上传,因为预期是二进制数据流,而不是 MIME 数据。
要使用表单数据: