Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using Soup;
- using Json;
- using Xml;
- using Gee;
- namespace Media
- {
- // struct for keep video url(s).
- public struct Item
- {
- public string url;
- public string quality;
- public string type;
- }
- public class Video
- {
- protected string data;
- /*
- A Gee ArrayList<Item> , which contain video links retrieved.
- */
- public ArrayList<Item?> urls{get; protected set;}
- public string title {get; protected set;}
- public Video()
- {
- urls = new ArrayList<Item?>();
- }
- public Video.from_url(string url)
- {
- urls = new ArrayList<Item?>();
- data = IO.download_string(url);
- }
- }
- public errordomain VideoError
- {
- Null,
- Forbidden
- }
- public class Youtube : Video
- {
- public Youtube(string url) throws VideoError
- {
- string[] prms = url.split_set("?&");
- foreach(string p in prms){
- string[] i = p.split("=");
- if(i[0]=="v"){this.id(i[1]);break;}
- }
- }
- public Youtube.id(string id) throws VideoError
- {
- base();
- IO.download_file("http://www.youtube.com/watch?v="+id,"temp.html");
- /// html parsing section, with libxml-2.0 ///
- Html.ParserCtxt ctx = new Html.ParserCtxt();
- ctx.use_options(Html.ParserOption.NOERROR | Html.ParserOption.NOBLANKS | Html.ParserOption.NOWARNING | Html.ParserOption.NONET);
- Html.Doc *doc = ctx.read_file("temp.html");
- XPath.Context c = new XPath.Context(doc);
- XPath.Object *o = c.eval("//script");
- XPath.NodeSet *nodeset = o->nodesetval;
- string script = nodeset->item(4)->get_content();
- /// end of section ///
- /// json parsing ///
- int i = script.index_of("ytplayer.config = ");
- string json = script.substring(i+"ytplayer.config = ".length).replace("};","}");
- Json.Parser p = new Json.Parser();
- p.load_from_data(json);
- Json.Object obj = p.get_root().get_object().get_object_member("args");
- title = obj.get_string_member("title");
- string[] map = obj.get_string_member("url_encoded_fmt_stream_map").split(",");
- /// end of json ///
- foreach(string s in map){
- /* personal unescape, Youtube slipped vicious characters (like , instead of &)
- * also, random distribution of the parameters
- */
- string st = Uri.unescape_string(s).replace("\"","%22").replace("sig=","signature=");
- ArrayList<string> list = new ArrayList<string>();
- string[] t = st.split("&");
- string itag = "";
- string quality = "";
- string type = "";
- foreach(string str in t){
- if(str.index_of("quality=")==0)quality = str.split("=")[1];
- if(str.index_of("type=")==0)type = str.split("=")[1].split(";")[0];
- if(str.index_of("itag=")==0){itag = str;continue;} // Finally, the dual presence of itag parameter
- list.add(str);
- }
- while(true){
- /// shift the list to the beginning of url
- if(list[0].index_of("url=")==0)break;
- string stri = list.remove_at(0);
- list.add(stri);
- }
- st = "";
- foreach(string str in list)
- st += str+"&";
- st += itag;
- urls.add({st.substring(4),quality,type});
- }
- }
- }
- public class Dailymotion : Video
- {
- public Dailymotion(string url)
- {
- base.from_url(url);
- FileUtils.set_data("temp",data.data);
- title = GLib.Uri.unescape_string(data.split("<title>")[1].split("</title>")[0]);
- Json.Parser parser = new Json.Parser();
- FileStream fs = FileStream.open("temp","r");
- string str;
- // reads a line as long as the parameter is not reached
- while((str = fs.read_line())!=null){
- if(str.contains("var flashvars")){
- string[] tab = str.split(" = ",10);
- tab[1] = tab[1].replace(";","");
- parser.load_from_data(tab[1]);
- break;
- }
- }
- var o = parser.get_root().get_object();
- str = Uri.unescape_string(o.get_string_member("sequence"));
- parser.load_from_data(str);
- o = parser.get_root().get_object();
- //parsing json to the list of video urls
- o = o.get_array_member("sequence")
- .get_object_element(0).get_array_member("layerList")
- .get_object_element(0).get_array_member("sequenceList")
- .get_object_element(2).get_array_member("layerList")
- .get_object_element(2).get_object_member("param");
- urls.add({o.get_string_member("ldURL"),"ld","mp4"});
- urls.add({o.get_string_member("sdURL"),"sd","mp4"});
- urls.add({o.get_string_member("hqURL"),"hq","mp4"});
- }
- }
- public class IGN : Video
- {
- public IGN(string url){
- base.from_url(url);
- FileUtils.set_data("temp",data.data);
- title = GLib.Uri.unescape_string(data.split("<title>")[1].split("</title>")[0]).replace("'","&");
- FileStream fs = FileStream.open("temp","r");
- string str = "";
- string[] t = new string[]{""};
- while((str = fs.read_line())!=null){
- if(str.contains("iPadVideoSource_0")){
- stdout.printf(str+"\n");
- t = str.split("\"");
- urls.add({t[3],"hq","mp4"});
- }
- if(str.contains("videoSource_0")){
- t = str.split("\"");
- urls.add({t[3],"sd","mp4"});
- }
- if(str.contains("mVideoSource_0")){
- t = str.split("\"");
- urls.add({t[3],"ld","mp4"});
- }
- }
- }
- }
- }
- /*
- static methods for convenience
- */
- namespace IO
- {
- public errordomain Error
- {
- Null
- }
- public static void download_file(string uri, string dest_file) throws IO.Error
- {
- if(dest_file == null)throw new IO.Error.Null("name of destination cannot be null");
- uint8[] data = download_data(uri);
- if(data.length < 1)throw new IO.Error.Null("data length is too short or null");
- FileUtils.set_data(dest_file,data);
- }
- public static uint8[] download_data(string uri){
- var session = new SessionSync();
- var message = new Message("GET",uri);
- session.send_message(message);
- return message.response_body.data;
- }
- public static string download_string(string uri){
- return (string)download_data(uri);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement