1- /**
2- * UC网盘处理器模块
3- * 提供UC网盘分享链接解析、文件下载、转存等功能
4- * @module uc-handler
5- */
6-
7- import req from '../req.js' ;
1+ import { reqs } from '../req.js' ;
82import { ENV } from '../env.js' ;
93import COOKIE from '../cookieManager.js' ;
104import CryptoJS from "crypto-js" ;
@@ -113,6 +107,17 @@ class UCHandler {
113107 * @param {Object } cfg - 配置对象
114108 */
115109 async initUC ( db , cfg ) {
110+ if ( this . token ) {
111+ let exp = JSON . parse ( CryptoJS . enc . Base64 . parse ( this . token . split ( '.' ) [ 1 ] ) . toString ( CryptoJS . enc . Utf8 ) )
112+ let now = Math . floor ( Date . now ( ) / 1000 )
113+ if ( exp . exp < now ) {
114+ console . log ( '登录状态已过期,尝试刷新Token' )
115+ await this . refreshUcToken ( )
116+ } else {
117+ console . log ( '登录成功,继续使用,可使用时间截止到:' + ( new Date ( exp . exp * 1000 ) ) . toLocaleString ( ) )
118+ console . log ( 'UC TV token获取成功:' + this . token )
119+ }
120+ }
116121 if ( this . cookie ) {
117122 console . log ( "cookie 获取成功" ) ;
118123 } else {
@@ -209,16 +214,25 @@ class UCHandler {
209214
210215 // 遍历所有目标文件,计算与主文件的匹配度
211216 for ( let i = 0 ; i < targetItems . length ; i ++ ) {
217+
212218 const currentLCS = this . lcs ( mainItem . name , targetItems [ i ] . name ) ;
219+
213220 results . push ( { target : targetItems [ i ] , lcs : currentLCS } ) ;
214221 // 更新最佳匹配
215222 if ( currentLCS . length > results [ bestMatchIndex ] . lcs . length ) {
223+
216224 bestMatchIndex = i ;
225+
217226 }
227+
218228 }
219229
230+
220231 const bestMatch = results [ bestMatchIndex ] ;
232+
233+
221234 return { allLCS : results , bestMatch : bestMatch , bestMatchIndex : bestMatchIndex } ;
235+
222236 }
223237
224238 /**
@@ -253,12 +267,12 @@ class UCHandler {
253267
254268 // 根据方法类型发送请求
255269 const resp =
256- method === 'get' ? await req . get ( `${ this . apiUrl } /${ url } ` , {
270+ method === 'get' ? await reqs . get ( `${ this . apiUrl } /${ url } ` , {
257271 headers : headers ,
258272 } ) . catch ( ( err ) => {
259273 console . error ( err ) ;
260274 return err . response || { status : 500 , data : { } } ;
261- } ) : await req . post ( `${ this . apiUrl } /${ url } ` , data , {
275+ } ) : await reqs . post ( `${ this . apiUrl } /${ url } ` , data , {
262276 headers : headers ,
263277 } ) . catch ( ( err ) => {
264278 console . error ( err ) ;
@@ -395,6 +409,7 @@ class UCHandler {
395409 // 过滤小于5MB的视频文件
396410 if ( item . size < 1024 * 1024 * 5 ) continue ;
397411 item . stoken = this . shareTokenCache [ shareData . shareId ] . stoken ;
412+ item . file_name = text . test ( item . file_name ) ? item . file_name . replace ( text , '' ) : item . file_name
398413 videos . push ( item ) ;
399414 } else if ( item . type === 'file' && this . subtitleExts . some ( ( x ) => item . file_name . endsWith ( x ) ) ) {
400415 // 收集字幕文件
@@ -550,9 +565,49 @@ class UCHandler {
550565 return CryptoJS . SHA256 ( data ) . toString ( ) ;
551566 }
552567
568+ async refreshUcToken ( ) {
569+ const timestamp = Math . floor ( Date . now ( ) / 1000 ) . toString ( ) + '000' ; // 13位时间戳需调整
570+ const deviceID = this . Addition . DeviceID || this . generateDeviceID ( timestamp ) ;
571+ const reqId = this . generateReqId ( deviceID , timestamp ) ;
572+ let data = JSON . stringify ( {
573+ "req_id" : reqId ,
574+ "app_ver" : this . conf . appVer ,
575+ "device_id" : deviceID ,
576+ "device_brand" : "OPPO" ,
577+ "platform" : "tv" ,
578+ "device_name" : "PCRT00" ,
579+ "device_model" : "PCRT00" ,
580+ "build_device" : "aosp" ,
581+ "build_product" : "PCRT00" ,
582+ "device_gpu" : "Adreno%20(TM)%20640" ,
583+ "activity_rect" : "%7B%7D" ,
584+ "channel" : this . conf . channel ,
585+ "refresh_token" : this . token
586+ } ) ;
587+ let config = {
588+ method : 'POST' ,
589+ url : 'http://api.extscreen.com/ucdrive/token' ,
590+ headers : {
591+ 'User-Agent' : 'Mozilla/5.0 (Linux; U; Android 7.1.2; zh-cn; PCRT00 Build/N2G47O) AppleWebKit/533.1 (KHTML, like Gecko) Mobile Safari/533.1' ,
592+ 'Connection' : 'Keep-Alive' ,
593+ 'Accept-Encoding' : 'gzip' ,
594+ 'Content-Type' : 'application/json' ,
595+ 'Cookie' : 'sl-session=VIaxTAKF8mdJBhU2uda0zA=='
596+ } ,
597+ data : data
598+ } ;
599+ let req = await axios . request ( config ) ;
600+ if ( req . status === 200 ) {
601+ console . log ( '刷新token成功' )
602+ const token = req . data . data . access_token
603+ let exp = JSON . parse ( CryptoJS . enc . Base64 . parse ( token . split ( '.' ) [ 1 ] ) . toString ( CryptoJS . enc . Utf8 ) )
604+ console . log ( '登录成功,继续使用,可使用时间截止到:' + ( new Date ( exp . exp * 1000 ) ) . toLocaleString ( ) )
605+ ENV . set ( 'uc_token_cookie' , token )
606+ }
607+ }
553608
554609 async getDownload ( shareId , stoken , fileId , fileToken , clean ) {
555-
610+ await this . initUC ( )
556611 if ( ! this . saveFileIdCaches [ fileId ] ) {
557612
558613 const saveFileId = await this . save ( shareId , stoken , fileId , fileToken , clean ) ;
@@ -614,38 +669,8 @@ class UCHandler {
614669 return video ;
615670 }
616671 if ( req . data . status === - 1 || req . data . errno === 10001 ) {
617- let data = JSON . stringify ( {
618- "req_id" : reqId ,
619- "app_ver" : this . conf . appVer ,
620- "device_id" : deviceID ,
621- "device_brand" : "OPPO" ,
622- "platform" : "tv" ,
623- "device_name" : "PCRT00" ,
624- "device_model" : "PCRT00" ,
625- "build_device" : "aosp" ,
626- "build_product" : "PCRT00" ,
627- "device_gpu" : "Adreno%20(TM)%20640" ,
628- "activity_rect" : "%7B%7D" ,
629- "channel" : this . conf . channel ,
630- "refresh_token" : this . token
631- } ) ;
632- let config = {
633- method : 'POST' ,
634- url : 'http://api.extscreen.com/ucdrive/token' ,
635- headers : {
636- 'User-Agent' : 'Mozilla/5.0 (Linux; U; Android 7.1.2; zh-cn; PCRT00 Build/N2G47O) AppleWebKit/533.1 (KHTML, like Gecko) Mobile Safari/533.1' ,
637- 'Connection' : 'Keep-Alive' ,
638- 'Accept-Encoding' : 'gzip' ,
639- 'Content-Type' : 'application/json' ,
640- 'Cookie' : 'sl-session=VIaxTAKF8mdJBhU2uda0zA=='
641- } ,
642- data : data
643- } ;
644- let req = await axios . request ( config ) ;
645- if ( req . status === 200 ) {
646- ENV . set ( 'uc_token_cookie' , req . data . data . refresh_token )
647- return await this . getDownload ( shareId , stoken , fileId , fileToken , clean )
648- }
672+ await this . refreshUcToken ( )
673+ return await this . getDownload ( shareId , stoken , fileId , fileToken , clean )
649674 }
650675 } else {
651676 const down = await this . api ( `file/download?${ this . pr } ` , {
@@ -661,9 +686,10 @@ class UCHandler {
661686 } ;
662687 // console.log('low_url:', low_url);
663688 const test_result = await this . testSupport ( low_url , low_headers ) ;
664- // console.log('test_result:', test_result);
689+ console . log ( 'test_result:' , test_result ) ;
665690 if ( ! test_result [ 0 ] ) {
666691 try {
692+ console . log ( `getDownload:自动刷新UC cookie` )
667693 await this . refreshUcCookie ( 'getDownload' ) ;
668694 } catch ( e ) {
669695 console . log ( `getDownload:自动刷新UC cookie失败:${ e . message } ` )
@@ -679,7 +705,7 @@ class UCHandler {
679705 const urls = [ ] ;
680706 if ( Array . isArray ( downCache ) ) {
681707 downCache . forEach ( ( it ) => {
682- urls . push ( it . name , it . url ) ;
708+ urls . push ( it . name , it . url + "#isVideo=true##fastPlayMode##threads=10#" ) ;
683709 } ) ;
684710 }
685711 return { parse : 0 , url : urls }
@@ -709,10 +735,9 @@ class UCHandler {
709735
710736 }
711737
712-
713738 async testSupport ( url , headers ) {
714739
715- const resp = await req
740+ const resp = await reqs
716741
717742 . get ( url , {
718743
@@ -767,7 +792,6 @@ class UCHandler {
767792
768793 }
769794
770-
771795 delAllCache ( keepKey ) {
772796
773797 try {
@@ -819,7 +843,6 @@ class UCHandler {
819843
820844 }
821845
822-
823846 async chunkStream ( inReq , outResp , url , urlKey , headers , option ) {
824847
825848 urlKey = urlKey || CryptoJS . enc . Hex . stringify ( CryptoJS . MD5 ( url ) ) . toString ( ) ;
@@ -954,7 +977,7 @@ class UCHandler {
954977
955978 console . log ( inReq . id , chunkIdx ) ;
956979
957- const dlResp = await req . get ( url , {
980+ const dlResp = await reqs . get ( url , {
958981
959982 responseType : 'stream' ,
960983
0 commit comments