40
public interface Extractor : GLib.Object
42
public abstract string get_url (VideoQuality q, Language lang, string page_url)
43
throws ExtractionError;
46
public class StreamUrlExtractor : GLib.Object
48
protected Soup.SessionAsync session;
50
public StreamUrlExtractor()
52
session = create_session ();
55
protected string extract_string_from_page (string url, string regexp)
56
throws ExtractionError
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");
68
var regex = new Regex (regexp);
69
regex.match((string) msg.response_body.flatten ().data, 0, out match);
71
} catch (RegexError e) {
72
GLib.warning ("%s", e.message);
73
throw new ExtractionError.EXTRACTION_FAILED (e.message);
80
public class RTMPStreamUrlExtractor : StreamUrlExtractor, Extractor
82
public string get_url (VideoQuality q, Language lang, string page_url)
83
throws ExtractionError
86
GLib.debug ("Initial Page URL:\t\t%s", page_url);
88
/* Setup the language string */
89
string lang_str = "fr";
90
if (lang == Language.GERMAN)
93
/* Setup quality string */
94
string quali_str = "hd";
95
if (q == VideoQuality.WMV_MQ)
98
/* Get the Arte Flash player URI */
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");
107
/* Get the Flash XML data */
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);
115
throw new ExtractionError.EXTRACTION_FAILED ("Video URL Extraction Error");
117
/* Get the language specific flash XML data */
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);
126
throw new ExtractionError.EXTRACTION_FAILED ("Video URL Extraction Error");
128
/* Get the RTMP uri. */
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);
136
/* sometimes only one quality level is available */
137
if (rtmp_uri == null) {
138
if (q == VideoQuality.WMV_HQ) {
139
q = VideoQuality.WMV_MQ;
141
GLib.warning ("No high quality stream available. Fallback to medium quality.");
142
} else if (q == VideoQuality.WMV_MQ) {
143
q = VideoQuality.WMV_HQ;
145
GLib.warning ("No medium quality stream available. Fallback to high quality.");
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);
151
if (rtmp_uri == null)
152
throw new ExtractionError.STREAM_NOT_READY ("This video is not available yet");
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");
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) */
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);
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
178
public string get_url (VideoQuality q, Language lang, string page_url)
179
throws ExtractionError
182
GLib.debug ("Initial Page URL:\t\t%s", page_url);
184
/* Setup the language string */
185
string lang_str = "fr";
186
if (lang == Language.GERMAN)
189
/* Get the Flash XML data */
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);
197
throw new ExtractionError.EXTRACTION_FAILED ("Video URL Extraction Error");
199
/* Get the language specific flash XML data */
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);
208
throw new ExtractionError.EXTRACTION_FAILED ("Video URL Extraction Error");
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);
218
/* Extract the real url */
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&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);
40
public interface UrlExtractor : GLib.Object
42
public abstract string get_url (VideoQuality q, Language lang, string page_url)
43
throws ExtractionError;
46
public class IndirectUrlExtractor : GLib.Object
48
protected Soup.SessionAsync session;
50
public IndirectUrlExtractor()
52
session = create_session ();
55
protected string extract_string_from_page (string url, string regexp)
56
throws ExtractionError
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");
68
var regex = new Regex (regexp);
69
regex.match((string) msg.response_body.flatten ().data, 0, out match);
71
} catch (RegexError e) {
72
GLib.warning ("%s", e.message);
73
throw new ExtractionError.EXTRACTION_FAILED (e.message);
80
public class RTMPStreamUrlExtractor : IndirectUrlExtractor, UrlExtractor
82
public string get_url (VideoQuality q, Language lang, string page_url)
83
throws ExtractionError
86
debug ("Initial Page URL:\t\t'%s'", page_url);
88
/* Setup the language string */
89
string lang_str = "fr";
90
if (lang == Language.GERMAN)
93
/* Setup quality string */
94
string quali_str = "hd";
95
if (q == VideoQuality.MEDIUM)
98
/* Get the Arte Flash player URI */
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");
107
/* Get the Flash XML data */
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);
115
throw new ExtractionError.EXTRACTION_FAILED ("Video URL Extraction Error");
117
/* Get the language specific flash XML data */
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);
126
throw new ExtractionError.EXTRACTION_FAILED ("Video URL Extraction Error");
128
/* Get the RTMP uri. */
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);
136
/* sometimes only one quality level is available */
137
if (rtmp_uri == null) {
138
if (q == VideoQuality.HIGH) {
139
q = VideoQuality.MEDIUM;
141
GLib.warning ("No high quality stream available. Fallback to medium quality.");
142
} else if (q == VideoQuality.MEDIUM) {
143
q = VideoQuality.HIGH;
145
GLib.warning ("No medium quality stream available. Fallback to high quality.");
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);
151
if (rtmp_uri == null)
152
throw new ExtractionError.STREAM_NOT_READY ("This video is not available yet");
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");
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) */
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);
173
public class ImageUrlExtractor : IndirectUrlExtractor, UrlExtractor
175
public string get_url (VideoQuality q, Language lang, string page_url)
176
throws ExtractionError
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;
182
regexp = "<link rel=\"image_src\" href=\"(http://.*.jpg)\"/>";
183
image_url = extract_string_from_page (page_url, regexp);
185
if (image_url == null)
186
throw new ExtractionError.EXTRACTION_FAILED ("Image URL Extraction Error");