117 lines
3.3 KiB
Go
117 lines
3.3 KiB
Go
package m3u8
|
||
|
||
import (
|
||
"bytes"
|
||
"fmt"
|
||
"strings"
|
||
"videoweb/pub/common/errors"
|
||
"videoweb/pub/common/utils"
|
||
"videoweb/pub/storage/proxy"
|
||
|
||
"github.com/grafov/m3u8"
|
||
)
|
||
|
||
const lsjKeyIV = "0x64cf692cebc516e4a86ac6081aae50ce"
|
||
|
||
// TransformForTranscode 生成转码专用播放列表,供老司机转码服务器拉取。
|
||
func TransformForTranscode(name, origDomain, cdnDomain, webM3u8Host, lsjM3u8Yuan, lsjTsYuan string) (media *m3u8.MediaPlaylist, buff *bytes.Buffer, err error) {
|
||
if strings.Contains(name, "hc237") {
|
||
name = "/laosiji" + name
|
||
}
|
||
if strings.Contains(name, "laosiji") {
|
||
return transcodeLaosiji(name, webM3u8Host, lsjM3u8Yuan, lsjTsYuan)
|
||
}
|
||
return transcodeNormal(name, origDomain, cdnDomain, webM3u8Host)
|
||
}
|
||
|
||
func transcodeLaosiji(name, webM3u8Host, lsjM3u8Yuan, lsjTsYuan string) (media *m3u8.MediaPlaylist, buff *bytes.Buffer, err error) {
|
||
m3u8reader, err := readFromRedis(laosijiUpstreamPath(name), lsjM3u8Yuan)
|
||
if err != nil {
|
||
return
|
||
}
|
||
p, t, err := m3u8.DecodeFrom(m3u8reader, false)
|
||
if err != nil {
|
||
err = errors.MakeWithErr(errors.M3u8Read, err)
|
||
return
|
||
}
|
||
switch t {
|
||
case m3u8.MEDIA:
|
||
pl := p.(*m3u8.MediaPlaylist)
|
||
keyURI := utils.JoinUrlPath(webM3u8Host, keyUriWebLsj)
|
||
// ts 走 CDN(TsYuan/laosiji),与正常播放的 CDN 路径一致。
|
||
media, err = makeTranscodeSegList(pl, utils.JoinUrlPath(lsjTsYuan, "/laosiji"), "", keyURI, lsjKeyIV, true)
|
||
if err != nil {
|
||
return
|
||
}
|
||
buff = media.Encode()
|
||
case m3u8.MASTER:
|
||
buff = p.(*m3u8.MasterPlaylist).Encode()
|
||
default:
|
||
err = errors.MakeWithMsg(errors.M3u8FileName, fmt.Sprintf("invalid m3u8 type %d", t))
|
||
}
|
||
return
|
||
}
|
||
|
||
func transcodeNormal(name, origDomain, cdnDomain, webM3u8Host string) (media *m3u8.MediaPlaylist, buff *bytes.Buffer, err error) {
|
||
if v := proxy.AppendsMediaS3Version(name); len(v) > 0 {
|
||
name = v + name
|
||
}
|
||
m3u8reader, err := readFromRedis(name, origDomain)
|
||
if err != nil {
|
||
return
|
||
}
|
||
p, t, err := m3u8.DecodeFrom(m3u8reader, false)
|
||
if err != nil {
|
||
err = errors.MakeWithErr(errors.M3u8Read, err)
|
||
return
|
||
}
|
||
switch t {
|
||
case m3u8.MEDIA:
|
||
pl := p.(*m3u8.MediaPlaylist)
|
||
dirPath := utils.PathForInfo(name).Dir
|
||
keyURI := utils.JoinUrlPath(webM3u8Host, webkeyUri)
|
||
// ts 走 CDN(CdnDomain),与正常播放一致。
|
||
media, err = makeTranscodeSegList(pl, cdnDomain, dirPath, keyURI, "", false)
|
||
if err != nil {
|
||
return
|
||
}
|
||
buff = media.Encode()
|
||
case m3u8.MASTER:
|
||
buff = p.(*m3u8.MasterPlaylist).Encode()
|
||
default:
|
||
err = errors.MakeWithMsg(errors.M3u8FileName, fmt.Sprintf("invalid m3u8 type %d", t))
|
||
}
|
||
return
|
||
}
|
||
|
||
func makeTranscodeSegList(from *m3u8.MediaPlaylist, srcDomain, dirPath, keyURI, iv string, laosiji bool) (media *m3u8.MediaPlaylist, err error) {
|
||
media, err = m3u8.NewMediaPlaylist(0, from.Count())
|
||
if err != nil {
|
||
return
|
||
}
|
||
base := utils.JoinUrlPath(srcDomain, dirPath)
|
||
for _, segment := range from.Segments {
|
||
if segment == nil {
|
||
continue
|
||
}
|
||
sg := new(m3u8.MediaSegment)
|
||
if laosiji {
|
||
if u, e := replaceDomainAndPath(segment.URI, srcDomain); e == nil {
|
||
sg.URI = u
|
||
} else {
|
||
sg.URI = segment.URI
|
||
}
|
||
} else {
|
||
sg.URI = utils.JoinUrlPath(base, segment.URI)
|
||
}
|
||
sg.Title = segment.Title
|
||
sg.Duration = segment.Duration
|
||
if err = media.AppendSegment(sg); err != nil {
|
||
return
|
||
}
|
||
}
|
||
_ = media.SetDefaultKey("AES-128", keyURI, iv, "", "")
|
||
media.Close()
|
||
return
|
||
}
|