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() }