Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Downloading Youtube Videos C# WinForm

0.00/5 (No votes)
2 Jul 2010 1  
Grab Youtube video in C# WinForm

Introduction

My Name is Charles Henington and I will be offering a YouTube Downloader that I developed in C#. It is complete with the source code.

Acknowledgements

The DLL that works with my downloader is open an opensource download made available through http://videodownloader.codeplex.com/. There is documentation available on the site. I use an HTTP downloader to access the HTTP download link supplied by the DLL. I cannot remember where this download came from, but I believe it was here on CodeProject. If you believe it is your project, please let me know so I can give proper acknowledgements.

Upcoming Additions

I will be working on the program in VB and will post it as soon as it is completed. I have been having a slight problem with one of the codes, since it is near completion except one code issue, I may submit it to get a better understanding of the issue. I do know that it is a runtime error according to MSDN.

Using the Code

Now to the code:

Right after the form initialization, we will add two lines of code. These two lines will do two things:

  1. private byte[] downloadedData; 

    prepares the downloader to download our video, and

  2. private Video_downloader_DLL.VideoDownloader = 
    	new Video_Downloader.DLL.VideoDownloader();
// This code is for the HTTP downloader
private byte[] downloadedData;

// this code is to call the DLL
private Video_Downloader_DLL.VideoDownloader downloadmaker = 
	new Video_Downloader_DLL.VideoDownloader();

Now we have the button 1 click event which is the click event for the DLL. This is where the DLL will give us the link of the download and the file name of the video. The two textboxes will be set to visible = false; (can be set like this in form initialize or set as visible false under the properties. I have it set under properties but it all depends on how you prefer to write your code.) We will need this information behind the scenes to obtain the download link of the video to be downloaded and for the file name to save as with the savefiledialog and for the msgbox that will display which video is being downloaded.

private void Button1_Click(object sender, System.EventArgs e)
{ 
 string videotitle = "";
 //string thumbnailurl i don't use but it can be used in three
 // (1) display image link (2) display image or (3) both 
 //string thumbnailurl = "";
 string output = "";
 string inputurl = TextBox1.Text;
 // this tell the DLL to get the title of the video
 downloadmaker.GetVideoTitle(inputurl, ref videotitle);
 System.String tempVar = "";
 System.Int32 tempVar2 = 0;
 // this lets the DLL know that the download link will
 // be set to string output which is textbox1.text
 downloadmaker.MakeDownloadURL(inputurl, ref output, ref tempVar, ref tempVar2);
 // this lets us obtain the thumbnail of the video we are downloading which once
 // again I am not using but I have included in case you would
 // like to add it to your project
 //downloadmaker.GetPreviewThumbnail(inputurl, ref thumbnailurl);
 OutLink.Text = (videotitle);
 LinkText.Text = (output);
 //PicImage.Text = (thumbnailurl);
 // this message box informs you which download is being processed
 // plus the steps to downloading the video which is somewhat confusing
 // at first also it takes a few moments for the DLL to extract the
 // information and this kills the few moments of wait time nicely. 
 MessageBox.Show("To Download " + videotitle + Environment.NewLine + 
	"Please click Download now, When finished Downloading select Save To File");
}

Now that we have the information for the download from the DLL, we will start working with setting up the download. Here we declare our progress bar to refresh and adjust itself to the bytes that are being downloaded. It makes a web request and if the web request is successful, i.e., the download file is found, then it downloads the file in chunks of bytes via a byte buffer through a memory stream. Then it is converted to a byte array. IMPORTANT! Some questions that I have noticed in forums ask how to use the file that is in the memory stream to manipulate the file, i.e., convert the file to a different format. If you do decide to add on to this project, I would like to save you some time and inform you that the file must be saved before you can do anything with the file as it cannot be altered or used for anything but saving while still in the memory stream. It will also update the byte count that is downloaded via the lbprogress label, just set the label text to 0/0 in the labels properties. If the web request was unsuccessful, i.e., the download link was not found, then the message box will display there was an error accessing the URL.

private void downloadData(string url)
{
 progressBar1.Value = 0;
 downloadedData = new byte[0];
 try
 {
  //Optional
  this.Text = "Connecting...";
  Application.DoEvents();
  //Get a data stream from the url
  WebRequest req = WebRequest.Create(url);
  WebResponse response = req.GetResponse();
  Stream stream = response.GetResponseStream();
  //Download in chunks
  byte[] buffer = new byte[1024];
  //Get Total Size
  int dataLength = (int)response.ContentLength;
  //With the total data we can set up our progress indicators
  progressBar1.Maximum = dataLength;
  lbProgress.Text = "0/" + dataLength.ToString();
  this.Text = "Downloading...";
  Application.DoEvents();
  //Download to memory
  //Note: adjust the streams here to download directly to the hard drive
  MemoryStream memStream = new MemoryStream();
  while (true)
  {
   //Try to read the data
   int bytesRead = stream.Read(buffer, 0, buffer.Length);
   if (bytesRead == 0)
   {
    //Finished downloading
    progressBar1.Value = progressBar1.Maximum;
    lbProgress.Text = dataLength.ToString() + "/" + dataLength.ToString();
    Application.DoEvents();
    break;
   }
   else
   {
    //Write the downloaded data
    memStream.Write(buffer, 0, bytesRead);
    //Update the progress bar
    if (progressBar1.Value + bytesRead <= progressBar1.Maximum)
    {
     progressBar1.Value += bytesRead;
     lbProgress.Text = progressBar1.Value.ToString() + "/" + dataLength.ToString();
     progressBar1.Refresh();
     Application.DoEvents();
    }
   }
 }
 //Convert the downloaded stream to a byte array
 downloadedData = memStream.ToArray();
 //Clean up
 stream.Close();
 memStream.Close();
}
catch (Exception)
{
 //May not be connected to the internet
 //Or the URL might not exist
 MessageBox.Show("There was an error accessing the URL.");
}
txtData.Text = downloadedData.Length.ToString();
this.Text = "YT Snatcher";
}

Now we have our download web request ready, we add the download button event which will download the URL that is stored in LinkText text box. The string ytdata is the video file title that the DLL generated earlier. I have the ytdata string set as the savefiledialogs filename to save to and have it set to add the extension .flv. IMPORTANT! I have noticed that in forums I see many!! discussions on codec to make flv play in (wmp) windows media player. This is funny to me because if you rename a flv file to wmv extension, the data stays the same and wmp will play it then. It will show an error to play anyways and an option to ignore the error for the file type wmv, you can ignore this and not get the warning again or just click to play anyways and do this every time you load the file in wmp. Either way, the flv file will play perfectly. If you want a flv file, just rename it back to flv no harm done.

private void btnDownload_Click(object sender, EventArgs e)
{
 downloadData(LinkText.Text);
 //Get the last part of the url, ie the file name
 if (downloadedData != null && downloadedData.Length != 0)
 {
  string ytdata = OutLink.Text; // this is the video title
  string urlName = LinkText.Text; // this is the download link
  if (urlName.EndsWith("/"))
  urlName = urlName.Substring(0, urlName.Length - 1); //Chop off the last '/'
  urlName = urlName.Substring(urlName.LastIndexOf('/') + 1);
  saveDiag1.FileName = ytdata + ".flv"; 	// this loads the videotitle 
					// = .flv into savefile dialog
 }
}

Now that the data is downloaded, it is in a memorystream and we need to save it to file with the save button click event. This brings up the save file dialog with the file to save to as the video title + .flv. You can change to mp4 only if the original file was mp4 if it wasn't and it was saved as mp4, just rename back to .flv but remember to rename true flv file not (mp4) to wmv and it will play in wmp.

private void button2_Click(object sender, EventArgs e)
{
 if (downloadedData != null && downloadedData.Length != 0)
 {
  if (saveDiag1.ShowDialog() == DialogResult.OK)
  {
   this.Text = "Saving Data...";
   Application.DoEvents();
   //Write the bytes to a file
   FileStream newFile = new FileStream(saveDiag1.FileName, FileMode.Create);
   newFile.Write(downloadedData, 0, downloadedData.Length);
   newFile.Close();
   this.Text = "Download Data";
   MessageBox.Show("Saved Successfully"); // if file was downloaded
  }
 }
 else
 MessageBox.Show("No File was Downloaded Yet!"); // if no file downloaded
}
}
}

We now have our YouTube video stored on the computer where we can view anytime we want!! I hope you have found this tutorial informative and I hope you enjoy the downloader. Please rate the tutorial if you like it or not. :laugh:

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here