获取“畸形的多部分体"尝试将视频上传到 YouTube 时 [英] Getting "Malformed multipart body" when trying to upload video to YouTube

查看:26
本文介绍了获取“畸形的多部分体"尝试将视频上传到 YouTube 时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序可以代表我们的客户将视频上传到 YouTube.我们每天管理数千个频道并上传数千个视频.这已经工作多年了.代码是用 C#、.Net 4.7 编写的(它实际上使用的是一个稍旧的版本,但我不得不更新它以重新编译和测试).它使用 REST API(而不是 SDK).

I have an application that uploads videos to YouTube on behalf of our customers. We manage thousands of channels and upload thousands of videos a day. This has been working for years. The code is written in C#, .Net 4.7 (it was actually using a slightly older version, but I had to update it in order to recompile and test). It uses the REST API (not the SDK).

出于某种原因,代码在 2018 年 10 月 12 日星期五晚上被破坏.我们所有上传请求都返回 400 状态和格式错误的多部分正文".作为身体.

For some reason, the code broke the evening of Friday, Oct 12th, 2018. All of our requests to upload return with a 400 status and "Malformed multipart body." as the body.

我们至少有 6 个月没有更改代码(尽管可能超过一年).我能够在我的开发机器上重现该错误.我查看了 Fiddler 中的原始 http 请求,我没有发现它有什么问题,尽管我很难找到普通的 REST 文档来确认内容处置标头.我知道 JSON 和视频很好(我验证了 JSON 并确认我能够将视频直接上传到 YouTube).此外,我们所做的所有其他 API 调用都可以正常工作.只是上传有问题.

We have not changed the code in at least 6 months (though likely over a year). I am able to reproduce the error on my dev machine. I looked at the raw http request in Fiddler and I don't see anything wrong with it, though I'm having difficulty finding the plain REST documentation to confirm the content-disposition headers. I know the JSON and video are fine (I validated the JSON and verified I'm able to upload the video directly to YouTube). Also, all of the other API calls we make work just fine. It's just uploading that is a problem.

这是来自 Fiddler 的 HTTP 请求的副本...

Here's a copy of the HTTP request from Fiddler...

POST https://www.googleapis.com/upload/youtube/v3/videos?part=snippet,status HTTP/1.1
Authorization: Bearer <token>
Content-Type: multipart/form-data; boundary="590ce98e-6411-4e49-8dde-d7aa06cb067d"
Host: www.googleapis.com
Content-Length: 8305362
Expect: 100-continue

--590ce98e-6411-4e49-8dde-d7aa06cb067d
Content-Type: application/json; charset=utf-8
Content-Disposition: form-data; name=json; filename=file.json; filename*=utf-8''file.json

{"snippet":{"title":"77 Wakefield Street, Bald Hills, QLD, 4036","description":"77 Wakefield Street\r\n\r\nContact Brian Brewder for more information.\nTourFactory Corporate Headquarters\n123-456-7890\n\r\n","categoryId":19,"tags":["Tag1","Tag2"]},"status":{"privacyStatus":"public","embeddable":true}}
--590ce98e-6411-4e49-8dde-d7aa06cb067d
Content-Disposition: form-data; name="files"; filename="video"
Content-Type: video/x-msvideo

<video>

API 的 YouTube 方面似乎发生了一些变化,但我查看了博客并没有看到任何列出的内容.由于 Google 使用 StackOverflow 来提供支持,我希望有人能帮我找出问题所在.

It seems like something must have changed on the YouTube side of the API, but I checked the blog and don't see anything listed. Since Google uses StackOverflow for support, I'm hoping somebody can help me identify the problem.

推荐答案

所以,显然是什么导致了这个问题(并且仍然存在)是现在

So, apparently what caused the issue (And still does) is that now the

Content-Type: multipart/mixed;

不再被接受.我设法通过更改一些内容来获得错误消息,并说只发送 video/*application/octet-stream.不幸的是,虽然我通过这样做仍然可以从服务器上获得成功,但导致 youtube 视频损坏

is no longer accepted. I managed to get an error message by changing some stuff around, and said to only send video/* or application/octet-stream. Unfortunately, while i still got OK from the server by doing so, resulted in a broken youtube video

此时我尝试使用标题,但没有成功.该文件将被 YouTube 接受,但不会正确显示.我怀疑他们更改了 - 或删除了 - 不可恢复的上传 API.如果他们这样做了,我就找不到相关公告.

At this point i tried playing with headers but with no success. The file would be accepted by YouTube but wouldn't be displayed correctly. I suspect they changed - or dropped - the non-resumable uploads API. If they did, i can't find an announcement on that.

所以,我的解决方案"——好吧,一种变通方法——是使用可恢复上传协议重新实现我的上传功能.

So, my "solution" - well, a workaround - was to reimplement my upload function using the Resumable Upload protocol.

https://developers.google.com/youtube/v3/guides/using_resumable_upload_protocol

这行得通,并没有花太长时间.只需确保为 BOTH 请求设置 X-Upload-Content-Length 和 x-upload-content-type(元数据优先,获取上传放置 URL 后的负载).

This works and didn't take too long. Just make sure to set both X-Upload-Content-Length and x-upload-content-type for BOTH requests (metadata first and payload after getting the upload put URL).

所以你首先 POST 相同的元数据(代码段和状态)并获取 PUT url

So you first POST the same metadata (snippet and status) and get the PUT url

QByteArray responseLocation = reply->rawHeader( "Location" );

然后使用相同的 X-Upload-Content-Length 和 x-upload-content-type 创建 PUT 请求

and then create the PUT request using the same X-Upload-Content-Length and x-upload-content-type

newrequest.setRawHeader( "X-Upload-Content-Length", QByteArray::number( video->size() ) );
newrequest.setRawHeader( "x-upload-content-type", "video/*" );

这对我有用 - 我希望这会有所帮助!

That worked for me - I hope this helps!

这篇关于获取“畸形的多部分体"尝试将视频上传到 YouTube 时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆