⚡️ perf(media): 音频代理改为流式转发
- downloadMedia 拿到响应头即返回 Body,音频不再全量驻留内存,改由 io.Copy 流式写出 - 重试仅覆盖响应阶段;Body 读取中途失败由客户端自行重试 - 请求头设置提取为 setMediaHeaders 复用;data_uri 模式保持全量读取(本就需驻留内存) - 漫画代理因需解密后输出,维持原有全量方式
This commit is contained in:
1 parent
f89bee8ddc
commit
ad6d28fd85
3 files changed
+54
-47
No files matched your search
@@ -4,15 +4,16 @@ import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
)
|
||||
|
||||
// AudioCacheItem 音频缓存项
|
||||
type AudioCacheItem struct {
|
||||
OriginalURL string `json:"original_url"` // 原始CDN URL
|
||||
DeviceID string `json:"device_id"` // 关联的设备ID
|
||||
DeviceID string `json:"device_id"` // 关联的设备ID
|
||||
Headers map[string]string `json:"headers"` // 请求头信息
|
||||
CachedAt time.Time `json:"cached_at"` // 缓存时间
|
||||
CachedAt time.Time `json:"cached_at"` // 缓存时间
|
||||
}
|
||||
|
||||
// GenerateAudioProxyURL 生成音频代理URL
|
||||
@@ -49,8 +50,8 @@ func GenerateAudioProxyURL(originalURL, deviceID string, headers map[string]stri
|
||||
return fmt.Sprintf("/audio/proxy/%s", key)
|
||||
}
|
||||
|
||||
// HandleAudioProxy 处理音频代理请求
|
||||
func HandleAudioProxy(key string) ([]byte, string, error) {
|
||||
// HandleAudioProxy 处理音频代理请求(流式返回,调用方负责 Close)
|
||||
func HandleAudioProxy(key string) (io.ReadCloser, string, error) {
|
||||
var originalURL, deviceID string
|
||||
var headers map[string]string
|
||||
|
||||
@@ -95,13 +96,13 @@ func HandleAudioProxy(key string) ([]byte, string, error) {
|
||||
headers = make(map[string]string)
|
||||
}
|
||||
|
||||
// 下载音频内容,使用关联的设备信息
|
||||
data, contentType, err := downloadMediaWithRetry(originalURL, deviceID, headers, 3)
|
||||
// 下载音频内容(流式),使用关联的设备信息
|
||||
body, contentType, err := downloadMediaWithRetry(originalURL, deviceID, headers, 3)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("下载音频失败: %w", err)
|
||||
}
|
||||
|
||||
return data, contentType, nil
|
||||
return body, contentType, nil
|
||||
}
|
||||
|
||||
// CleanExpiredAudioCache 清理过期的音频缓存
|
||||
|
||||
Reference in new issue
Block a user