Downloading a Video from YouTube using C#

9/15/2009

I'm not sure how useful this is to the average person, but if you really need that video of that Gopher looking dramatic there's an easy way to download it. It turns out that within a YouTube page, you're given everything that you would need in order to pull down the files. Specifically there is a line in there that looks like this: var swfArgs = {...}. That line of javascript holds everything we need. There are three items from that we need to use: length_seconds, t, and video_id. So we simply parse the data out and add them to an url that looks like this: http://www.youtube.com?video_id=VIDEO_ID&l=LENGTH_SECONDS&t=T. Using this url we can then pull down our video in an FLV file. So how can we automate this process?

   1: /*
   2: Copyright (c) 2010 <a href="http://www.gutgames.com">James Craig</a>
   3: 
   4: Permission is hereby granted, free of charge, to any person obtaining a copy
   5: of this software and associated documentation files (the "Software"), to deal
   6: in the Software without restriction, including without limitation the rights
   7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   8: copies of the Software, and to permit persons to whom the Software is
   9: furnished to do so, subject to the following conditions:
  10: 
  11: The above copyright notice and this permission notice shall be included in
  12: all copies or substantial portions of the Software.
  13: 
  14: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20: THE SOFTWARE.*/
  21:  
  22: #region Usings
  23: using System;
  24: using System.Collections.Generic;
  25: using System.IO;
  26: using System.Net;
  27: using System.Text;
  28: using System.Text.RegularExpressions;
  29: using Utilities.IO;
  30: #endregion
  31:  
  32: namespace Utilities.Web.Youtube
  33: {
  34:     /// <summary>
  35:     /// Class to help with dealing with YouTube
  36:     /// </summary>
  37:     public static class Youtube
  38:     {
  39:         #region Public Static Functions
  40:  
  41:         /// <summary>
  42:         /// Gets a movie and saves it
  43:         /// </summary>
  44:         /// <param name="FileLocation">Location to save the file</param>
  45:         /// <param name="Url">The youtube url for the movie</param>
  46:         public static void GetMovie(string FileLocation, string Url)
  47:         {
  48:             string Content = FileManager.GetFileContents(new Uri(Url));
  49:             Regex TempRegex = new Regex("'SWF_ARGS': {(.*)}");
  50:             Match Match = TempRegex.Match(Content);
  51:             Content = Match.Value;
  52:             TempRegex = new Regex("\"video_id\": \"(.*?\")");
  53:             string VideoLocation = "http://www.youtube.com/get_video?video_id=";
  54:             Match = TempRegex.Match(Content);
  55:             VideoLocation += Match.Groups[1].Value.Replace("\"", "");
  56:             VideoLocation += "&l=";
  57:             TempRegex = new Regex("\"length_seconds\": \"(.*?\")");
  58:             Match = TempRegex.Match(Content);
  59:             VideoLocation += Match.Groups[1].Value.Replace("\"", "");
  60:             VideoLocation += "&t=";
  61:             TempRegex = new Regex("\"t\": \"(.*?\")");
  62:             Match = TempRegex.Match(Content);
  63:             VideoLocation += Match.Groups[1].Value.Replace("\"", "");
  64:             Stream TempStream;
  65:             WebClient Client;
  66:             FileManager.GetFileContents(new Uri(VideoLocation), out TempStream, out Client);
  67:             BinaryReader TempReader = new BinaryReader(TempStream);
  68:             List<byte> Bytes = new List<byte>();
  69:             while (true)
  70:             {
  71:                 byte[] Buffer = new byte[1024];
  72:                 int Length = TempReader.Read(Buffer, 0, 1024);
  73:                 if (Length == 0)
  74:                     break;
  75:                 for (int x = 0; x < Length; ++x)
  76:                 {
  77:                     Bytes.Add(Buffer[x]);
  78:                 }
  79:             }
  80:             TempStream.Dispose();
  81:             Client.Dispose();
  82:             FileManager.SaveFile(Bytes.ToArray(), FileLocation);
  83:         }
  84:  
  85:         /// <summary>
  86:         /// Generates an HTML embed for a youtube video
  87:         /// </summary>
  88:         /// <param name="ID">ID of the video</param>
  89:         /// <returns>The needed embed html tag for the video</returns>
  90:         public static string GenerateEmbed(string ID)
  91:         {
  92:             return GenerateEmbed(ID, false, 320, 240);
  93:         }
  94:  
  95:         /// <summary>
  96:         /// Generates an HTML embed tag for a youtube video
  97:         /// </summary>
  98:         /// <param name="ID">ID of the video</param>
  99:         /// <param name="AutoPlay">Should the video auto play?</param>
 100:         /// <returns>The needed embed html tag</returns>
 101:         public static string GenerateEmbed(string ID, bool AutoPlay)
 102:         {
 103:             return GenerateEmbed(ID, AutoPlay, 320, 240);
 104:         }
 105:  
 106:         /// <summary>
 107:         /// Generates an HTML embed tag for a youtube video
 108:         /// </summary>
 109:         /// <param name="ID">ID of the video</param>
 110:         /// <param name="AutoPlay">Should the video auto play?</param>
 111:         /// <param name="Height">Height of the video</param>
 112:         /// <param name="Width">Width of the video</param>
 113:         /// <returns>The needed embed html tag</returns>
 114:         public static string GenerateEmbed(string ID, bool AutoPlay, int Width, int Height)
 115:         {
 116:             StringBuilder Builder = new StringBuilder();
 117:             Builder.Append(@"<embed src='http://www.youtube.com/v/")
 118:                 .Append(ID).Append("&autoplay=").Append(AutoPlay ? 1 : 0)
 119:                 .Append(@"' type='application/x-shockwave-flash' 
 120:                         allowscriptaccess='never' enableJavascript ='false' 
 121:                         allowfullscreen='true' width='").Append(Width)
 122:                 .Append("' height='").Append(Height).Append(@"'></embed>");
 123:             return Builder.ToString();
 124:         }
 125:  
 126:         #endregion
 127:     }
 128: }

You will notice that the code is using something called FileManager. That is a bit of code that can be found in my utility library. Basically it just downloads the files and gives it to us in a format that we can use. Past that though, it's just a bit of file parsing using Regex. That's all there is to it. So try it out, leave feedback, and happy coding.



Comments