@@ -96,8 +96,41 @@ export async function fetchHighQualityVideoUrl(itemId: string, refreshToken: str
9696 const responseStr = JSON . stringify ( result ) ;
9797 logger . info ( `get_local_item_list 响应大小: ${ responseStr . length } 字符` ) ;
9898
99- // 策略1: 从结构化字段中提取视频URL
99+ // 策略0(最优先): 从 video_model 字段提取无水印视频URL
100+ // video_model 是 JSON 字符串,其中 video_list.*.main_url 为 Base64 编码的无水印链接
100101 const itemList = result . item_list || result . local_item_list || [ ] ;
102+ if ( itemList . length > 0 ) {
103+ const item = itemList [ 0 ] ;
104+ const videoModelStr = item ?. video ?. video_model ;
105+ if ( videoModelStr && typeof videoModelStr === "string" ) {
106+ try {
107+ const videoModel = JSON . parse ( videoModelStr ) ;
108+ const videoList = videoModel ?. video_list ;
109+ if ( videoList && typeof videoList === "object" ) {
110+ // 按清晰度优先级尝试提取:
111+ // 4K(video_4) > 2K(video_3) > 1080p(video_2) > 720p(video_1)
112+ // 目前只抓包到video_1
113+ const priorityKeys = [ "video_4" , "video_3" , "video_2" , "video_1" ] ;
114+ for ( const key of priorityKeys ) {
115+ const mainUrlB64 = videoList [ key ] ?. main_url ;
116+ if ( mainUrlB64 && typeof mainUrlB64 === "string" ) {
117+ // Base64 解码得到真实无水印URL(Node.js 16+ 全局支持 atob)
118+ const decodedUrl = atob ( mainUrlB64 ) ;
119+ if ( decodedUrl . startsWith ( "http" ) ) {
120+ const definition = videoList [ key ] ?. definition || key ;
121+ logger . info ( `从video_model提取到无水印视频URL (${ definition } ): ${ decodedUrl } ` ) ;
122+ return decodedUrl ;
123+ }
124+ }
125+ }
126+ }
127+ } catch ( e ) {
128+ logger . warn ( `解析video_model JSON失败: ${ e . message } ` ) ;
129+ }
130+ }
131+ }
132+
133+ // 策略1: 从结构化字段中提取视频URL(可能带水印,作为降级方案)
101134 if ( itemList . length > 0 ) {
102135 const item = itemList [ 0 ] ;
103136 const videoUrl =
@@ -108,7 +141,7 @@ export async function fetchHighQualityVideoUrl(itemId: string, refreshToken: str
108141 item ?. video ?. url ;
109142
110143 if ( videoUrl ) {
111- logger . info ( `从get_local_item_list结构化字段获取到高清视频URL: ${ videoUrl } ` ) ;
144+ logger . info ( `从get_local_item_list结构化字段获取到高清视频URL(可能含水印) : ${ videoUrl } ` ) ;
112145 return videoUrl ;
113146 }
114147 }
0 commit comments