PDA

View Full Version : youtube upload



ernie
11th December 2010, 15:01
Hi guys.
I make a yotube appload application,using youtube api clientlogin.
First request performed good and server returned me auth key,but on second request(when i try to upload video),server return me bad request.



MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
but = new QPushButton("Upload");
layout()->addWidget(but);
connect(but,SIGNAL(clicked()),this,SLOT(staTimer() ));
}

MainWindow::~MainWindow()
{
delete ui;
}


void MainWindow::staTimer()
{
QNetworkRequest request;
request.setUrl(QUrl("https://www.google.com/youtube/accounts/ClientLogin"));
request.setHeader(QNetworkRequest::ContentTypeHead er,"application/x-www-form-urlencoded");
QByteArray reqString;
/////////Email=your email,passwd=your pass
reqString = "Email=_______&Passwd=_____&service=youtube&source=test";
_networkMen = new QNetworkAccessManager();
_networkMen->post(request,reqString);
connect(_networkMen, SIGNAL(finished(QNetworkReply*)), this, SLOT(handleNetworkReply(QNetworkReply*)));
}

void MainWindow::handleNetworkReply(QNetworkReply *reply)
{
reply->ignoreSslErrors();
if (reply->error())
{
qDebug()<<reply->errorString();
}
else
{
QByteArray otv = reply->readAll();
QList<QByteArray> lst(otv.split('\n'));
lst.removeLast();
QByteArray auth(lst.at(0).split('=').at(1));
qDebug()<<otv;
qDebug()<<auth;
QFile f("C:\\test.avi"); //video file
f.open(QIODevice::ReadOnly);
QByteArray fileBinaryData(f.readAll());
f.close();
QNetworkRequest request;
// forming request
request.setUrl(QUrl("http://uploads.gdata.youtube.com/feeds/api/users/default/uploads"));
request.setRawHeader("Authorization","GoogleLogin auth="+auth);
request.setRawHeader("GData-Version","2");
request.setRawHeader("X-GData-Key","key=AI39si53w0jmcZxorzxniPVD_rGBRZJhShx6Bh7uKy-JmAn--BAKzINwR3lNzvOtqnClFlCRiXsk-j8UMaE-EAO9U-7EsDJRxg");
request.setRawHeader("Slug","test.avi");
request.setRawHeader("Content-Type","multipart/related; boundary=\"f93dcbA3\"");
request.setRawHeader("Content-Length",QString::number(fileBinaryData.length()).toStdStr ing().c_str());
request.setRawHeader("Connection","close");
QByteArray reqString;
reqString.append("--f93dcbA3\r\n");
reqString.append("Content-Type: application/atom+xml; charset=UTF-8\r\n");
reqString.append("\r\n");
reqString.append("<?xml version=\"1.0\"?>\r\n");
reqString.append("<entry xmlns=\"http://www.w3.org/2005/Atom\"\r\n");
reqString.append("xmlns:media=\"http://search.yahoo.com/mrss/\"\r\n");
reqString.append("xmlns:yt=\"http://gdata.youtube.com/schemas/2007\">\r\n");
reqString.append("<media:group>\r\n");
reqString.append("<media:title type=\"plain\">Test test</media:title>\r\n");
reqString.append("<media:description type=\"plain\">\r\n");
reqString.append("Batafa\r\n");
reqString.append("</media:description>\r\n");
reqString.append("<media:category\r\n");
reqString.append("scheme=\"http://gdata.youtube.com/schemas/2007/categories.cat\">People\r\n");
reqString.append("</media:category>\r\n");
reqString.append("<media:keywords>ara,arara</media:keywords>\r\n");
reqString.append("</media:group>\r\n");
reqString.append("</entry>\r\n");
reqString.append("--f93dcbA3\r\n");
reqString.append("Content-Type: video/*\r\n");
reqString.append("Content-Transfer-Encoding: binary\r\n");
reqString.append("\r\n");
reqString.append(fileBinaryData);
reqString.append("\r\n");
reqString.append("--f93dcbA3");
netmen2 = new QNetworkAccessManager();
netmen2->post(request,reqString);
connect(netmen2, SIGNAL(finished(QNetworkReply*)), this, SLOT(handleUploadReply(QNetworkReply*)));
}
}

void MainWindow::handleUploadReply(QNetworkReply *reply)
{
reply->ignoreSslErrors();
if(reply->error())
{
qDebug()<<reply->errorString();
} else
{
qDebug()<<reply->readAll();
}
}


what i do wrong?thanks

squidge
11th December 2010, 16:27
Why do you create request by simple string concatenation rather than use proper MIME library?

Is your unique developer key correct ? and did you encode it into the data correctly ? [I wouldn't include this in your posts BTW even though it is likely to be stored in your application and transmitted in plain text]

Try using something like Wireshark to determine exactly what you are sending, and compare it with a program known to work.

Or you could just use the Youtube client API library, which handles all this for you.

ernie
11th December 2010, 18:42
squidge,thanks for reply,i use wireshark and determinate my post request and post request from youtube api sample,it's same.
how can i use the proper MIME library?i don't know about it in Qt,sorry:)
developer key correct,i copied it from http://code.google.com/apis/youtube/dashboard for my app(don't worry,it's test app and key not secret:) )
how encode data correct?i try to convert bynary data to base64 (fileBinaryData.toBase64()),but it's not given result.
youtube give libraries for java,c# ,not for c++ unfortunately :(

squidge
11th December 2010, 19:50
So your sending exactly the same data as the api sample, but the sample works and yours does not? That is most odd, but at least it proves that the encoding and mime headers are already correct, so there's really no point changing something that works.

ernie
11th December 2010, 20:08
yes,header(i sure) and body(i think) of request is same as api sample,but i thinks it's must be because i encode file binary data wrong?i try to delete video with my auth data and video is deleted,i think headers is true,may body of post request is wrong?i can't try the sample to work(request in sample and in my programm is identical),may it dapend on country where are i from?some says,that upload api work worst in China and another countries, i'm from Russia and i can upload video with youtube web interface without problem,what application you can advise for me to try upload video to youtube besides Free Youtube Uploader(it cant's run in my computer,.net framework fault)?thanks,squidge

squidge
11th December 2010, 20:25
I would try sending "Content-Type: video/mp4" rather than "Content-Type: video/*", as you are sending, not receiving.

ernie
11th December 2010, 20:29
squidge, i try to send video/mpeg ,video/mp4 ,not result :)anybody can upload video to youtube from qt app?:)

squidge
11th December 2010, 21:34
Ah, you didn't say that in your original post.

Looking at your code, your "Content-length" field looks incorrect too. That is supposed to be the length of the entire post body, where as you have it only being the length of the binary data part.

ernie
12th December 2010, 05:07
I try set content lenght after request body filling (request.setRawHeader("Content-lenght",QString::number(reqString.length()).toStdString() .c_str()))),not result

squidge
12th December 2010, 11:42
Then you'll need to fix your .net fault and compare the two wireshark traces, I'm out of ideas.

ernie
12th December 2010, 12:41
squidge,i fix it,but free youtube uploader doesn't work too;)now i'm downloading directx sdk,there is an youtube upload example in it

wysota
12th December 2010, 18:32
I'm pretty sure that YouTube API will be setting some cookies while sending replies to you so you need to attach a cookie jar to your QNAM to make sure you send those cookies back with queries that follow. Also try to rely on Qt where possible - don't set content-length yourself at all, QNAM will do this for you. Furthermore don't assemble the xml yourself, use QDomDocument or any other available Qt xml writer so that you don't make any mistakes when creating the request. Next, make sure you don't add any incorrect data to the binary stream - I'm not sure your binary data should be surrounded by \r\n, check that this is really how it should be. Also try changing the binary encoding to base64, it will be easier for you to debug although the volume will double.

ernie
13th December 2010, 10:34
i fix the bad request,new request code:


request.setUrl(QUrl("http://uploads.gdata.youtube.com/feeds/api/users/default/uploads"));
request.setRawHeader("Host","uploads.gdata.youtube.com");
request.setRawHeader("Authorization","GoogleLogin auth="+auth);
request.setRawHeader("GData-Version","2");
request.setRawHeader("X-GData-Key","key=AI39si53w0jmcZxorzxniPVD_rGBRZJhShx6Bh7uKy-JmAn--BAKzINwR3lNzvOtqnClFlCRiXsk-j8UMaE-EAO9U-7EsDJRxg");
request.setRawHeader("Slug","C:\\qwerty.avi");
request.setRawHeader("Content-Type","multipart/related; boundary=\"f93dcbA3\"");
request.setRawHeader("Connection","close");
QByteArray reqString;
reqString.append("--f93dcbA3\r\n");
reqString.append("Content-Type: application/atom+xml; charset=UTF-8\r\n");
reqString.append("\r\n");
reqString.append("<?xml version=\"1.0\"?>\r\n");
reqString.append("<entry xmlns=\"http://www.w3.org/2005/Atom\"\r\n");
reqString.append("xmlns:media=\"http://search.yahoo.com/mrss/\"\r\n");
reqString.append("xmlns:yt=\"http://gdata.youtube.com/schemas/2007\">\r\n");
reqString.append("<media:group>\r\n");
reqString.append("<media:title type=\"plain\">Test test</media:title>\r\n");
reqString.append("<media:description type=\"plain\">\r\n");
reqString.append("Batafa\r\n");
reqString.append("</media:description>\r\n");
reqString.append("<media:category ");
reqString.append("scheme=\"http://gdata.youtube.com/schemas/2007/categories.cat\">People\r\n");
reqString.append("</media:category>\r\n");
reqString.append("<media:keywords>ara,arara</media:keywords>\r\n");
reqString.append("</media:group>\r\n");
reqString.append("</entry>\r\n");
reqString.append("--f93dcbA3\r\n");
reqString.append("Content-Type: video/*\r\n");
reqString.append("Content-Transfer-Encoding: binary\r\n");
reqString.append("\r\n");
reqString.append(fileBinaryData.toBase64());
reqString.append("\r\n");
reqString.append("--f93dcbA3\r\n");
request.setRawHeader("Content-Length",QString::number(reqString.length()).toUtf8());


now video upload to server,but youtube say that can't convert video

ernie
13th December 2010, 16:21
i finished,work fine.Thanks squidge and wysota for replies.
Work sourcecode for second request:


QFile f("C:\\video.avi"); //video file
f.open(QIODevice::ReadOnly);
QByteArray fileBinaryData = f.readAll();
f.close();
QNetworkRequest request;
request.setUrl(QUrl("http://uploads.gdata.youtube.com/feeds/api/users/default/uploads"));
request.setRawHeader("Host","uploads.gdata.youtube.com");
request.setRawHeader("Authorization","GoogleLogin auth="+auth);
request.setRawHeader("GData-Version","2");
request.setRawHeader("X-GData-Key","key=devkey");
request.setRawHeader("Slug","C:\\video.avi");
request.setRawHeader("Content-Type","multipart/related; boundary=\"f93dcbA3\"");
request.setRawHeader("Connection","close");
QByteArray reqString;
reqString.append("--f93dcbA3\r\n");
reqString.append("Content-Type: application/atom+xml; charset=UTF-8\r\n");
reqString.append("\r\n");
reqString.append("<?xml version=\"1.0\"?>\r\n");
reqString.append("<entry xmlns=\"http://www.w3.org/2005/Atom\"\r\n");
reqString.append("xmlns:media=\"http://search.yahoo.com/mrss/\"\r\n");
reqString.append("xmlns:yt=\"http://gdata.youtube.com/schemas/2007\">\r\n");
reqString.append("<media:group>\r\n");
reqString.append("<media:title type=\"plain\">Test</media:title>\r\n");
reqString.append("<media:description type=\"plain\">\r\n");
reqString.append("Batafa\r\n");
reqString.append("</media:description>\r\n");
reqString.append("<media:category ");
reqString.append("scheme=\"http://gdata.youtube.com/schemas/2007/categories.cat\">People\r\n");
reqString.append("</media:category>\r\n");
reqString.append("<media:keywords>ara,arara</media:keywords>\r\n");
reqString.append("</media:group>\r\n");
reqString.append("</entry>\r\n");
reqString.append("--f93dcbA3\r\n");
reqString.append("Content-Type: video/mpeg\r\n");
reqString.append("Content-Transfer-Encoding: binary\r\n");
reqString.append("\r\n");
reqString.append(fileBinaryData);
reqString.append("\r\n");
reqString.append("--f93dcbA3\r\n");
request.setRawHeader("Content-Length",QString::number(reqString.length()).toUtf8());
netmen2 = new QNetworkAccessManager();
QNetworkReply *rep=netmen2->post(request,reqString);
connect(netmen2, SIGNAL(finished(QNetworkReply*)), this, SLOT(handleUploadReply(QNetworkReply*)));

sureshmenlo
2nd September 2015, 14:48
Hi everyone,

I am new to QT & c++, i do have a requirement for uploading videos on youtube using API. I have tried to implement the logic, but it always gives me build errors.
I kindly request to help me with the working .zip file or the instructions which help me to upload a video file to youtube using QT.

Thanks in advance,
Suresh.

anda_skoa
2nd September 2015, 15:29
You have not provided any error message nor your non-working ZIP.

Cheers,
_