@@ -3,7 +3,18 @@ const select = require('./select');
33const crypto = require ( '../crypto' ) ;
44const request = require ( '../request' ) ;
55const { getManagedCacheStorage } = require ( '../cache' ) ;
6- const url = require ( 'url' ) ;
6+ const { logScope } = require ( '../logger' ) ;
7+
8+ const logger = logScope ( 'provider/bodian' ) ;
9+
10+ function getRandomDeviceId ( ) {
11+ const min = 0 ;
12+ const max = 100000000000 ;
13+ const randomNum = Math . floor ( Math . random ( ) * ( max - min + 1 ) ) + min ;
14+ return randomNum . toString ( ) ;
15+ }
16+ const deviceId = getRandomDeviceId ( ) ;
17+ // const deviceId = crypto.random.uuid();
718
819const format = ( song ) => ( {
920 id : song . MUSICRID . split ( '_' ) . pop ( ) ,
@@ -15,29 +26,22 @@ const format = (song) => ({
1526 name,
1627 } ) ) ,
1728} ) ;
18- //随机ID不确定ID是否被封禁
19- function getRandomDeviceId ( ) {
20- const min = 0 ;
21- const max = 100000000000 ;
22- const randomNum = Math . floor ( Math . random ( ) * ( max - min + 1 ) ) + min ;
23- return randomNum . toString ( ) ;
24- }
25- const deviceId = getRandomDeviceId ( ) ;
26- console . log ( `bodian deviceId: ${ deviceId } ` ) ;
2729
2830const generateSign = ( str ) => {
31+ const url = new URL ( str ) ;
32+
2933 const currentTime = Date . now ( ) ;
3034 str += `×tamp=${ currentTime } ` ;
31- const questionMarkIndex = str . indexOf ( '?' ) ;
32- const baseUrl = str . substring ( 0 , questionMarkIndex ) ;
35+
3336 const filteredChars = str
34- . substring ( questionMarkIndex + 1 )
37+ . substring ( str . indexOf ( '?' ) + 1 )
3538 . replace ( / [ ^ a - z A - Z 0 - 9 ] / g, '' )
36- . split ( '' ) ;
37- filteredChars . sort ( ) ;
38- const dataToEncrypt = `kuwotest${ filteredChars . join ( '' ) } ${ url . parse ( baseUrl ) . path } ` ;
39+ . split ( '' )
40+ . sort ( ) ;
41+
42+ const dataToEncrypt = `kuwotest${ filteredChars . join ( '' ) } ${ url . pathname } ` ;
3943 const md5 = crypto . md5 . digest ( dataToEncrypt ) ;
40- return `${ str } &sign=${ md5 . toLowerCase ( ) } ` ;
44+ return `${ str } &sign=${ md5 } ` ;
4145} ;
4246
4347const search = ( info ) => {
@@ -62,10 +66,11 @@ const search = (info) => {
6266 return matched ? matched . id : Promise . reject ( ) ;
6367 } ) ;
6468} ;
65- //获取设备免费听歌时长
66- const sendAdFreeRequest = async ( ) => {
69+
70+ const sendAdFreeRequest = ( ) => {
6771 const adurl =
6872 'http://bd-api.kuwo.cn/api/service/advert/watch?uid=-1&token=×tamp=1724306124436&sign=15a676d66285117ad714e8c8371691da' ;
73+
6974 const headers = {
7075 'user-agent' : 'Dart/2.19 (dart:io)' ,
7176 plat : 'ar' ,
@@ -76,19 +81,22 @@ const sendAdFreeRequest = async () => {
7681 qimei36 : '1e9970cbcdc20a031dee9f37100017e1840e' ,
7782 'content-type' : 'application/json; charset=utf-8' ,
7883 } ;
84+
7985 const data = JSON . stringify ( {
8086 type : 5 ,
8187 subType : 5 ,
8288 musicId : 0 ,
8389 adToken : '' ,
8490 } ) ;
85- const response = await request ( 'POST' , adurl , headers , data ) ;
86- if ( typeof response . body === 'object' ) {
87- console . log ( 'bodian ad free response:' , response . body ) ;
88- }
91+
92+ return request ( 'POST' , adurl , headers , data )
93+ . then ( ( response ) => response . body ( ) )
94+ . then ( ( jsonBody ) =>
95+ logger . debug ( `bodian ad free response: ${ jsonBody } ` )
96+ ) ;
8997} ;
9098
91- const track = async ( id ) => {
99+ const track = ( id ) => {
92100 const headers = {
93101 'user-agent' : 'Dart/2.19 (dart:io)' ,
94102 plat : 'ar' ,
@@ -98,20 +106,26 @@ const track = async (id) => {
98106 host : 'bd-api.kuwo.cn' ,
99107 'X-Forwarded-For' : '1.0.1.114' ,
100108 } ;
109+
101110 let audioUrl = `http://bd-api.kuwo.cn/api/play/music/v2/audioUrl?&br=${
102111 select . ENABLE_FLAC ? '2000kflac' : '320kmp3'
103112 } &musicId=${ id } `;
104113 audioUrl = generateSign ( audioUrl ) ;
105- try {
106- await sendAdFreeRequest ( ) ;
107- let response = await request ( 'GET' , audioUrl , headers ) ;
108- const body = await response . body ( ) ;
109- let urlMatch = ( body . match ( / h t t p [ ^ \s $ " ] + / ) || [ ] ) [ 0 ] ;
110- urlMatch = urlMatch . replace ( / \? .* / , '' ) ;
111- return urlMatch || Promise . reject ( ) ;
112- } catch ( error ) {
113- return insure ( ) . bodian . track ( id ) ;
114- }
114+
115+ return sendAdFreeRequest ( ) . then ( ( ) =>
116+ request ( 'GET' , audioUrl , headers )
117+ . then ( ( response ) => response . json ( ) )
118+ . then ( ( jsonBody ) => {
119+ if (
120+ ! jsonBody ||
121+ jsonBody . code !== 200 ||
122+ typeof jsonBody . data !== 'object'
123+ )
124+ return Promise . reject ( ) ;
125+ return jsonBody . data . audioUrl || Promise . reject ( ) ;
126+ } )
127+ . catch ( ( ) => insure ( ) . bodian . track ( id ) )
128+ ) ;
115129} ;
116130
117131const cs = getManagedCacheStorage ( 'provider/bodian' ) ;
0 commit comments