package utils import ( "bytes" "fmt" "go.uber.org/zap" "io" "net/http" "net/url" "os" "strings" ) type reader struct { bytes.Reader io.Closer } func (a *reader) Seek(offset int64, whence int) (int64, error) { return a.Reader.Seek(offset, whence) } func toSeeker(src io.ReadCloser) io.ReadCloser { buf := &bytes.Buffer{} _, _ = io.Copy(buf, src) return &reader{ Reader: *bytes.NewReader(buf.Bytes()), Closer: src, } } func open(u string) io.ReadCloser { p, _ := strings.CutPrefix(u, "file://") f, e := os.Open(p) if e != nil { zap.S().Infof("音频文件 [%v] 打开错误: %v\n", u, e) return nil } return f } func get(u string) io.ReadCloser { resp, e := http.Get(u) if e != nil { zap.S().Infof("音频文件 [%v] 下载失败: %v\n", u, e) return nil } return resp.Body } // LinkAudio 链接音频,解析链接,直接提取为数据流 func LinkAudio(link string) (bgm io.ReadCloser, err error) { if link == "" { return } u, err := url.Parse(link) if err != nil { err = fmt.Errorf("URL 解析错误: %v", err) } else { if u.Scheme == "file" { bgm = open(link) } else if u.Scheme == "http" || u.Scheme == "https" { bgm = get(link) } else { err = fmt.Errorf("不支持的链接协议: %v", u.String()) } if bgm != nil { bgm = toSeeker(bgm) } } return }