package fqapi import ( "fanqie/internal/common" "fmt" ) var audioLogger = common.NewLogger("audio", "INFO", "") // HandleAudio 处理获取音频 func HandleAudio(itemIDs interface{}, toneID interface{}, output interface{}) (string, error) { if itemIDs == nil || itemIDs == "" { return BuildSuccessResponse([]interface{}{}), nil } // 处理itemIDs - 使用ParseStringParam itemIDStr := ParseStringParam(itemIDs, "") // 处理toneID - 使用ParseIntParam toneIDInt := ParseIntParam(toneID, 1) // 处理output参数 outputStr := ParseStringParam(output, "url") // 使用 BuildURL 添加设备参数 url := BuildURL("https://reading.snssdk.com/reading/reader/audio/playinfo/", fmt.Sprintf("item_ids=%s", itemIDStr), fmt.Sprintf("tone_id=%d", toneIDInt), "pv_player=-1", ) // 使用 GorgonRequest 添加签名和设备信息 resp, err := GorgonRequest(url, map[string]interface{}{ "method": "GET", "headers": map[string]string{ "User-Agent": "com.dragon.read", }, }) if err != nil { audioLogger.Error(fmt.Sprintf("获取音频失败: %v", err)) return BuildErrorResponse("获取音频失败"), err } respJSON, err := resp.JSON() if err != nil { audioLogger.Error(fmt.Sprintf("解析响应失败: %v", err)) return BuildErrorResponse("解析响应失败"), err } // 检查响应码 var respCode float64 var okCode bool if code, ok := respJSON["code"].(float64); ok { respCode, okCode = code, code == 0 } else if code, ok := respJSON["Code"].(float64); ok { respCode, okCode = code, code == 0 } if okCode { // 转换响应格式:只修改 code 和 message,保留原始数据结构 respJSON["code"] = 200 respJSON["message"] = "SUCCESS" // 处理output参数,替换音频URL if outputStr != "url" { // 获取当前使用的设备信息 currentDevice := GetCurrentDevice() deviceID := "" if currentDevice != nil { deviceID = currentDevice.DeviceHeader } // 准备请求头 headers := map[string]string{ "User-Agent": "com.dragon.read", } // 处理音频URL,支持多种可能的结构 if dataArray, ok := respJSON["data"].([]interface{}); ok { // 情况1:data是数组格式(实际返回的格式) for _, item := range dataArray { if audioItem, ok := item.(map[string]interface{}); ok { // 处理main_url if mainURL, ok := audioItem["main_url"].(string); ok && mainURL != "" { processedURL := processMediaURL(mainURL, deviceID, headers, outputStr, "audio") audioItem["main_url"] = processedURL } // 处理backup_url if backupURL, ok := audioItem["backup_url"].(string); ok && backupURL != "" { processedURL := processMediaURL(backupURL, deviceID, headers, outputStr, "audio") audioItem["backup_url"] = processedURL } } } } else if data, ok := respJSON["data"].(map[string]interface{}); ok { // 情况2:单个音频在audio_info下 if audioInfo, ok := data["audio_info"].(map[string]interface{}); ok { if playURL, ok := audioInfo["play_url"].(string); ok && playURL != "" { processedURL := processMediaURL(playURL, deviceID, headers, outputStr, "audio") audioInfo["play_url"] = processedURL } } // 情况3:音频列表在audio_list下 if audioList, ok := data["audio_list"].([]interface{}); ok { for _, item := range audioList { if audioItem, ok := item.(map[string]interface{}); ok { if playURL, ok := audioItem["play_url"].(string); ok && playURL != "" { processedURL := processMediaURL(playURL, deviceID, headers, outputStr, "audio") audioItem["play_url"] = processedURL } } } } } } return marshalNoEscape(UnwrapJSONStrings(respJSON)), nil } // 返回错误信息 errMsg := "获取音频失败" if msg, ok := respJSON["message"].(string); ok { errMsg = msg } else if msg, ok := respJSON["Message"].(string); ok { errMsg = msg } audioLogger.Error(fmt.Sprintf("获取音频失败: code=%v, msg=%s", respCode, errMsg)) return BuildErrorResponse(errMsg), nil }