Advertisement
rotrevrep

video.vala

May 2nd, 2013
295
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Vala 6.43 KB | None | 0 0
  1. using Soup;
  2. using Json;
  3. using Xml;
  4. using Gee;
  5.  
  6. namespace Media
  7. {
  8.     // struct for keep video url(s).
  9.    
  10.     public struct Item
  11.     {
  12.         public string url;
  13.         public string quality;
  14.         public string type;
  15.     }
  16.    
  17.     public class Video
  18.     {
  19.         protected string data;
  20.        
  21.         /*
  22.         A Gee ArrayList<Item> , which contain video links retrieved.
  23.          */
  24.        
  25.         public ArrayList<Item?> urls{get; protected set;}
  26.         public string title {get; protected set;}
  27.        
  28.         public Video()
  29.         {
  30.             urls = new ArrayList<Item?>();
  31.         }
  32.        
  33.         public Video.from_url(string url)
  34.         {
  35.             urls = new ArrayList<Item?>();
  36.             data = IO.download_string(url);
  37.         }
  38.     }
  39.    
  40.     public errordomain VideoError
  41.     {
  42.         Null,
  43.         Forbidden
  44.     }
  45.    
  46.     public class Youtube : Video
  47.     {
  48.         public Youtube(string url) throws VideoError
  49.         {
  50.             string[] prms = url.split_set("?&");
  51.             foreach(string p in prms){
  52.                 string[] i = p.split("=");
  53.                 if(i[0]=="v"){this.id(i[1]);break;}
  54.             }
  55.         }
  56.        
  57.         public Youtube.id(string id) throws VideoError
  58.         {
  59.             base();
  60.             IO.download_file("http://www.youtube.com/watch?v="+id,"temp.html");
  61.            
  62.             /// html parsing section, with libxml-2.0 ///
  63.             Html.ParserCtxt ctx = new Html.ParserCtxt();
  64.             ctx.use_options(Html.ParserOption.NOERROR | Html.ParserOption.NOBLANKS | Html.ParserOption.NOWARNING | Html.ParserOption.NONET);
  65.             Html.Doc *doc = ctx.read_file("temp.html");
  66.             XPath.Context c = new XPath.Context(doc);
  67.             XPath.Object *o = c.eval("//script");
  68.             XPath.NodeSet *nodeset = o->nodesetval;
  69.             string script = nodeset->item(4)->get_content();
  70.             /// end of section ///
  71.             /// json parsing ///
  72.             int i = script.index_of("ytplayer.config = ");
  73.             string json = script.substring(i+"ytplayer.config = ".length).replace("};","}");
  74.             Json.Parser p = new Json.Parser();
  75.             p.load_from_data(json);
  76.             Json.Object obj = p.get_root().get_object().get_object_member("args");
  77.             title = obj.get_string_member("title");
  78.             string[] map = obj.get_string_member("url_encoded_fmt_stream_map").split(",");
  79.             /// end of json ///
  80.             foreach(string s in map){
  81.                 /* personal unescape, Youtube slipped vicious characters (like , instead of &)
  82.                  * also, random distribution of the parameters
  83.                  */
  84.                 string st = Uri.unescape_string(s).replace("\"","%22").replace("sig=","signature=");
  85.                 ArrayList<string> list = new ArrayList<string>();
  86.                 string[] t = st.split("&");
  87.                 string itag = "";
  88.                 string quality = "";
  89.                 string type = "";
  90.                 foreach(string str in t){
  91.                     if(str.index_of("quality=")==0)quality = str.split("=")[1];
  92.                     if(str.index_of("type=")==0)type = str.split("=")[1].split(";")[0];
  93.                     if(str.index_of("itag=")==0){itag = str;continue;} // Finally, the dual presence of itag parameter
  94.                     list.add(str);
  95.                 }
  96.                 while(true){
  97.                     /// shift the list to the beginning of url
  98.                     if(list[0].index_of("url=")==0)break;
  99.                     string stri = list.remove_at(0);
  100.                     list.add(stri);
  101.                 }
  102.                 st = "";
  103.                 foreach(string str in list)
  104.                     st += str+"&";
  105.                 st += itag;
  106.                 urls.add({st.substring(4),quality,type});
  107.             }
  108.         }
  109.     }
  110.  
  111.     public class Dailymotion : Video
  112.     {
  113.         public Dailymotion(string url)
  114.         {
  115.             base.from_url(url);
  116.             FileUtils.set_data("temp",data.data);
  117.             title = GLib.Uri.unescape_string(data.split("<title>")[1].split("</title>")[0]);
  118.             Json.Parser parser = new Json.Parser();
  119.             FileStream fs = FileStream.open("temp","r");
  120.             string str;
  121.             // reads a line as long as the parameter is not reached
  122.             while((str = fs.read_line())!=null){
  123.                 if(str.contains("var flashvars")){
  124.                     string[] tab = str.split(" = ",10);
  125.                     tab[1] = tab[1].replace(";","");
  126.                     parser.load_from_data(tab[1]);
  127.                     break;
  128.                 }
  129.             }
  130.             var o = parser.get_root().get_object();
  131.             str = Uri.unescape_string(o.get_string_member("sequence"));
  132.             parser.load_from_data(str);
  133.             o = parser.get_root().get_object();
  134.             //parsing json to the list of video urls
  135.             o = o.get_array_member("sequence")
  136.             .get_object_element(0).get_array_member("layerList")
  137.             .get_object_element(0).get_array_member("sequenceList")
  138.             .get_object_element(2).get_array_member("layerList")
  139.             .get_object_element(2).get_object_member("param");
  140.             urls.add({o.get_string_member("ldURL"),"ld","mp4"});
  141.             urls.add({o.get_string_member("sdURL"),"sd","mp4"});
  142.             urls.add({o.get_string_member("hqURL"),"hq","mp4"});
  143.         }
  144.     }
  145.    
  146.     public class IGN : Video
  147.     {
  148.         public IGN(string url){
  149.             base.from_url(url);
  150.             FileUtils.set_data("temp",data.data);
  151.             title = GLib.Uri.unescape_string(data.split("<title>")[1].split("</title>")[0]).replace("&#039;","&");
  152.             FileStream fs = FileStream.open("temp","r");
  153.             string str = "";
  154.             string[] t = new string[]{""};
  155.             while((str = fs.read_line())!=null){
  156.                 if(str.contains("iPadVideoSource_0")){
  157.                     stdout.printf(str+"\n");
  158.                     t = str.split("\"");
  159.                     urls.add({t[3],"hq","mp4"});
  160.                 }
  161.                 if(str.contains("videoSource_0")){
  162.                     t = str.split("\"");
  163.                     urls.add({t[3],"sd","mp4"});
  164.                 }
  165.                 if(str.contains("mVideoSource_0")){
  166.                     t = str.split("\"");
  167.                     urls.add({t[3],"ld","mp4"});
  168.                 }
  169.             }
  170.         }
  171.     }
  172. }
  173.  
  174.  
  175. /*
  176.     static methods for convenience
  177. */
  178.  
  179. namespace IO
  180. {
  181.     public errordomain Error
  182.     {
  183.         Null
  184.     }
  185.    
  186.     public static void download_file(string uri, string dest_file) throws IO.Error
  187.     {
  188.         if(dest_file == null)throw new IO.Error.Null("name of destination cannot be null");
  189.         uint8[] data = download_data(uri);
  190.         if(data.length < 1)throw new IO.Error.Null("data length is too short or null");
  191.         FileUtils.set_data(dest_file,data);
  192.     }
  193.    
  194.     public static uint8[] download_data(string uri){
  195.         var session = new SessionSync();
  196.         var message = new Message("GET",uri);
  197.         session.send_message(message);
  198.         return message.response_body.data;
  199.     }
  200.  
  201.     public static string download_string(string uri){
  202.         return (string)download_data(uri);
  203.     }
  204. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement