Version up
[raitv.user.js] / raitv.user.js
1 // ==UserScript==
2 // @name        RaiTV video
3 // @description Turn RaiTV silverlight objects into video tags
4 // @namespace   http://oblomov.myopenid.com
5 // @include     http://rai.tv/*
6 // @include     http://rai.it/*
7 // @include     http://www.rai.tv/*
8 // @include     http://www.rai.it/*
9 // @include     http://archivioluce.com/*
10 // @include     http://www.archivioluce.com/*
11 // @author      Giuseppe "Oblomov" Bilotta
12 // @version     20130607.2301
13 // ==/UserScript==
14
15 /* Since the Chrome sandbox is _extremely_ restrictive and we can't
16  * access things such as window.videoURL from the actual document,
17  * we have to resort to script injection to be completely cross-platform.
18  */
19
20 (function() {
21
22 function addScript(source) {
23         var script = document.createElement('script');
24         script.setAttribute("type", "application/javascript");
25         script.textContent = '(' + source + ')();';
26         document.body.appendChild(script);
27 }
28
29
30 addScript(
31 function() {
32
33         function getURL(name) {
34                 var list = document.getElementsByName(name) ;
35                 if (list && list[0]) {
36                         return list[0].content;
37                 } else {
38                         var altname = name.toUpperCase().replace('VIDEO','video');
39                         console.log(name, altname);
40                         console.log(window[name], window[altname]);
41                         return window[altname];
42                 }
43         }
44
45         var urls = {
46                 std: getURL('videourl'),
47                 mp4: getURL('videourl_mp4'),
48                 wmv: getURL('videourl_wmv'),
49                 h264: getURL('videourl_h264'),
50                 m3u8: getURL('videourl_m3u8'),
51         }
52
53         function srctag(url, av, fmt) {
54                 if (!url)
55                         return '' ;
56                 return '<source src="' + url + '" ' + (fmt ? 'type="' + av + '/' + fmt + '" ' : '') + '/>'
57         }
58
59         function H5video(fmt) {
60                 return srctag(urls[fmt], 'video', (fmt == 'std' ? null : fmt));
61         }
62
63         // create a link element for one of the page-wide media streams
64         function H5a(fmt) {
65                 if (urls[fmt]) {
66                         var a = document.createElement('a');
67                         a.href = urls[fmt];
68                         a.innerHTML = fmt.toUpperCase();
69                         a.setAttribute('style', 'font-weight:bold;margin-left:1em;color:white');
70                         return a;
71                 }
72                 return null
73         }
74
75         // create a link element for a raw URL
76         function H5aRaw(name, url) {
77                 if (url) {
78                         var a = document.createElement('a');
79                         a.href = url;
80                         a.innerHTML = name.toUpperCase();
81                         a.setAttribute('style', 'font-weight:bold;margin-left:1em;color:red');
82                         return a;
83                 }
84                 return null
85         }
86
87         var streamlist = document.createElement("li");
88
89         // reset stream list: this is used in the playTg and playAudio
90         // functions to reset the stream list when changing stream,
91         function slReset() {
92                 streamlist.innerHTML = '<span>Stream/Download:</span>';
93         }
94         // and of course once at the beginning of it all 8-)
95         slReset();
96
97         var sch = document.getElementById("silverlightControlHost");
98         if (sch) {
99                 // debug
100                 console.log(urls);
101
102                 // find place to append the stream list to
103                 // if possible, look for an existing ul in what is likely to be the top
104                 // otherwise, create an ul and put it either in a miniLink if available,
105                 // or the top otherwise
106                 // TODO use some smarter mechanism
107                 var pp = sch.parentNode.parentNode.previousElementSibling;
108                 var specs = pp.getElementsByTagName('ul');
109                 if (!specs || !specs[0]) {
110                         specs = document.createElement('ul');
111                         specs.className = 'Specifiche';
112                         var mid = document.getElementById('Notizie');
113                         if (mid) {
114                                 mid = mid.lastElementChild;
115                                 mid.insertBefore(specs, mid.firstElementChild);
116                         } else {
117                                 pp.appendChild(specs);
118                         }
119                 } else {
120                         specs = specs[0];
121                 }
122                 specs.appendChild(streamlist);
123                 console.log(streamlist, 'appended');
124
125                 // if we are on a page that defines the videourl* metas, go straight to creating
126                 // the video element
127                 if (urls.std) {
128                         // prevent other JS with messing with this element further
129                         sch.id = 'html5mediaHost';
130                         sch.innerHTML = "<video style='width:100%; height:100%' controls>" +
131                                 H5video('mp4') + H5video('wmv') +
132                                 H5video('h264') + H5video('m3u8') +
133                                 H5video('std') +
134                                 "<h3>Sorry, no supported video format found :-(</h3></video>";
135                         console.log(sch, 'hacked');
136
137                         for (var fmt in urls) {
138                                 var a = H5a(fmt);
139                                 if (a)
140                                         streamlist.appendChild(a);
141                         }
142                         return; // done
143                 }
144
145                 // hack the play* JS functions
146                 if (window.playTg) {
147                         window.playTg = function (liveTg, video, h264, androidUrl) {
148                                 var dataP = new Date();
149                                 var ggP, mmP, aaaaP;
150                                 ggP = dataP.getDate() + "-";
151                                 mmP = dataP.getMonth() + 1 + "-";
152                                 aaaaP = 1900 + dataP.getYear();
153
154                                 // prevent page from refreshing, the site only checks for
155                                 // the existence of object/embed, not audio/video
156                                 window.refreshByJS = false;
157
158                                 // stop loading any current audio/video
159                                 if (sch.firstChild && sch.firstChild.src) {
160                                         console.log('stopping current A/V');
161                                         sch.firstChild.src = '';
162                                 }
163
164                                 // re-create the video player
165                                 sch.innerHTML = "<video width='258' height='195' controls autoplay>" +
166                                         srctag(h264, 'video') +
167                                         srctag(androidUrl, 'video') +
168                                         srctag(video, 'video') +
169                                         "<h3>Sorry, no supported video format found :-(</h3></video>";
170
171                                 // re-create stream list
172                                 slReset();
173                                 // oh we would like to indicate the media type somehow,
174                                 // but it seems to be somewhat random. Not even a HEAD
175                                 // on the URL works reliably all the time
176                                 var a = H5aRaw('1', h264);
177                                 if (a)
178                                         streamlist.appendChild(a);
179                                 if (androidUrl != h264) {
180                                         a = H5aRaw('2', androidUrl);
181                                         if (a)
182                                                 streamlist.appendChild(a);
183                                 }
184                                 if ((video != androidUrl) && (video != h264)) {
185                                         a = H5aRaw('3', video);
186                                         if (a)
187                                                 streamlist.appendChild(a);
188                                 }
189
190                                 setNielsen(location.href + '&video=' + liveTg + '&data=' + ggP + mmP + aaaaP + '', true);
191                                 console.log('playTg', liveTg, video, h264, androidUrl)
192                         }
193                         console.log('playTg hacked');
194                 }
195
196                 if (window.playAudio) {
197                         window.playAudio = function (grrEdizione, mediaUrl, mediatype) {
198                                 var dataP = new Date();
199                                 var ggP, mmP, aaaaP;
200                                 ggP = dataP.getDate() + "-";
201                                 mmP = dataP.getMonth() + 1 + "-";
202                                 aaaaP = 1900 + dataP.getYear();
203
204                                 // prevent page from refreshing, the site only checks for
205                                 // the existence of object/embed, not audio/video
206                                 window.refreshByJS = false;
207
208                                 // stop loading any current audio/video
209                                 if (sch.firstChild && sch.firstChild.src) {
210                                         console.log('stopping current A/V');
211                                         sch.firstChild.src = '';
212                                 }
213
214                                 // re-create the audio player
215                                 sch.innerHTML = "<audio width='258' height='35' controls autoplay>" +
216                                         srctag(mediaUrl, 'audio') +
217                                         "<h3>Sorry, no supported audio format found :-(</h3></audio>";
218
219                                 // re-create stream list
220                                 slReset();
221                                 var a = H5aRaw(mediatype ? mediatype : '(???)', mediaUrl);
222                                 if (a)
223                                         streamlist.appendChild(a);
224
225                                 setNielsen(location.href + '&audio=' + grrEdizione + '&data=' + ggP + mmP + aaaaP + '', true);
226                                 console.log('playAudio', grrEdizione, mediaUrl, mediatype);
227                         }
228                         console.log('playAudio hacked');
229                 }
230         }
231
232         // Archivio Luce
233         if (window.ply  && window.ply.configuration
234                         && window.ply.configuration.file
235                         && window.cnt) {
236                 var src = window.ply.configuration.file.replace(/^mms:\/\//,'http://');
237                 var width = window.ply.configuration.width;
238                 var height = window.ply.configuration.height;
239
240                 window.cnt.innerHTML = "<video style='width:" + width +
241                                         "px; height:" + height + "' controls autostart>" +
242                                         srctag(src, 'video', null) +
243                                         "</video>";
244                 console.log(window.cnt, 'hacked');
245                 window.cnt.appendChild(H5aRaw("WMV", src));
246         }
247 })
248
249 })();