~ubuntu-branches/ubuntu/utopic/totem-plugin-arte/utopic-proposed

« back to all changes in this revision

Viewing changes to url-extractor.vala

  • Committer: Package Import Robot
  • Author(s): Nicolas Delvaux
  • Date: 2011-10-23 13:55:28 UTC
  • mfrom: (3.1.5 experimental)
  • Revision ID: package-import@ubuntu.com-20111023135528-l9lso2mnile0dk8u
Tags: 3.0.0-2
* Upload to unstable
* Fix FTBS by switching to valac-0.14 and libpeas 1.1 (bump dependencies)
* Update the user-agent string
* Rework the "disable gsettings schema compilation" patch (use upstream patch)
* Packaging:
  - Tweak the long description (some videos are playable everywhere)
  - Remove VCS links in Control (there is no VCS for this package)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * Totem Arte Plugin allows you to watch streams from arte.tv
3
 
 * Copyright (C) 2010 Simon Wenner <simon@wenner.ch>
 
3
 * Copyright (C) 2010, 2011 Simon Wenner <simon@wenner.ch>
4
4
 *
5
5
 * This program is free software; you can redistribute it and/or modify
6
6
 * it under the terms of the GNU General Public License as published by
37
37
    ACCESS_RESTRICTED
38
38
}
39
39
 
40
 
public interface Extractor : GLib.Object
41
 
{
42
 
  public abstract string get_url (VideoQuality q, Language lang, string page_url)
43
 
      throws ExtractionError;
44
 
}
45
 
 
46
 
public class StreamUrlExtractor : GLib.Object
47
 
{
48
 
  protected Soup.SessionAsync session;
49
 
 
50
 
  public StreamUrlExtractor()
51
 
  {
52
 
    session = create_session ();
53
 
  }
54
 
 
55
 
  protected string extract_string_from_page (string url, string regexp)
56
 
      throws ExtractionError
57
 
  {
58
 
    /* Download */
59
 
    var msg = new Soup.Message ("GET", url);
60
 
    this.session.send_message(msg);
61
 
    if (msg.response_body.data == null)
62
 
      throw new ExtractionError.DOWNLOAD_FAILED ("Video URL Extraction Error");
63
 
 
64
 
    /* Extract */
65
 
    string res = null;
66
 
    try {
67
 
      MatchInfo match;
68
 
      var regex = new Regex (regexp);
69
 
      regex.match((string) msg.response_body.flatten ().data, 0, out match);
70
 
      res = match.fetch(1);
71
 
    } catch (RegexError e) {
72
 
        GLib.warning ("%s", e.message);
73
 
        throw new ExtractionError.EXTRACTION_FAILED (e.message);
74
 
    }
75
 
 
76
 
    return res;
77
 
  }
78
 
}
79
 
 
80
 
public class RTMPStreamUrlExtractor : StreamUrlExtractor, Extractor
81
 
{
82
 
  public string get_url (VideoQuality q, Language lang, string page_url)
83
 
      throws ExtractionError
84
 
  {
85
 
    string regexp, url;
86
 
    GLib.debug ("Initial Page URL:\t\t%s", page_url);
87
 
 
88
 
    /* Setup the language string */
89
 
    string lang_str = "fr";
90
 
    if (lang == Language.GERMAN)
91
 
      lang_str = "de";
92
 
 
93
 
    /* Setup quality string */
94
 
    string quali_str = "hd";
95
 
    if (q == VideoQuality.WMV_MQ)
96
 
      quali_str = "sd";
97
 
 
98
 
    /* Get the Arte Flash player URI */
99
 
    // Example:
100
 
    // var url_player = "http://videos.arte.tv/blob/web/i18n/view/player_9-3188338-data-4807088.swf";
101
 
    regexp = "var url_player = \"(http://.*.swf)\";";
102
 
    var flash_player_uri = extract_string_from_page (page_url, regexp);
103
 
    GLib.debug ("Extract Flash player URI:\t%s", flash_player_uri);
104
 
    if (flash_player_uri == null)
105
 
      throw new ExtractionError.EXTRACTION_FAILED ("Video URL Extraction Error");
106
 
 
107
 
    /* Get the Flash XML data */
108
 
    // Example:
109
 
    // vars_player.videorefFileUrl = "http://videos.arte.tv/de/do_delegate/videos/geheimnisvolle_pflanzen-3219416,view,asPlayerXml.xml";
110
 
    regexp = "videorefFileUrl = \"(http://.*.xml)\";";
111
 
    url = extract_string_from_page (page_url, regexp);
112
 
    GLib.debug ("Extract Flash Videoref:\t%s", url);
113
 
 
114
 
    if (url == null)
115
 
      throw new ExtractionError.EXTRACTION_FAILED ("Video URL Extraction Error");
116
 
 
117
 
    /* Get the language specific flash XML data */
118
 
    // Example:
119
 
    // <video lang="de" ref="http://videos.arte.tv/de/do_delegate/videos/geheimnisvolle_pflanzen-3219418,view,asPlayerXml.xml"/>
120
 
    // <video lang="fr" ref="http://videos.arte.tv/fr/do_delegate/videos/secrets_de_plantes-3219420,view,asPlayerXml.xml"/>
121
 
    regexp = "video lang=\"" + lang_str + "\" ref=\"(http://.*.xml)\"";
122
 
    url = extract_string_from_page (url, regexp);
123
 
    GLib.debug ("Extract Flash Lang Videoref:\t%s", url);
124
 
 
125
 
    if (url == null)
126
 
      throw new ExtractionError.EXTRACTION_FAILED ("Video URL Extraction Error");
127
 
 
128
 
    /* Get the RTMP uri. */
129
 
    // Example:
130
 
    // <url quality="hd">rtmp://artestras.fcod.llnwd.net/a3903/o35/MP4:geo/videothek/EUR_DE_FR/arteprod/A7_SGT_ENC_08_037778-021-B_PG_HQ_FR?h=7258f52f54eb0d320f6650e647432f03</url>
131
 
    // <url quality="sd">rtmp://artestras.fcod.llnwd.net/a3903/o35/MP4:geo/videothek/EUR_DE_FR/arteprod/A7_SGT_ENC_06_037778-021-B_PG_MQ_FR?h=76c529bce0f034e74dc92a14549d6a4e</url>
132
 
    regexp = "quality=\"" + quali_str + "\">(rtmp://.*)</url>";
133
 
    var rtmp_uri = extract_string_from_page (url, regexp);
134
 
    GLib.debug ("Extract RTMP URI:\t\t%s", rtmp_uri);
135
 
 
136
 
    /* sometimes only one quality level is available */
137
 
    if (rtmp_uri == null) {
138
 
      if (q == VideoQuality.WMV_HQ) {
139
 
        q = VideoQuality.WMV_MQ;
140
 
        quali_str = "sd";
141
 
        GLib.warning ("No high quality stream available. Fallback to medium quality.");
142
 
      } else if (q == VideoQuality.WMV_MQ) {
143
 
        q = VideoQuality.WMV_HQ;
144
 
        quali_str = "hd";
145
 
        GLib.warning ("No medium quality stream available. Fallback to high quality.");
146
 
      }
147
 
      regexp = "quality=\"" + quali_str + "\">(rtmp://.*)</url>";
148
 
      rtmp_uri = extract_string_from_page (url, regexp);
149
 
      GLib.debug ("Extract RTMP URI:\t\t%s", rtmp_uri);
150
 
 
151
 
      if (rtmp_uri == null)
152
 
        throw new ExtractionError.STREAM_NOT_READY ("This video is not available yet");
153
 
    }
154
 
 
155
 
    /* detect videos with temporal restrictions */
156
 
    if (rtmp_uri.has_suffix ("/carton_23h_fr.mp4") || rtmp_uri.has_suffix ("/carton_23h_de.mp4"))
157
 
      throw new ExtractionError.ACCESS_RESTRICTED ("This video is not available currently");
158
 
    
159
 
    /* Build the stream URI
160
 
     * To prevent regular disconnections (and so to keep the plugin usable),
161
 
     * we need to pass the Flash player uri to GStreamer.
162
 
     * We do that by appending it to the stream uri.
163
 
     * (see the librtmp manual for more information) */
164
 
    // Example:
165
 
    // rtmp://artestras.fcod.llnwd.net/a3903/o35/MP4:geo/videothek/EUR_DE_FR/arteprod/A7_SGT_ENC_08_042143-002-A_PG_HQ_FR?h=d7878fae5c9726844d22da78e05f764e swfVfy=1 swfUrl=http://videos.arte.tv/blob/web/i18n/view/player_9-3188338-data-4807088.swf
166
 
    string stream_uri = rtmp_uri + " swfVfy=1 swfUrl=" + flash_player_uri;
167
 
    GLib.debug ("Build stream URI:\t\t%s", stream_uri);
168
 
 
169
 
    return stream_uri;
170
 
  }
171
 
}
172
 
 
173
 
/* This extractor use "EQ" quality links provided by Arte. */
174
 
// While writing this, these links do not work.
175
 
// So this extractor stays here, waiting for its time...
176
 
public class MP4StreamUrlExtractor : StreamUrlExtractor, Extractor
177
 
{
178
 
  public string get_url (VideoQuality q, Language lang, string page_url)
179
 
      throws ExtractionError
180
 
  {
181
 
    string regexp, url;
182
 
    GLib.debug ("Initial Page URL:\t\t%s", page_url);
183
 
 
184
 
    /* Setup the language string */
185
 
    string lang_str = "fr";
186
 
    if (lang == Language.GERMAN)
187
 
      lang_str = "de";
188
 
 
189
 
    /* Get the Flash XML data */
190
 
    // Example:
191
 
    // vars_player.videorefFileUrl = "http://videos.arte.tv/de/do_delegate/videos/geheimnisvolle_pflanzen-3219416,view,asPlayerXml.xml";
192
 
    regexp = "videorefFileUrl = \"(http://.*.xml)\";";
193
 
    url = extract_string_from_page (page_url, regexp);
194
 
    GLib.debug ("Extract Flash Videoref:\t\t%s", url);
195
 
 
196
 
    if (url == null)
197
 
      throw new ExtractionError.EXTRACTION_FAILED ("Video URL Extraction Error");
198
 
 
199
 
    /* Get the language specific flash XML data */
200
 
    // Example:
201
 
    // <video lang="de" ref="http://videos.arte.tv/de/do_delegate/videos/geheimnisvolle_pflanzen-3219418,view,asPlayerXml.xml"/>
202
 
    // <video lang="fr" ref="http://videos.arte.tv/fr/do_delegate/videos/secrets_de_plantes-3219420,view,asPlayerXml.xml"/>
203
 
    regexp = "video lang=\"" + lang_str + "\" ref=\"(http://.*.xml)\"";
204
 
    url = extract_string_from_page (url, regexp);
205
 
    GLib.debug ("Extract Flash Lang Videoref:\t%s", url);
206
 
 
207
 
    if (url == null) {
208
 
      throw new ExtractionError.EXTRACTION_FAILED ("Video URL Extraction Error");
209
 
    }
210
 
 
211
 
    /* Get the EQ uri */
212
 
    // Example:
213
 
    // <url quality="EQ">http://artestras.wmod.rd.llnw.net/geo/arte7/EUR_DE_FR/arteprod/A7_SGT_ENC_16_037778-021-B_PG_EQ_FR.mp4</url>
214
 
    regexp = "quality=\"EQ\">(http://.*.mp4)";
215
 
    var eq_uri = extract_string_from_page (url, regexp);
216
 
    GLib.debug ("Extract EQ URI:\t\t%s", eq_uri);
217
 
 
218
 
    /* Extract the real url */
219
 
    // Example:
220
 
    // <REF HREF="mms://artestras.wmod.llnwd.net/a3903/o35/geo/arte7/EUR_DE_FR/arteprod/A7_SGT_ENC_16_037778-021-B_PG_EQ_FR.mp4?e=1280957332&amp;h=3ab8ed22003545b1f46c6a595d5c6475"/>
221
 
    regexp = "\"(mms://.*)\"";
222
 
    var real_url = extract_string_from_page (eq_uri, regexp);
223
 
    GLib.debug ("Extract Real WMV URL:\t\t%s", real_url);
224
 
 
225
 
    return real_url;
226
 
  }
227
 
}
228
 
 
 
40
public interface UrlExtractor : GLib.Object
 
41
{
 
42
    public abstract string get_url (VideoQuality q, Language lang, string page_url)
 
43
            throws ExtractionError;
 
44
}
 
45
 
 
46
public class IndirectUrlExtractor : GLib.Object
 
47
{
 
48
    protected Soup.SessionAsync session;
 
49
 
 
50
    public IndirectUrlExtractor()
 
51
    {
 
52
        session = create_session ();
 
53
    }
 
54
 
 
55
    protected string extract_string_from_page (string url, string regexp)
 
56
            throws ExtractionError
 
57
    {
 
58
        /* Download */
 
59
        var msg = new Soup.Message ("GET", url);
 
60
        this.session.send_message(msg);
 
61
        if (msg.response_body.data == null)
 
62
            throw new ExtractionError.DOWNLOAD_FAILED ("Video URL Extraction Error");
 
63
 
 
64
        /* Extract */
 
65
        string res = null;
 
66
        try {
 
67
            MatchInfo match;
 
68
            var regex = new Regex (regexp);
 
69
            regex.match((string) msg.response_body.flatten ().data, 0, out match);
 
70
            res = match.fetch(1);
 
71
        } catch (RegexError e) {
 
72
            GLib.warning ("%s", e.message);
 
73
            throw new ExtractionError.EXTRACTION_FAILED (e.message);
 
74
        }
 
75
 
 
76
        return res;
 
77
    }
 
78
}
 
79
 
 
80
public class RTMPStreamUrlExtractor : IndirectUrlExtractor, UrlExtractor
 
81
{
 
82
    public string get_url (VideoQuality q, Language lang, string page_url)
 
83
            throws ExtractionError
 
84
    {
 
85
        string regexp, url;
 
86
        debug ("Initial Page URL:\t\t'%s'", page_url);
 
87
 
 
88
        /* Setup the language string */
 
89
        string lang_str = "fr";
 
90
        if (lang == Language.GERMAN)
 
91
            lang_str = "de";
 
92
 
 
93
        /* Setup quality string */
 
94
        string quali_str = "hd";
 
95
        if (q == VideoQuality.MEDIUM)
 
96
            quali_str = "sd";
 
97
 
 
98
        /* Get the Arte Flash player URI */
 
99
        // Example:
 
100
        // var url_player = "http://videos.arte.tv/blob/web/i18n/view/player_9-3188338-data-4807088.swf";
 
101
        regexp = "var url_player = \"(http://.*.swf)\";";
 
102
        var flash_player_uri = extract_string_from_page (page_url, regexp);
 
103
        debug ("Extract Flash player URI:\t'%s'", flash_player_uri);
 
104
        if (flash_player_uri == null)
 
105
            throw new ExtractionError.EXTRACTION_FAILED ("Video URL Extraction Error");
 
106
 
 
107
        /* Get the Flash XML data */
 
108
        // Example:
 
109
        // vars_player.videorefFileUrl = "http://videos.arte.tv/de/do_delegate/videos/geheimnisvolle_pflanzen-3219416,view,asPlayerXml.xml";
 
110
        regexp = "videorefFileUrl = \"(http://.*.xml)\";";
 
111
        url = extract_string_from_page (page_url, regexp);
 
112
        debug ("Extract Flash Videoref:\t'%s'", url);
 
113
 
 
114
        if (url == null)
 
115
            throw new ExtractionError.EXTRACTION_FAILED ("Video URL Extraction Error");
 
116
 
 
117
        /* Get the language specific flash XML data */
 
118
        // Example:
 
119
        // <video lang="de" ref="http://videos.arte.tv/de/do_delegate/videos/geheimnisvolle_pflanzen-3219418,view,asPlayerXml.xml"/>
 
120
        // <video lang="fr" ref="http://videos.arte.tv/fr/do_delegate/videos/secrets_de_plantes-3219420,view,asPlayerXml.xml"/>
 
121
        regexp = "video lang=\"" + lang_str + "\" ref=\"(http://.*.xml)\"";
 
122
        url = extract_string_from_page (url, regexp);
 
123
        debug ("Extract Flash Lang Videoref:\t'%s'", url);
 
124
 
 
125
        if (url == null)
 
126
            throw new ExtractionError.EXTRACTION_FAILED ("Video URL Extraction Error");
 
127
 
 
128
        /* Get the RTMP uri. */
 
129
        // Example:
 
130
        // <url quality="hd">rtmp://artestras.fcod.llnwd.net/a3903/o35/MP4:geo/videothek/EUR_DE_FR/arteprod/A7_SGT_ENC_08_037778-021-B_PG_HQ_FR?h=7258f52f54eb0d320f6650e647432f03</url>
 
131
        // <url quality="sd">rtmp://artestras.fcod.llnwd.net/a3903/o35/MP4:geo/videothek/EUR_DE_FR/arteprod/A7_SGT_ENC_06_037778-021-B_PG_MQ_FR?h=76c529bce0f034e74dc92a14549d6a4e</url>
 
132
        regexp = "quality=\"" + quali_str + "\">(rtmp://.*)</url>";
 
133
        var rtmp_uri = extract_string_from_page (url, regexp);
 
134
        debug ("Extract RTMP URI:\t\t'%s'", rtmp_uri);
 
135
 
 
136
        /* sometimes only one quality level is available */
 
137
        if (rtmp_uri == null) {
 
138
            if (q == VideoQuality.HIGH) {
 
139
                q = VideoQuality.MEDIUM;
 
140
                quali_str = "sd";
 
141
                GLib.warning ("No high quality stream available. Fallback to medium quality.");
 
142
            } else if (q == VideoQuality.MEDIUM) {
 
143
                q = VideoQuality.HIGH;
 
144
                quali_str = "hd";
 
145
                GLib.warning ("No medium quality stream available. Fallback to high quality.");
 
146
            }
 
147
            regexp = "quality=\"" + quali_str + "\">(rtmp://.*)</url>";
 
148
            rtmp_uri = extract_string_from_page (url, regexp);
 
149
            debug ("Extract RTMP URI:\t\t'%s'", rtmp_uri);
 
150
 
 
151
            if (rtmp_uri == null)
 
152
                throw new ExtractionError.STREAM_NOT_READY ("This video is not available yet");
 
153
        }
 
154
 
 
155
        /* detect videos with temporal restrictions */
 
156
        if (rtmp_uri.has_suffix ("/carton_23h_fr.mp4") || rtmp_uri.has_suffix ("/carton_23h_de.mp4"))
 
157
            throw new ExtractionError.ACCESS_RESTRICTED ("This video is not available currently");
 
158
 
 
159
        /* Build the stream URI
 
160
         * To prevent regular disconnections (and so to keep the plugin usable),
 
161
         * we need to pass the Flash player uri to GStreamer.
 
162
         * We do that by appending it to the stream uri.
 
163
         * (see the librtmp manual for more information) */
 
164
        // Example:
 
165
        // rtmp://artestras.fcod.llnwd.net/a3903/o35/MP4:geo/videothek/EUR_DE_FR/arteprod/A7_SGT_ENC_08_042143-002-A_PG_HQ_FR?h=d7878fae5c9726844d22da78e05f764e swfVfy=1 swfUrl=http://videos.arte.tv/blob/web/i18n/view/player_9-3188338-data-4807088.swf
 
166
        string stream_uri = rtmp_uri + " swfVfy=1 swfUrl=" + flash_player_uri;
 
167
        debug ("Build stream URI:\t\t'%s'", stream_uri);
 
168
 
 
169
        return stream_uri;
 
170
    }
 
171
}
 
172
 
 
173
public class ImageUrlExtractor : IndirectUrlExtractor, UrlExtractor
 
174
{
 
175
    public string get_url (VideoQuality q, Language lang, string page_url)
 
176
            throws ExtractionError
 
177
    {
 
178
        // takes a video page url and returns the image url
 
179
        // Example: <link rel="image_src" href="http://videos.arte.tv/image/web/i18n/view/ai_wei_wei_jpg_1-4008448-imageData-4966655,h,102,w,180.jpg"/>
 
180
        string regexp, image_url;
 
181
 
 
182
        regexp = "<link rel=\"image_src\" href=\"(http://.*.jpg)\"/>";
 
183
        image_url = extract_string_from_page (page_url, regexp);
 
184
 
 
185
        if (image_url == null)
 
186
            throw new ExtractionError.EXTRACTION_FAILED ("Image URL Extraction Error");
 
187
 
 
188
        return image_url;
 
189
    }
 
190
}