package model
import (
"fmt"
)
var (
// segmentLength 分段长度,根据视频时长做分段,单位:毫秒
segmentLength = int64(6 * 60 * 1000)
_defaultSeg = &Segment{Start: 0, End: DefaultVideoEnd, Cnt: 1, Num: 1, Duration: 0}
// 弹幕内容
_xmlSegFmt = `%s`
// DefaultPage default page info
DefaultPage = &Page{Num: 1, Size: DefaultVideoEnd, Total: 1}
_xmlSegHeader = `%d%d%d%d%d%d%d`
)
// const variable
const (
// DefaultVideoEnd 当视频时长不存在或者为0时的默认视频结尾时间点
DefaultVideoEnd = 10 * 60 * 60 * 1000
// DefaultPageSize 默认分段长度
DefaultPageSize = 60 * 6 * 1000
)
// Page dm page info
type Page struct {
Num int64 `json:"num"`
Size int64 `json:"size"`
Total int64 `json:"total"`
}
// Segment dm segment struct
type Segment struct {
Start int64 `json:"ps"` // 分段起始时间
End int64 `json:"pe"` // 分段结束时间
Cnt int64 `json:"cnt"` // 总分段数
Num int64 `json:"num"` // 当前第几段
Duration int64 `json:"duration"` // 视频总时长
}
// ToXMLHeader convert segment to xml header format.
func (s *Segment) ToXMLHeader(oid int64, state, realname int32) string {
return fmt.Sprintf(_xmlSegHeader, oid, s.Start, s.End, s.Cnt, s.Num, state, realname)
}
// SegmentInfo get segment info by start time and video duration.
func SegmentInfo(ps, duration int64) (s *Segment) {
var cnt, num, pe int64
if duration == 0 {
s = _defaultSeg
return
}
cnt = duration / DefaultPageSize
if duration%DefaultPageSize > 0 {
cnt++
}
for i := int64(0); i < cnt; i++ {
if ps >= i*DefaultPageSize && ps < (i+1)*DefaultPageSize {
ps = i * DefaultPageSize
pe = (i + 1) * DefaultPageSize
num = i + 1
}
}
if pe > duration {
pe = duration
}
s = &Segment{
Start: ps,
End: pe,
Cnt: cnt,
Num: num,
Duration: duration,
}
return
}
// ToXMLSeg convert dm struct to xml.
func (d *DM) ToXMLSeg() (s string) {
if d.Content == nil {
return
}
msg := d.Content.Msg
if d.ContentSpe != nil {
msg = d.ContentSpe.Msg
}
if len(msg) == 0 {
return
}
if d.Pool == PoolSpecial {
msg = ""
}
s = fmt.Sprintf(_xmlSegFmt, d.ID, d.Attr, d.Progress, d.Content.Mode, d.Content.FontSize, d.Content.Color, d.Ctime, d.Pool, hash(d.Mid, uint32(d.Content.IP)), xmlReplace([]byte(msg)))
return
}
// ToElem convert dm struct to element.
func (d *DM) ToElem() (e *Elem) {
if d.Content == nil {
return
}
msg := d.Content.Msg
if d.ContentSpe != nil {
msg = d.ContentSpe.Msg
}
if len(msg) == 0 {
return
}
if d.Pool == PoolSpecial {
msg = ""
}
// "弹幕ID,弹幕属性,播放时间,弹幕模式,字体大小,颜色,发送时间,弹幕池,用户hash id
e = &Elem{
Attribute: fmt.Sprintf(`%d,%d,%d,%d,%d,%d,%d,%d,%s`, d.ID, d.Attr, d.Progress, d.Content.Mode, d.Content.FontSize, d.Content.Color, d.Ctime, d.Pool, hash(d.Mid, uint32(d.Content.IP))),
Content: msg,
}
return
}
// SegmentPoint 根据当前段数和视频总时长计算分段的起始时间点
func SegmentPoint(num, duration int64) (ps, pe int64) {
if duration == 0 {
ps = 0
pe = DefaultVideoEnd
return
}
pe = num * segmentLength
ps = pe - segmentLength
if pe > duration {
pe = duration
}
if ps < 0 {
ps = 0
}
return
}