Skip to content

Commit a22ad08

Browse files
author
LiuLang
committed
tucao.cc added
1 parent 9e8ce97 commit a22ad08

File tree

4 files changed

+340
-2
lines changed

4 files changed

+340
-2
lines changed

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ netease
8787
=======
8888
这个能工作, 也可以用来下载公开课等.
8989

90+
tucao
91+
=====
92+
tucao.cc, 主要收录了一些二次元动画, 还有弹幕功能. 它主要使用了新浪的视频.
9093

9194
tudou
9295
=====

funshion/funshionHTML5.user.js

-2
Original file line numberDiff line numberDiff line change
@@ -398,8 +398,6 @@ var funshion = {
398398
div.insertBefore(parent, div.children[0]);
399399
},
400400

401-
402-
403401
/**
404402
* Create a new <style> tag with str as its content.
405403
* @param string styleText

tucao/tucao.cc-data

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
2+
原始地址:
3+
http://www.tucao.cc/play/h4021653/
4+
5+
来倒着查找:
6+
7+
最终的视频地址:
8+
46.2M
9+
http://61.158.251.172/6/edge.v.iask.com/118522052.hlv?KID=sina,viask&Expires=1384012800&ssig=uIj25wPxmw
10+
46.2M
11+
http://61.158.251.171/edge.v.iask.com/118522052.hlv?KID=sina,viask&Expires=1384012800&ssig=uIj25wPxmw
12+
46.2M
13+
http://edge.v.iask.com/118522052.hlv?KID=sina,viask&Expires=1384012800&ssig=uIj25wPxmw
14+
15+
获取视频地址的API, 得到的是一个XML文件. 这个视频是存放在sina的服务器上的, 并且在新浪视频也可以播放:
16+
http://www.tucao.cc/api/sina.php?vid=118519519
17+
这里的vid是..
18+
19+
这个是获取用户tucao的:
20+
http://www.tucao.cc/index.php?m=mukio&c=index&a=init&playerID=11-4021653-1-0&r=828
21+
22+
这个是获取tucao服务器地址, 包括广告地址:
23+
http://www.tucao.cc/conf.xml
24+
25+
解析原始的网页:
26+
http://www.tucao.cc/play/h4021653/
27+
<ul id="player_code"></ul>
28+
这里面放着两个<li>, 它们的内容分别是vid和playerID. 前者用于获取视频地址, 后者用于获取用户tucao的信息.
29+
30+
<li>type=sina&vid=118519519</li>这里, 可以看到, 是要用sina.php来得到视频地址.
31+
但要注意, 如果是一个集合(专辑)的话, 里面会放有好多数据, 比如这个地址:http://www.tucao.cc/play/h4021435/. 不同集之间以**作为分隔符. 并且, 还有每一集的标题, 以|分隔.
32+
如果是合集的话, 可以在URL中加入#5, 这会跳到第5集(从1开始计数).
33+
34+
35+
其它网站, 比如youku等的视频接口还没遇到过, 这个以后再加入.
36+
37+
youku========
38+
原始地址:http://www.tucao.cc/play/h4018460/
39+
获取视频地址:
40+
http://www.tucao.cc/api/youku.php?id=XNjEwOTUwNzE2
41+
这个可以根据id构造出原始的youku的地址.
42+
43+
tudou====
44+
与youku类似, 也可以构造出原始的url地址.
45+
http://www.tudou.com/programs/view/24JRFPvKiC4/

tucao/tucao.user.js

+292
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
1+
// ==UserScript==
2+
// @name tucaoHTML5
3+
// @version 1.0
4+
// @include http://www.tucao.cc/play/*
5+
// @description Get video links in tucao.cc
6+
// @author LiuLang
7+
8+
// @license GPLv3
9+
// @grant GM_xmlhttpRequest
10+
// @run-at document-end
11+
// ==/UserScript==
12+
13+
/**
14+
* v1.0 - 2013.11.8
15+
* Project inited.
16+
*/
17+
18+
var uw = unsafeWindow,
19+
log = uw.console.log,
20+
error = uw.console.error;
21+
22+
var tucao = {
23+
24+
run: function() {
25+
log('run()');
26+
this.init();
27+
this.createPanel();
28+
this.getVid();
29+
if (this.vids.length === 0) {
30+
error('Failed to get Vid!');
31+
return false;
32+
}
33+
this.getTitle();
34+
log(this);
35+
this.getUrl();
36+
},
37+
38+
init: function() {
39+
log('init()');
40+
var oldDiv = uw.document.querySelector('.download-wrap');
41+
42+
if (oldDiv) {
43+
uw.document.body.removeChild(oldDiv);
44+
}
45+
this.url = '';
46+
this.playerId = '';
47+
this.title = '';
48+
this.vid = '';
49+
this.vids = [];
50+
this.pos = 0;
51+
this.videos = [];
52+
this.types = {
53+
sina: 'sina.php',
54+
tudou: false,
55+
youku: false,
56+
};
57+
},
58+
59+
getVid: function() {
60+
log('getVid() -- ');
61+
var playerCode = uw.document.querySelectorAll('ul#player_code li');
62+
63+
if (playerCode.length === 2) {
64+
this.vids = playerCode[0].firstChild.nodeValue.split('**');
65+
if (this.vids[this.vids.length - 1] == '') {
66+
this.vids.pop();
67+
}
68+
this.playerId = playerCode[1].innerHTML;
69+
}
70+
},
71+
72+
getTitle: function() {
73+
log('getTitle()');
74+
75+
if (this.vids.length === 1 || uw.location.hash === '') {
76+
this.pos = 0;
77+
this.url = uw.location.href;
78+
} else {
79+
// hash starts with 1, not 0
80+
this.pos = parseInt(uw.location.hash.replace('#', '')) - 1;
81+
this.url = uw.location.href.replace(uw.location.hash, '');
82+
}
83+
this.vid = this.vids[this.pos].split('|')[0];
84+
if (this.vids.length === 1) {
85+
this.title = uw.document.title.substr(0, uw.document.title.length - 16);
86+
} else {
87+
this.title = this.vids[this.pos].split('|')[1];
88+
}
89+
},
90+
91+
getUrl: function(type) {
92+
log('getUrl()');
93+
var url,
94+
params,
95+
that = this;
96+
97+
params = this.getQueryVariable(this.vid);
98+
if (this.types[params.type] === false) {
99+
this.redirect(params);
100+
return false;
101+
}
102+
103+
url = [
104+
'http://www.tucao.cc/api/',
105+
this.types[params.type],
106+
'?vid=',
107+
params.vid,
108+
].join('');
109+
110+
log('url: ', url);
111+
GM_xmlhttpRequest({
112+
method: 'GET',
113+
url: url,
114+
onload: function(response) {
115+
log(response);
116+
var xml = that.parseXML(response.responseText),
117+
durl = xml.querySelector('durl'),
118+
urls = durl.querySelectorAll('url'),
119+
url,
120+
i;
121+
122+
for (i = 0; url = urls[i]; i += 1) {
123+
that.videos.push(
124+
url.innerHTML.replace('<![CDATA[', '').replace(']]>', ''));
125+
}
126+
127+
log(that);
128+
that.appendVideos();
129+
},
130+
});
131+
},
132+
133+
redirect: function(params) {
134+
log('redirect()');
135+
var urls = {
136+
tudou: function(vid) {
137+
return 'http://www.tudou.com/programs/view/' + vid + '/';
138+
},
139+
youku: function(vid) {
140+
return 'http://v.youku.com/v_show/id_' + vid + '.html';
141+
},
142+
},
143+
url,
144+
div = uw.document.querySelector('.download-wrap'),
145+
a;
146+
147+
url = urls[params.type](params.vid);
148+
log('url: ', url);
149+
150+
a = uw.document.createElement('a');
151+
a.href = url;
152+
a.innerHTML = url;
153+
a.className = 'download-link';
154+
div.appendChild(a);
155+
},
156+
157+
createPanel: function() {
158+
log('createPanel() --');
159+
var div = uw.document.createElement('div');
160+
161+
this.addStyle([
162+
'.download-wrap { ',
163+
'position: fixed; ',
164+
'left: 10px; ',
165+
'bottom: 10px; ',
166+
'border: 2px solid #ccc; ',
167+
'border-top-right-radius: 15px; ',
168+
'margin; 0; ',
169+
'padding: 10px; ',
170+
'background-color: #fff; ',
171+
'z-index: 9999; ',
172+
'}',
173+
'.download-pager {',
174+
'pading-bottom: 10px;',
175+
'}',
176+
'.download-pager a {',
177+
//'padding: 10px; ',
178+
'display: block; ',
179+
'}',
180+
'.download-link { ',
181+
'clear: both;',
182+
'display: block;',
183+
'}',
184+
'.download-link:hover { ',
185+
'text-decoration: underline; ',
186+
'}',
187+
'.download-link:active {',
188+
'color: #e03434; ',
189+
'outline: none; ',
190+
'}',
191+
].join(''));
192+
div.className = 'download-wrap';
193+
uw.document.body.appendChild(div);
194+
},
195+
196+
appendVideos: function() {
197+
log('appendVideos()');
198+
var div = uw.document.querySelector('.download-wrap'),
199+
pager = uw.document.createElement('div'),
200+
video,
201+
i,
202+
a;
203+
204+
pager.className = 'download-pager';
205+
div.appendChild(pager);
206+
207+
if (this.vids.length > 1) {
208+
if (this.pos > 0) {
209+
// show prev page.
210+
a = uw.document.createElement('a');
211+
a.innerHTML = '上一集';
212+
a.href = this.url + '#' + String(this.pos);
213+
a.style.cssFloat = 'left';
214+
pager.appendChild(a);
215+
}
216+
if (this.pos < this.vids.length - 1) {
217+
// show next page.
218+
a = uw.document.createElement('a');
219+
a.innerHTML = '下一集';
220+
a.href = this.url + '#' + String(this.pos + 2);
221+
a.style.cssFloat = 'right';
222+
pager.appendChild(a);
223+
}
224+
}
225+
226+
for (i = 0; video = this.videos[i]; i += 1) {
227+
a = uw.document.createElement('a');
228+
a.href = video;
229+
if (this.videos.length === 1) {
230+
a.innerHTML = this.title;
231+
} else if (this.videos.length > 9 && i < 9) {
232+
a.innerHTML = this.title + '-(0' + String(i) + ')';
233+
} else {
234+
a.innerHTML = this.title + '-(' + i + ')';
235+
}
236+
a.className = 'download-link';
237+
div.appendChild(a);
238+
}
239+
},
240+
241+
/**
242+
* Create a new <style> tag with str as its content.
243+
* @param string styleText
244+
* - The <style> tag content.
245+
*/
246+
addStyle: function(styleText) {
247+
var style = uw.document.createElement('style');
248+
if (uw.document.head) {
249+
uw.document.head.appendChild(style);
250+
style.innerHTML = styleText;
251+
}
252+
},
253+
254+
/**
255+
* Convert string to xml
256+
* @param string str
257+
* - the string to be converted.
258+
* @return object xml
259+
* - the converted xml object.
260+
*/
261+
parseXML: function(str) {
262+
if (uw.document.implementation &&
263+
uw.document.implementation.createDocument) {
264+
xmlDoc = new DOMParser().parseFromString(str, 'text/xml');
265+
} else {
266+
log('parseXML() error: not support current web browser!');
267+
return null;
268+
}
269+
return xmlDoc;
270+
},
271+
272+
getQueryVariable: function(query) {
273+
var vars = query.split('&'),
274+
params = {},
275+
param,
276+
i;
277+
278+
for (i = 0; i < vars.length; i += 1) {
279+
param = vars[i].split('=');
280+
params[param[0]] = param[1];
281+
}
282+
return params;
283+
},
284+
}
285+
286+
uw.addEventListener('hashchange', function() {
287+
tucao.run();
288+
}, false);
289+
//uw.onhashchange = function() {
290+
// tucao.run();
291+
//};
292+
tucao.run();

0 commit comments

Comments
 (0)