How to upload video to Youtube with QNetworkAuth

2019-07-27 01:52发布

问题:

Using QOAuth2AuthorizationCodeFlow to authorize with google's oauth2. The authorization is successful as well as using GET request (for example, obtaining list of videos from youtube channel). But while QNetworkAccessManager provides user with a bunch of post method overloads:

QNetworkReply * post(const QNetworkRequest &request, QIODevice *data)
QNetworkReply * post(const QNetworkRequest &request, const QByteArray &data)
QNetworkReply * post(const QNetworkRequest &request, QHttpMultiPart *multiPart)

QOAuth2AuthorizationCodeFlow has only:

QNetworkReply *post(const QUrl &url, const QVariantMap &parameters = QVariantMap());

It's easy to append a file using QHttpMultiPart & QHttpPart::setBodyDevice(). But I'm not sure how to use QVariantMap for video/file uploading.

Also, tried to use: QOAuth2AuthorizationCodeFlow::networkAccessManager() to get access to underlying network manager, but it gives 202 response code with GET. And, if using with authenticated url, QOAuth2AuthorizationCodeFlow::createAuthenticatedUrl(), the response code is 200, but reply content is empty (readAll() returns empty buffer). Doesn't work with POST as well.

Using QT 2nd day, so I may misunderstand some concepts. Thanks for any help & ideas.

回答1:

Was able to work around it. But still, maybe there is the right solution to it.

QOAuth2AuthorizationCodeFlow youtube{};
...
// authorization
...
auto multi_part = new QHttpMultiPart{ QHttpMultiPart::MixedType };
auto video_part = new QHttpPart{};
auto video = new QFile{ video_path };

if (!video->open(QIODevice::ReadOnly)) { return nullptr; }

video_part->setHeader(QNetworkRequest::ContentTypeHeader, QVariant("video/*"));
video_part->setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("Slug"));
video_part->setBodyDevice(video);
multi_part->append(*video_part);

QNetworkRequest req{youtube_videos_insert};
const QString bearer_format = QStringLiteral("Bearer %1");
const QString bearer = bearer_format.arg(youtube.token());
req.setRawHeader("Authorization", bearer.toUtf8());

youtube.networkAccessManager()->post(req, multi_part);