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