低端影视解析

解析低端影视to=>m3u8

目前為 2021-03-05 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name 低端影视解析
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1
  5. // @description 解析低端影视to=>m3u8
  6. // @author ZainCheung
  7. // @match https://ddrk.me/*
  8. // @match https://ddys.tv/*
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15. /* global _wpmejsSettings, MediaElementPlayer */
  16.  
  17. (function ($, _, Backbone) {
  18. 'use strict';
  19.  
  20. function download(filename, text) {
  21. var element = document.createElement('a');
  22. element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
  23. element.setAttribute('download', filename);
  24.  
  25. element.style.display = 'none';
  26. document.body.appendChild(element);
  27.  
  28. element.click();
  29.  
  30. document.body.removeChild(element);
  31. }
  32.  
  33. /** @namespace wp */
  34. window.wp = window.wp || {};
  35.  
  36. var myPlayer,vjsoptions,SrcType,timerId=-1;
  37. const zimuOss = "https://ddrk.oss-accelerate.aliyuncs.com";
  38.  
  39. var videoServer;
  40. if (Math.random() >= 0.4) {
  41. videoServer = "https://v3.ddrk.me";
  42. }
  43. else {
  44. videoServer = "https://v2.ddrk.me";
  45. }
  46. if (document.domain == 'ddys.tv') videoServer = "https://v.ddys.tv";
  47.  
  48. var playlistDiv = $("div.wp-video-playlist");
  49. if (!deviceInfoQJ) window.deviceInfoQJ = new UAParser();
  50. var WPPlaylistView = Backbone.View.extend({
  51. initialize : function (options) {
  52. this.index = 0;
  53. this.settings = {};
  54. this.data = options.metadata || $.parseJSON( this.$('script.wp-playlist-script').html() );
  55. this.playerNode = this.$( this.data.type );
  56.  
  57. this.tracks = new Backbone.Collection( this.data.tracks );
  58. this.current = this.tracks.first();
  59.  
  60. if ( 'audio' === this.data.type ) {
  61. this.currentTemplate = wp.template( 'wp-playlist-current-item' );
  62. this.currentNode = this.$( '.wp-playlist-current-item' );
  63. }
  64.  
  65. this.renderCurrent();
  66.  
  67. if ( this.data.tracklist ) {
  68. this.itemTemplate = wp.template( 'wp-playlist-item' );
  69. this.playingClass = 'wp-playlist-playing';
  70. this.renderTracks();
  71. }
  72.  
  73. _.bindAll( this, /* 'bindPlayer', 'bindResetPlayer', 'setPlayer', 'ended', */ 'clickTrack' );
  74.  
  75. if ( ! _.isUndefined( window._wpmejsSettings ) ) {
  76. this.settings = _.clone( _wpmejsSettings );
  77. }
  78. //this.settings.success = this.bindPlayer;
  79. if (myPlayer) {
  80. myPlayer.dispose();
  81. playlistDiv[0].innerHTML='<video id="vjsp" class="video-js vjs-default-skin vjs-big-play-centered vjs-fluid vjs-playback-rate" controls="controls" x5-playsinline="" preload="none" webkit-playsinline playsinline></video>'+playlistDiv[0].innerHTML;
  82. }
  83. //$.ajaxSetup({xhrFields: { withCredentials: true } });
  84. this.setPlayer();
  85. },
  86.  
  87. setPlayer: function (force) {
  88. function GetQueryString(name) {
  89. var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
  90. var r = window.location.search.substr(1).match(reg);
  91. var context = "";
  92. if (r != null)
  93. context = r[2];
  94. reg = null;
  95. r = null;
  96. return context == null || context == "" || context == "undefined" ? "" : context;
  97. }
  98. var videoep = parseInt(GetQueryString("ep"));
  99. var nosub = parseInt(GetQueryString("nosub"));
  100.  
  101. if (!force) {
  102. if (1 <= videoep && videoep!=this.index+1 && videoep <= this.tracks.length) {
  103. this.index = videoep-1;
  104. this.current = this.tracks.at( this.index );
  105. if ( this.data.tracklist ) {
  106. this.$( '.wp-playlist-item' )
  107. .removeClass( this.playingClass )
  108. .eq( this.index )
  109. .addClass( this.playingClass );
  110. }
  111. }
  112.  
  113. videojs.addLanguage('zh-CN', {"The media could not be loaded, either because the server or network failed or because the format is not supported.": "没有获取到视频地址,请尝试稍后刷新本页",
  114. "Toggle theater mode":"网页全屏",
  115. "Quality":"画质",
  116. "subtitles off":"关闭",
  117. "subtitles settings":"设置"});
  118.  
  119. vjsoptions = {
  120. controlBar: {
  121. volumePanel: {inline: false}
  122. },
  123. userActions: {
  124. hotkeys: false,
  125. },
  126. language: 'zh-CN',
  127. playbackRates: [0.5, 1, 1.25, 1.5, 2],
  128. poster: "https://tvax1.sinaimg.cn/large/007Pu4zFly1gmq436gjlpj312c0lkmx1.jpg",
  129. };
  130. }
  131. else {
  132. window.history.replaceState(null, null, "?ep="+(this.index+1));
  133. videoep = parseInt(GetQueryString("ep"));
  134. }
  135.  
  136. var subtrackfull=this.current.get( 'subsrc' );
  137. var [subtracksrc,subshift]=subtrackfull.split(',');
  138. var haveVtt = false;
  139. var isiOS = (deviceInfoQJ.getOS().name == "iOS");
  140. var isAndroid = (deviceInfoQJ.getOS().name == "Android");
  141. var isAndroidQQ = isAndroid && /MQQBrowser/i.test(navigator.userAgent);
  142. //console.log(deviceInfoQJ.getResult());
  143. //console.log(subtracksrc);
  144.  
  145. const x5PlayerSet = () => {
  146. //myPlayer.usingNativeControls(true);
  147. var vjsp_html5=document.querySelector("#vjsp_html5_api");
  148. vjsp_html5.setAttribute("x5-video-player-type", "h5");
  149. vjsp_html5.setAttribute("x5-video-player-fullscreen", "true");
  150. vjsp_html5.setAttribute("x5-video-orientation", "landscape|portrait");
  151. //vjsp_html5_api.setAttribute("x5-playsinline", "");
  152. //$('#to_top_scrollup').remove();
  153. }
  154. $.ajax({
  155. url: zimuOss + subtracksrc,
  156. type: 'HEAD',
  157. error: function()
  158. {
  159. //
  160. },
  161. success: function()
  162. {
  163. haveVtt = true;
  164. if (isAndroidQQ) {
  165. x5PlayerSet();
  166. }
  167. }
  168. });
  169.  
  170. if (subshift==undefined) subshift = "0";
  171. var vttshift=this.current.get( 'vttshift' );
  172. if (vttshift==undefined) vttshift = 0;
  173. var portn=this.current.get('portn');
  174. var vtracksrc0=this.current.get( 'src0' );
  175. var vtracksrc=this.current.get( 'src1' );
  176. var vtracksrc2=this.current.get( 'src2' );
  177. var vtracksrc3=this.current.get( 'src3' );
  178.  
  179. if (window.vjs_list_SrcType != -1) SrcType = window.vjs_list_SrcType;
  180. else SrcType=this.current.get('srctype');
  181. //var [vtracksrc,vtrackStartTime]=vtracksrcfull.split(',');
  182. //if (vtrackStartTime==undefined) vtrackStartTime = "0";
  183. var userIP=this.current.get('userIP');
  184. var vdesc=this.current.get('description');
  185. var videoCutTime=this.current.get('cut');
  186. var VideoNotJump=true;
  187. if (videoCutTime == 0) VideoNotJump=false;
  188. var logdata = {
  189. action: 'is_user_logged_in'
  190. };
  191.  
  192. function oneTime(){
  193. let srvdate = new Date($.ajax({async: false}).getResponseHeader("Date"));
  194. let eTimes = srvdate.getTime() + 600000;
  195. let uTxt = CryptoJS.enc.Utf8.parse("{\"path\":\"" + vtracksrc0 + "\",\"expire\":" + eTimes.toString() + "}");
  196. let uKey = CryptoJS.enc.Utf8.parse("zevS%th@*8YWUm%K");
  197. let waiv = CryptoJS.enc.Utf8.parse("5080305495198718");
  198. var ttestvtrack = CryptoJS.AES.encrypt(uTxt,uKey,{
  199. iv: waiv,
  200. mode: CryptoJS.mode.CBC
  201. });
  202. vtracksrc = encodeURIComponent(ttestvtrack.ciphertext.toString(CryptoJS.enc.Base64));
  203. }
  204. setTimeout(oneTime, 1);
  205.  
  206. const videoPlayHandler = () => {
  207. if (myPlayer.src() == '') {
  208. myPlayer.bigPlayButton.hide();
  209. if (SrcType == 0 || SrcType == 3 ) {
  210. if (isAndroid) {
  211. myPlayer.src({src: videoServer+':'+'9543'+'/video?id='+vtracksrc+'&type=hls&ee=a.m3u8', type: 'application/x-mpegURL'});
  212. }
  213. else if (isiOS || deviceInfoQJ.getOS().name == 'Mac OS') {
  214. $.get(videoServer+':'+'9543'+'/video?id='+vtracksrc+'&type=mix',function(data) {
  215. var pint = pako.ungzip(data.pin,{to:'string'});
  216. var bpstr = 'data:application/vnd.apple.mpegurl;base64,' + btoa(pint);
  217. myPlayer.src({src: bpstr, type: 'application/vnd.apple.mpegurl'});
  218. });
  219. //myPlayer.src({src: videoServer+':'+'9543'+'/video?id='+vtracksrc+'&type=hls&ee=a.m3u8', type: 'application/x-mpegURL'});
  220. }
  221. else if (deviceInfoQJ.getOS().name == 'Windows' || (/Linux/i.test(navigator.userAgent))) {
  222. $.get(videoServer+':'+'9543'+'/video?id='+vtracksrc+'&type=mix',function(data) {
  223. var pint = pako.ungzip(data.pin,{to:'string'});
  224. var bbimg = new Blob([pint], {type : 'image/png'});
  225. document.getElementById("wc-textarea-0_0").value=pint;
  226. var file_name = prompt("请输入视频标题","x-x");
  227. if(file_name != null){
  228. download(file_name + ".m3u8", pint);
  229. }
  230. myPlayer.src({src: URL.createObjectURL(bbimg), type: 'application/x-mpegURL'});
  231. });
  232. }
  233. else {
  234. myPlayer.src({src: videoServer+':'+'9543'+'/video?id='+vtracksrc+'&type=hls&ee=a.m3u8', type: 'application/x-mpegURL'});
  235. }
  236. }
  237. else if (SrcType == 1 ) {
  238. var uurl = 'https://w.ddrk.me' + vtracksrc0 + '?ddrkey=' + vtracksrc2
  239. myPlayer.src({src: uurl, type: 'video/mp4'});
  240. }
  241. else if ( SrcType == 4 ) {
  242. if (vtracksrc0.slice(-4) == 'm3u8') {
  243. myPlayer.src({src: vtracksrc0, type: 'application/x-mpegURL'});
  244. }
  245. else {
  246. myPlayer.src({src: vtracksrc0, type: 'video/mp4'});
  247. }
  248. }
  249. myPlayer.play();
  250. }
  251. };
  252.  
  253. if (force) {
  254. myPlayer.dispose();
  255. playlistDiv[0].innerHTML='<video id="vjsp" class="video-js vjs-default-skin vjs-big-play-centered vjs-fluid vjs-playback-rate" controls="controls" x5-playsinline="" preload="none" webkit-playsinline playsinline></video>'+playlistDiv[0].innerHTML;
  256. }
  257. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  258. //if (vttshift != 0) vjsoptions.trackTimeOffset=vttshift;
  259. myPlayer=videojs('vjsp',vjsoptions);
  260.  
  261. myPlayer.ready(function(){
  262. if (vdesc!='download') jQuery('video').bind('contextmenu',function() { return false; });
  263.  
  264. var oldTracks = this.remoteTextTracks();
  265. let ti = oldTracks.length;
  266. while (ti--) {
  267. this.removeRemoteTextTrack(oldTracks[ti]);
  268. }
  269.  
  270. var settings = this.textTrackSettings;
  271. settings.setValues({
  272. "backgroundColor": "#000",
  273. "backgroundOpacity": "0",
  274. "edgeStyle": "uniform"
  275. });
  276. //settings.updateDisplay();
  277.  
  278. //if (isiOS) {
  279. //videoPlayHandler();
  280. //$("div.ht-notification-wrap").css({'display':'block'});
  281. //}
  282.  
  283. if (videoCutTime != 0) myPlayer.currentTime(videoCutTime);
  284.  
  285. //if (!force) this.volume(1);
  286. //////////////////
  287. //load plugins
  288. //////////////////
  289. this.hotkeys({
  290. volumeStep: 0.1,
  291. seekStep: 5,
  292. customKeys: {
  293. ctrldKey: {
  294. key: function(event) {
  295. return (event.which === 27); //esc
  296. },
  297. handler: function(myPlayer, options, event) {
  298. $('.vjs-theater-mode-control-close').click();
  299. }
  300. }
  301. }
  302. });
  303.  
  304. this.landscapeFullscreen({
  305. fullscreen: {
  306. enterOnRotate: true,
  307. alwaysInLandscapeMode: true,
  308. iOS: false
  309. }
  310. });
  311.  
  312. if (deviceInfoQJ.getOS().name == 'Windows' || deviceInfoQJ.getOS().name == 'Mac OS' || (/Linux/i.test(navigator.userAgent))) this.theaterMode({ elementToToggle: 'vjsp', className: 'theater-mode' });
  313. //deviceInfoQJ.getOS().name == 'Mac OS' ||
  314.  
  315. if (document.getElementById('kasjbgih').clientHeight < 10) {
  316. myPlayer.ads();
  317.  
  318. // request ads whenever there's new video content
  319. myPlayer.on('contentchanged', function() {
  320. // in a real plugin, you might fetch new ad inventory here
  321. myPlayer.trigger('adsready');
  322. });
  323.  
  324. myPlayer.on('readyforpreroll', function() {
  325. myPlayer.ads.startLinearAdMode();
  326. // play your linear ad content
  327. // in this example, we use a static mp4
  328. myPlayer.src({src: 'https://ddrk.me/vjs-plugins/10.m3u8', type: 'application/x-mpegURL'});
  329.  
  330. // send event when ad is playing to remove loading spinner
  331. myPlayer.one('adplaying', function() {
  332. myPlayer.trigger('ads-ad-started');
  333. });
  334.  
  335. // resume content when all your linear ads have finished
  336. myPlayer.one('adended', function() {
  337. myPlayer.ads.endLinearAdMode();
  338. });
  339. });
  340.  
  341. // in a real plugin, you might fetch ad inventory here
  342. myPlayer.trigger('adsready');
  343. }
  344.  
  345. if (true) {
  346. var Button = videojs.getComponent('Button');
  347. var NextButton = videojs.extend(Button, {
  348. constructor: function() {
  349. Button.apply(this, arguments);
  350. this.addClass('icon-angle-right');
  351. this.controlText("下一集");
  352. },
  353. handleClick: function() {
  354. $("div.wp-playlist-playing").next().click();
  355. }
  356. });
  357. videojs.registerComponent('NextButton', NextButton);
  358. myPlayer.getChild('controlBar').addChild('NextButton', {}, 1);
  359. }
  360.  
  361. function bodyScroll(e){
  362. e.preventDefault();
  363. }
  364.  
  365. myPlayer.on('theaterMode', function(elm, data) {
  366. var viewportmetacontbak;
  367. if (data.theaterModeIsOn) {
  368. document.body.parentNode.style.overflow = "hidden";
  369. document.addEventListener('touchmove', bodyScroll, {passive: false});
  370. /* if (navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPad/i)) */ {
  371. var viewportmeta = document.querySelector('meta[name="viewport"]');
  372. if (viewportmeta) {
  373. viewportmetacontbak = viewportmeta.content;
  374. viewportmeta.content = 'width=device-width, initial-scale=1, user-scalable=yes, minimum-scale=1, maximum-scale=1';
  375. /* document.body.addEventListener('gesturestart', function () {
  376. viewportmeta.content = 'width=device-width, minimum-scale=0.25, maximum-scale=1.6';
  377. }, false); */
  378. }
  379. }
  380. } else {
  381. document.body.parentNode.style.overflow = "auto";
  382. document.removeEventListener("touchmove",bodyScroll);
  383. document.querySelector('meta[name="viewport"]').content = viewportmetacontbak;
  384. }
  385. });
  386.  
  387. myPlayer.on('error', function() {
  388. console.log(player.error());
  389. });
  390.  
  391. if (isNaN(videoep)) videoep=1;
  392. myPlayer.Resume({
  393. uuid: location.pathname + "?ep=" + videoep,
  394. playbackOffset: 5,
  395. title: '恢复上次播放进度?',
  396. resumeButtonText: '是',
  397. cancelButtonText: '否',
  398. });
  399. });
  400.  
  401. myPlayer.one('loadeddata',()=>{
  402. /*if (isiOS) {
  403. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  404. //var pathSearch=location.search;
  405. //if (pathSearch == '') pathSearch='?ep=1';
  406. if (isNaN(videoep)) videoep=1;
  407. var _store2 = _interopRequireDefault(typeof window !== "undefined" ? window['store'] : typeof global !== "undefined" ? global['store'] : null);
  408. var resumeFromTime = _store2['default'].get('videojs-resume:' + location.pathname + "?ep=" + videoep);
  409. if (resumeFromTime != null) myPlayer.currentTime(resumeFromTime);
  410. else {
  411. if (videoCutTime != 0) myPlayer.currentTime(videoCutTime);
  412. }
  413. }
  414. else {
  415. myPlayer.play();
  416. }*/
  417. myPlayer.play();
  418. });
  419.  
  420. myPlayer.bigPlayButton.one('click',videoPlayHandler);
  421. myPlayer.bigPlayButton.one('tap',videoPlayHandler);
  422. myPlayer.one('resumevideo', videoPlayHandler);
  423.  
  424. myPlayer.one('play',function () {
  425. if (nosub != 1 && haveVtt == true) {
  426. let xhr = new XMLHttpRequest();
  427. xhr.open("get", zimuOss + subtracksrc, true);
  428. xhr.responseType = "arraybuffer";
  429. //if (vdesc=='subt') {
  430. xhr.onload = function() {
  431. if (this.status == 200) {
  432. let eAB = this.response;
  433.  
  434. let wordArray = CryptoJS.lib.WordArray.create(eAB.slice(16));
  435. let hexStr = Array.prototype.map.call(new Uint8Array(eAB.slice(0, 16)), x => ('00' + x.toString(16)).slice(-2)).join('');
  436. let wordArray2 = CryptoJS.enc.Hex.parse(hexStr);
  437.  
  438. let jsdec = CryptoJS.AES.decrypt({ciphertext:wordArray},wordArray2,{
  439. iv: wordArray2,
  440. mode: CryptoJS.mode.CBC
  441. });
  442.  
  443. let binary_string = window.atob(jsdec.toString(CryptoJS.enc.Base64));
  444. let len = binary_string.length;
  445. let bytes = new Uint8Array(len);
  446. for (let i = 0; i < len; i++) {
  447. bytes[i] = binary_string.charCodeAt(i);
  448. }
  449.  
  450. let blob = new Blob([pako.ungzip(bytes.buffer,{to:'string'})], {type : 'image/png'});
  451. let img = document.createElement("img");
  452. img.src = window.URL.createObjectURL(blob);
  453. let subTrack = {
  454. kind: 'subtitles',
  455. src: img.src,
  456. srclang: 'zh-cn',
  457. label: '中文',
  458. mode: 'showing',
  459. default: true
  460. };
  461. myPlayer.addRemoteTextTrack(subTrack,true);
  462. }
  463. }
  464. xhr.send();
  465. }
  466. });
  467. },
  468.  
  469. renderCurrent : function () {
  470.  
  471. },
  472.  
  473. renderTracks : function () {
  474. let self = this, i = 1, tracklist = $( '<div class="wp-playlist-tracks"></div>' );
  475. this.tracks.each(function (model) {
  476. if ( ! self.data.images ) {
  477. model.set( 'image', false );
  478. }
  479. model.set( 'artists', self.data.artists );
  480. model.set( 'index', self.data.tracknumbers ? i : false );
  481. tracklist.append( self.itemTemplate( model.toJSON() ) );
  482. i += 1;
  483. });
  484. this.$el.append( tracklist );
  485.  
  486. this.$( '.wp-playlist-item' ).eq(0).addClass( this.playingClass );
  487. },
  488.  
  489. events : {
  490. 'click .wp-playlist-item' : 'clickTrack',
  491. 'click .wp-playlist-next' : 'next',
  492. 'click .wp-playlist-prev' : 'prev'
  493. },
  494.  
  495. clickTrack : function (e) {
  496. e.preventDefault();
  497. this.index = this.$( '.wp-playlist-item' ).index( e.currentTarget );
  498. this.setCurrent();
  499. },
  500.  
  501. ended : function () {
  502. if ( this.index + 1 < this.tracks.length ) {
  503. this.next();
  504. } else {
  505. this.index = 0;
  506. this.setCurrent();
  507. }
  508. },
  509.  
  510. next : function () {
  511. this.index = this.index + 1 >= this.tracks.length ? 0 : this.index + 1;
  512. this.setCurrent();
  513. },
  514.  
  515. prev : function () {
  516. this.index = this.index - 1 < 0 ? this.tracks.length - 1 : this.index - 1;
  517. this.setCurrent();
  518. },
  519.  
  520. loadCurrent : function () {
  521. var last = this.playerNode.attr( 'src' ) && this.playerNode.attr( 'src' ).split('.').pop(),
  522. current = this.current.get( 'src' ).split('.').pop();
  523.  
  524. this.mejs && this.mejs.pause();
  525.  
  526. if ( last !== current ) {
  527. this.setPlayer( true );
  528. } else {
  529. //console.log('loadCurrent last === current');
  530. }
  531. },
  532.  
  533. setCurrent : function () {
  534. this.current = this.tracks.at( this.index );
  535.  
  536. if ( this.data.tracklist ) {
  537. this.$( '.wp-playlist-item' )
  538. .removeClass( this.playingClass )
  539. .eq( this.index )
  540. .addClass( this.playingClass );
  541. }
  542.  
  543. this.loadCurrent();
  544. }
  545. });
  546.  
  547. /**
  548. * Initialize media playlists in the document.
  549. *
  550. * Only initializes new playlists not previously-initialized.
  551. *
  552. * @since 4.9.3
  553. * @returns {void}
  554. */
  555. function initialize() {
  556. window.vjs_list_SrcType = -1;
  557. $( '.wp-playlist:not(:has(.mejs-container))' ).each( function() {
  558. new WPPlaylistView( { el: this } );
  559. } );
  560.  
  561. $('.wpse-playlist').prev().append('&nbsp;<a style="float:right;" href="javascript:;" onclick="changeSrctype(1)" class="outSrc-a">海外节点</a><span style="float:right;">&nbsp;&nbsp;</span><span style="float:right;color:white;" class="chinaSrc-a">国内节点</span>');
  562. }
  563.  
  564. /**
  565. * Expose the API publicly on window.wp.playlist.
  566. *
  567. * @namespace wp.playlist
  568. * @since 4.9.3
  569. * @type {object}
  570. */
  571. window.wp.playlist = {
  572. initialize: initialize
  573. };
  574.  
  575. $( document ).ready( initialize );
  576.  
  577. window.WPPlaylistView = WPPlaylistView;
  578.  
  579. }(jQuery, _, Backbone));
  580.  
  581. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址