Programmatically Uploading Videos to YouTube
March 21st, 2008 Posted in Software Development
YouTube recently updated their API with some new features. YouTube is now using the GoogleData API instead of a proprietary API. One of the new features is the ability to upload videos via the API. This means that web sites and client applications now have the ability to upload videos directly to YouTube.
I’ve been playing around with the YouTube API upload feature and have a quick and dirty little C# class library that can upload videos straight to YouTube via the API.
Before you can upload a video you have to get an authorization code using your YouTube username and password. The code is then used in the call that actually uploads the video.
The Authorize method of the YouTube library performs the authentication.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | public bool Authorize(string username, string password) { bool result = false; this.username = username; this.password = password; using (WebClient client = new WebClient()) { // Send the requeset with username and password client.Headers.Add("Content-Type", "application/x-www-form-urlencoded"); string response = client.UploadString( "https://www.google.com/youtube/accounts/ClientLogin", string.Format("Email={0}&Passwd={1}&service=youtube&source=TrailsintheSand.YouTube.Library", username, password)); // The response is plain text containing: // Auth=<authorization code> string[] split = response.Split('\n'); foreach (string s in split) { string[] nvsplit = s.Split('='); if (nvsplit.Length == 2) { if (nvsplit[0] == "Auth") { authCode = nvsplit[1]; result = true; } } } } return result; } |
This simple method uses the WebClient class. WebClient is the simplest way to perform an HTTP request in .NET. The UploadString method of the WebClient class is used because we need to POST the username and password to the server. The response that comes back contains the string “Auth=
The Upload method is passed several parameters including the title of the video, a description of the video, the video’s category, a list of keywords and the path to the video on the local hard drive.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | public bool Upload(string title, string description, Catagory catagory, string keywords, string videoFileName, out string error) { bool result = false; error = null; // Build byte arrays for the header file and footer byte[] header = Encoding.UTF8.GetBytes(GetHeader(title, description, catagory, keywords, videoFileName)); byte[] file = File.ReadAllBytes(videoFileName); byte[] footer = Encoding.UTF8.GetBytes(lineTerm + boundary + "--"); // Combine the byte arrays into one big byte array byte[] data = new byte[header.Length + file.Length + footer.Length]; Array.Copy(header, 0, data, 0, header.Length); Array.Copy(file, 0, data, header.Length, file.Length); Array.Copy(footer, 0, data, header.Length + file.Length, footer.Length); // Using a HttpWebRequest here because it allows us to control the timeout HttpWebRequest req = (HttpWebRequest)WebRequest .Create(string.Format("http://uploads.gdata.youtube.com/feeds/api/users/{0}/uploads", username)); req.Method = "POST"; req.ContentType = string.Format("multipart/related; boundary={0};", boundaryheader); req.ContentLength = data.Length; req.Timeout = timeout; req.Headers.Add("Authorization", "GoogleLogin auth=" + authCode); req.Headers.Add("X-GData-Client", clientCode); // supposed to be optional req.Headers.Add("X-GData-Key", devCode); req.Headers.Add("Slug", Path.GetFileName(videoFileName)); using (Stream postStream = req.GetRequestStream()) { // Send the data to the server postStream.WriteTimeout = timeout; postStream.Write(data, 0, data.Length); postStream.Close(); try { // Get the response back from the server WebResponse webResponse = req.GetResponse(); using (Stream responseStream = webResponse.GetResponseStream()) { using (StreamReader reader = new StreamReader(responseStream)) { // Should check the response here reader.Close(); result = true; } responseStream.Close(); } webResponse.Close(); } catch (WebException ex) { // Got a bad response using (StreamReader sr = new StreamReader(ex.Response.GetResponseStream())) { error = sr.ReadToEnd(); } } } return result; } |
Upload builds the content of the HTTP POST. The content is of type multipart/related meaning there will be more than one part and the parts are related. In the case of a YouTube video upload there are two parts. The first part contains an XML document describing the video. It contains the title, description, category, keywords and file name. The Upload method calls the GetHeader method to get a string that contains both the HTTP headers for the parts of the content and the XML data for the video.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | private string GetHeader(string title, string description, Catagory catagory, string keywords, string videoFileName) { StringBuilder xml = new StringBuilder(); xml.Append(boundary + lineTerm + "Content-Type: application/atom+xml; charset=UTF-8" + lineTerm + lineTerm); xml.Append("<?xml version=\"1.0\"?><entry xmlns=\"http://www.w3.org/2005/Atom\" "); xml.Append("xmlns:media=\"http://search.yahoo.com/mrss/\" xmlns:yt=\"http://gdata.youtube.com/schemas/2007\">"); xml.AppendFormat("<media:group><media:title type=\"plain\">{0}</media:title>", title); xml.AppendFormat("<media:description type=\"plain\">{0}</media:description>", description); xml.AppendFormat("<media:category scheme=\"http://gdata.youtube.com/schemas/2007/categories.cat\">{0}</media:category>", catagory); xml.AppendFormat("<media:keywords>{0}</media:keywords>", keywords); xml.Append("</media:group></entry>" + lineTerm); xml.Append(boundary + lineTerm + "Content-Type: video/*" + lineTerm + "Content-Transfer-Encoding: binary" + lineTerm + lineTerm); return xml.ToString(); } |
GetHeader simply uses a StringBuilder to build the header data containing the XML. It would probably be better to use an XmlWriter or XmlDocument to build the XML part of this data.
The Upload method then builds a byte array containing the entire content of the POST which includes the raw data for the video to be uploaded. The File.ReadAllBytes method is used to load the video into a byte array.
The HttpWebRequest class is used to POST the video to YouTube. This class is used instead of the simple WebClient because we need to be able to set the timeout for the POST. Since video files can be very large it may take longer than the default timeout for a WebClient request and the WebClient timeout cannot be changed.
Here is an example of using the class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | Trails.YouTube youTube = new Trails.YouTube(); Console.WriteLine("Authorizing..."); if(youTube.Authorize("youtube username", "youtube password")) { Console.WriteLine("Authorized"); Console.WriteLine("Uploading..."); string error; if (youTube.Upload("Test Video", "This is a test", YouTube.Catagory.Howto, "test", @"c:\test.mp4", out error)) { Console.WriteLine("Upload complete"); } else { Console.WriteLine("Upload failed: {0}", error); } } else { Console.WriteLine("Authorization failed"); } |
Using the GoogleData API requires you to have a developer key. Go to the Google YouTube API web page to request a developer key. The library contains two constants named clientCode and devCode. Set devCode to the developer key you got from Google. You will also get a Client ID with your developer key. Set the clientCode constant to the client ID you received.
As you can see it is very easy to upload a video to YouTube from your application. The class has some room for improvement but serves as an example of how to upload videos directly to YouTube. For instance, the Upload method is not checking the response after an upload. A successful upload will return a list of uploaded videos for the YouTube account being used.
Here is the Visual Studio 2005 project with all of the source code.
Trails in the Sand YouTube Library
Enjoy!












Related Articles:

[...] speaks the GData XML format and querying YouTube with C# is fairly simple from there. You can even upload videos programmatically to YouTube like this [...]
[...] speaks the GData XML format and querying YouTube with C# is fairly simple from there. You can even upload videos programmatically to YouTube like this [...]
I plan on playing around with this code this weekend.
There’s one thing I wanted to let you know though. Catagory is misspelled. It should be Category (with an ‘e’).
Cheers.
i use your helping code but where i can get YouTube.Catagory
hi i used your code but it threw exceptiom
403
help me ASAP i m not sure video is upload or not
Did you get the auth issue resolved with c# youtube upload?
Problem solved by
http://uploads.gdata.youtube.com/feeds/api/users/{0}/uploads”,
with
http://uploads.gdata.youtube.com/feeds/api/users/default/uploads“,
A this point the original problem may be a non-issue, since google has notified me that they they had authentication problems around the time I was working on this.
change
req.Headers.Add(”X-GData-Key”, devCode)
to
req.Headers.Add(”X-GData-Key”, “key=” + devCode)
Video uploads succesfully, but there is any way to know the url of the uploaded video, or the code generated? i.e:
http://www.youtube.com/watch?v=aOfeI3gmNGw
aOfeI3gmNGw <—– that thing
Thank you very much
well, finally i can know, in the webresponse header is the generated code
thanks anyway
How to i get the url for the vieo to show on ahtml page?
How to i get the url for the video to show on a html page?
try this… the ID of the video is in the WebResponse headers. You need to split the content of the header, and then, you have the code…
string s1 = objWebResponse.Headers.ToString();
string[] sep = s1.Split(’/');
string s2 = sep[8].ToString();
string[] sep2 = s2.Split(’?');
string url = sep2[0].ToString();
result = “http://www.youtube.com/watch?v=” + url;
Thank you very much i´ll have a go at it today.
Hi,
Do you have any way to add progress bar to show upload progress?
Thanks!
Ohad Kless
Hi everyone,
is there any way of playing the youtube video in C# application by writing youtube url.
thanks you. but I can not see my video i just load.
Thanks ,
I was looking for this Sample more then a week
You Really helped me.
[...] the GData XML format and querying YouTube with C# is fairly simple from there. You can even upload videos programmatically to YouTube like this [...]
i can able to upload the video file with the extention .wmv but i cant able to upload the video file with the extention .flv. can any one help me what to do in the upload function or coding..
Thanks in Advance..
By.
s.venkatesh
hi,I am getting Token invalid - Invalid AuthSub token.401 .I am calling authorize method first and getting auhorized and then calling uploading method.In the response of uploading method..i am getting Token invalid - Invalid AuthSub token.401 in the catch.
kindly assisst me.
Best,
I got the developer key and no client code with a note that it is no longer required. So i commented that out.
I changed the username to my email address and the API authorized me. I changed the developer key in the code. When I m trying to upload I get a “Service Forbidden 403″ Exception. Can you help me out ? This is urgent and I would really appreciate your reply. Thanks
I resolved the issue using my sign in email for authentication and username with the request. Is there a url or video id in the response where I can see the uploaded video ?
hello Asad Siddiqi!
me too.. the same error..
authentication ok with email address..
but i cant upload file.. service forbidden..
have u got the solution?
thanks
nicola
This does not work with ASP.Net web forms and the error returned is “Service Forbidden 403″
hello there!
for 1 months that code in my c# applications worked very very well… now it dosent work… 5 days ago..
i dont change nothing.. can u help me?
change something on utube or google process??
result : authoritazion failed
but by browser i can access on my utube channel..
can u try it on your app??
thank you very much
nicola
if i put my google/utube account its works!
user=email address and pwd=password
and with email the authentification is ok.
but the upload file failed. error: service forbidden
???
thanks
nicola
Hello Friends,
Greetings
I am new to Youtube API use. I am developing my application in .Net
(ASP .Net/C#). I am facing issue as below.
I am trying to post comment for the video that are being uploaded by
users. My code is working fine and it’s not throwing any error.
However i am not able to view comment in the youtube.com against the
video.
My code is as below.
=======================================
YouTubeRequestSettings settings = new
YouTubeRequestSettings(”ApplicationName”,
“AI39si53ltlNkiaLm1P1OAJjuIFNk-IUNsrpO6JowqAKxJ1z4NPXa1Dm8X3vwdSBFGV-
tXUdQa7aQ”);
YouTubeRequest request = new YouTubeRequest(settings);
Comment c = new Comment();
c.Content = “Test Comments”;
Video newVideo = new Video();
newVideo.VideoId = “Hnz5avWae70″;
request.AddComment(newVideo, c);
=======================================
Please let me know what i am doing wrong. Do any one have idea what i
am doing wrong?
Thanks,
Yagnesh
Program is not working .
please help me give correct solution file.