ytb.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. String.prototype.rstrip = function (chars) {
  2. let regex = new RegExp(chars + "$");
  3. return this.replace(regex, "");
  4. };
  5. const request_timeout = 5000;
  6. const VERSION = 'YouTube';
  7. const UA = 'Mozilla/5.0'; //默认请求ua
  8. const __ext = {data_dict:{}};
  9. const tips = `\n${VERSION}`;
  10. const def_pic = 'https://www.youtube.com/img/desktop/yt_1200.png';
  11. function print(any){
  12. any = any||'';
  13. if(typeof(any)=='object'&&Object.keys(any).length>0){
  14. try {
  15. any = JSON.stringify(any);
  16. console.log(any);
  17. }catch (e) {
  18. console.log(typeof(any)+':'+any.length);
  19. }
  20. }else if(typeof(any)=='object'&&Object.keys(any).length<1){
  21. console.log('null object');
  22. }else{
  23. console.log(any);
  24. }
  25. }
  26. function getHome(url){
  27. if(!url){
  28. return ''
  29. }
  30. let tmp = url.split('//');
  31. url = tmp[0] + '//' + tmp[1].split('/')[0];
  32. try {
  33. url = decodeURIComponent(url);
  34. }catch (e) {}
  35. return url
  36. }
  37. const http = function (url, options = {}) {
  38. if(options.method ==='POST' && options.data){
  39. options.body = JSON.stringify(options.data);
  40. options.headers = Object.assign({'content-type':'application/json'}, options.headers);
  41. }
  42. options.timeout = request_timeout;
  43. if(!options.headers){
  44. options.headers = {};
  45. }
  46. let keys = Object.keys(options.headers).map(it=>it.toLowerCase());
  47. if(!keys.includes('referer')){
  48. options.headers['Referer'] = getHome(url);
  49. }
  50. if(!keys.includes('user-agent')){
  51. options.headers['User-Agent'] = UA;
  52. }
  53. console.log(JSON.stringify(options.headers));
  54. try {
  55. const res = req(url, options);
  56. res.json = () => res&&res.content ? JSON.parse(res.content) : null;
  57. res.text = () => res&&res.content ? res.content:'';
  58. return res
  59. }catch (e) {
  60. return {
  61. json() {
  62. return null
  63. }, text() {
  64. return ''
  65. }
  66. }
  67. }
  68. };
  69. ["get", "post"].forEach(method => {
  70. http[method] = function (url, options = {}) {
  71. return http(url, Object.assign(options, {method: method.toUpperCase()}));
  72. }
  73. });
  74. function init(ext) {
  75. console.log(":"+VERSION);
  76. let data;
  77. if (typeof ext == 'object'){
  78. data = ext;
  79. print('live ext:object');
  80. } else if (typeof ext == 'string') {
  81. if (ext.startsWith('http')) {
  82. let ext_paramas = ext.split(';');
  83. let data_url = ext_paramas[0];
  84. print(data_url);
  85. data = http.get(data_url).json();
  86. }
  87. }
  88. print(data);
  89. __ext.data = data;
  90. print('init执行完毕');
  91. }
  92. function home(filter) {
  93. let classes = __ext.data.map(it => ({
  94. type_id: it.url,
  95. type_name: it.name,
  96. }));
  97. print("----home----");
  98. print(classes);
  99. return JSON.stringify({ 'class': classes});
  100. }
  101. function homeVod(params) {
  102. let _get_url = __ext.data[0].url;
  103. let html = http.get(_get_url).text();
  104. let arr = html.match(/.*?,#[\s\S].*?#/g);
  105. let _list = [];
  106. try {
  107. arr.forEach(it=>{
  108. _list.push({
  109. vod_name:it.split(',')[0],
  110. vod_id:_get_url+'$'+it.split(',')[0],
  111. vod_pic:def_pic,
  112. vod_remarks:it.split(',')[1],
  113. });
  114. });
  115. }catch (e) {
  116. print('Live2cms获取首页推荐发送错误:'+e.message);
  117. }
  118. return JSON.stringify({ 'list': _list });
  119. }
  120. function category(tid, pg, filter, extend) {
  121. let _get_url = tid;
  122. let html;
  123. if(__ext.data_dict[_get_url]){
  124. html = __ext.data_dict[_get_url];
  125. }else{
  126. html = http.get(_get_url).text();
  127. __ext.data_dict[_get_url] = html;
  128. }
  129. let arr = html.match(/.*?,#[\s\S].*?#/g);
  130. let _list = [];
  131. try {
  132. arr.forEach(it=>{
  133. _list.push({
  134. vod_name:it.split(',')[0],
  135. vod_id:_get_url+'$'+it.split(',')[0],
  136. vod_pic:def_pic,
  137. vod_remarks:it.split(',')[1],
  138. });
  139. });
  140. }catch (e) {
  141. print('Live2cms获取一级分类页发生错误:'+e.message);
  142. }
  143. return JSON.stringify({
  144. 'page': 1,
  145. 'pagecount': 1,
  146. 'limit': _list.length,
  147. 'total': _list.length,
  148. 'list': _list,
  149. });
  150. }
  151. function detail(tid) {
  152. let _get_url = tid.split('$')[0];
  153. let _tab = tid.split('$')[1];
  154. if(tid.includes('#search#')){
  155. let vod_play_url = _tab.replace('#search#','')+'$'+_get_url;
  156. print(vod_play_url);
  157. return JSON.stringify({
  158. list: [{
  159. vod_id: tid,
  160. vod_name: '搜索:'+_tab.replace('#search#',''),
  161. type_name: "YouTube列表",
  162. vod_pic: def_pic,
  163. vod_content: tid,
  164. vod_play_from: '来自搜索',
  165. vod_play_url: vod_play_url,
  166. vod_director: tips,
  167. vod_remarks: `YouTube${VERSION}`,
  168. }]
  169. });
  170. }
  171. let html;
  172. if(__ext.data_dict[_get_url]){
  173. html = __ext.data_dict[_get_url];
  174. }else{
  175. html = http.get(_get_url).text();
  176. __ext.data_dict[_get_url] = html;
  177. }
  178. let a = new RegExp(`.*?${_tab},#[\\s\\S].*?#`);
  179. let b = html.match(a)[0];
  180. let c = html.split(b)[1];
  181. if(c.match(/.*?,#[\s\S].*?#/)){
  182. let d = c.match(/.*?,#[\s\S].*?#/)[0];
  183. c = c.split(d)[0];
  184. }
  185. let arr = c.trim().split('\n');
  186. let _list = [];
  187. arr.forEach((it)=>{
  188. if(it.trim()){
  189. let t = it.trim().split(',')[0];
  190. let u = it.trim().split(',')[1];
  191. _list.push(t+'$'+u);
  192. }
  193. });
  194. let vod_name = __ext.data.find(x=>x.url===_get_url).name;
  195. let vod_play_url = _list.join('#');
  196. let vod = {
  197. vod_id: tid,
  198. vod_name: vod_name+'|'+_tab,
  199. type_name: "YouTube列表",
  200. vod_pic: def_pic,
  201. vod_content: tid,
  202. vod_play_from: vod_name,
  203. vod_play_url: vod_play_url,
  204. vod_director: tips,
  205. vod_remarks: `${VERSION}`,
  206. };
  207. return JSON.stringify({
  208. list: [vod]
  209. });
  210. }
  211. function play(flag, id, flags) {
  212. let vod = {
  213. 'parse': /m3u8/.test(id)?0:1,
  214. 'playUrl': '',
  215. 'url': id
  216. };
  217. print(vod);
  218. return JSON.stringify(vod);
  219. }
  220. function search(wd, quick) {
  221. let _get_url = __ext.data[0].url;
  222. let html;
  223. if(__ext.data_dict[_get_url]){
  224. html = __ext.data_dict[_get_url];
  225. }else{
  226. html = http.get(_get_url).text();
  227. __ext.data_dict[_get_url] = html;
  228. }
  229. let str='';
  230. Object.keys(__ext.data_dict).forEach(()=>{
  231. str+=__ext.data_dict[_get_url];
  232. });
  233. let links = str.split('\n').filter(it=>it.trim() && it.includes(','));
  234. links = links.map(it=>it.trim());
  235. let plays = Array.from(new Set(links));
  236. print('搜索关键词:'+wd);
  237. print('过滤前:'+plays.length);
  238. plays = plays.filter(it=>it.includes(wd));
  239. print('过滤后:'+plays.length);
  240. print(plays);
  241. let _list = [];
  242. plays.forEach((it)=>{
  243. _list.push({
  244. 'vod_name':it.split(',')[0],
  245. 'vod_id':it.split(',')[1].trim()+'$'+it.split(',')[0].trim()+'#search#',
  246. 'vod_pic':def_pic,
  247. })
  248. });
  249. return JSON.stringify({
  250. 'list': _list
  251. });
  252. }
  253. export default {
  254. init: init,
  255. home: home,
  256. homeVod: homeVod,
  257. category: category,
  258. detail: detail,
  259. play: play,
  260. search: search
  261. }