Files
web_hgtv_server/pub/common/m3u8/vtt.go
T
rootandClaude Opus 5.5 7974a42301 Initial commit
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 11:07:42 +08:00

97 lines
2.6 KiB
Go

package m3u8
import (
"bufio"
"bytes"
"io"
"strings"
"videoweb/pub/common/errors"
"videoweb/pub/common/utils"
"videoweb/pub/storage/proxy"
)
// TransformVtt 读取雪碧图 vtt 文件,并把其中的缩略图路径替换为图片 cdn 地址。
// 兼容现有 /laosiji 路径资源:laosiji 的 vtt 需移除 /laosiji 前缀后,从 lsjImageYuan 源站读取。
// imgCdn 图片 cdn 域名(缩略图访问地址)
// origDomain 普通媒资的源站域名
// lsjImageYuan 老司机图片源站域名(由 app/web 项目从配置 lsjMediaConf.imageYuan 传入)
func TransformVtt(name, imgCdn, origDomain, lsjImageYuan string) (buff []byte, err error) {
if name == "" {
err = errors.MakeWithMsg(errors.M3u8FileName, "vtt file name is empty")
return
}
if imgCdn == "" || origDomain == "" {
err = errors.MakeWithMsg(errors.DomainErr, "imgCdn or origDomain is empty")
return
}
mediaVersion := proxy.AppendsMediaS3Version(name)
if len(mediaVersion) > 0 {
name = mediaVersion + name
}
originName := name
if strings.Contains(name, "laosiji") {
if lsjImageYuan == "" {
err = errors.MakeWithMsg(errors.DomainErr, "lsjImageYuan is empty")
return
}
originName = stripLaosijiPrefix(name)
origDomain = lsjImageYuan
}
srcReader, err := readFromRedis(originName, origDomain)
if err != nil {
return
}
raw, err := io.ReadAll(srcReader)
if err != nil {
return nil, errors.MakeWithMsg(errors.M3u8Read, "read vtt reader fail: "+err.Error())
}
dirPath := utils.PathForInfo(name).Dir
buff = rewriteVttWithCDN(raw, imgCdn, dirPath)
return
}
func stripLaosijiPrefix(name string) string {
p := strings.TrimPrefix(name, "/")
p = strings.TrimPrefix(p, "laosiji")
p = strings.TrimPrefix(p, "/")
return p
}
func rewriteVttWithCDN(vttData []byte, imgCdn, dirPath string) []byte {
imgCdn = strings.TrimRight(strings.TrimSpace(imgCdn), "/")
var out bytes.Buffer
scanner := bufio.NewScanner(bytes.NewReader(vttData))
scanner.Buffer(make([]byte, 0, 64*1024), 1024*1024)
for scanner.Scan() {
line := scanner.Text()
trim := strings.TrimSpace(line)
if idx := strings.Index(trim, "#xywh="); idx >= 0 {
p := strings.TrimSpace(trim[:idx])
xywh := trim[idx:]
var newPath string
switch {
case strings.HasPrefix(p, "http://") || strings.HasPrefix(p, "https://"):
newPath = p
case strings.HasPrefix(p, "/"):
newPath = imgCdn + p
default:
newPath = utils.JoinUrlPath(utils.JoinUrlPath(imgCdn, strings.TrimRight(dirPath, "/")), p)
}
out.WriteString(newPath + xywh + "\n")
continue
}
out.WriteString(line + "\n")
}
return out.Bytes()
}