mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-31 04:04:21 -04:00
Update tracker
This commit is contained in:
parent
e3fdf0af45
commit
59010797a8
@ -55,8 +55,12 @@ func (h *Handler) GetMaster(c echo.Context) error {
|
|||||||
// This route can take a few seconds to respond since it will way for at least one segment to be
|
// This route can take a few seconds to respond since it will way for at least one segment to be
|
||||||
// available.
|
// available.
|
||||||
//
|
//
|
||||||
// Path: /:path/:quality/index.m3u8
|
// Path: /:path/:video/:quality/index.m3u8
|
||||||
func (h *Handler) GetVideoIndex(c echo.Context) error {
|
func (h *Handler) GetVideoIndex(c echo.Context) error {
|
||||||
|
video, err := strconv.ParseInt(c.Param("video"), 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
quality, err := src.QualityFromString(c.Param("quality"))
|
quality, err := src.QualityFromString(c.Param("quality"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -70,7 +74,7 @@ func (h *Handler) GetVideoIndex(c echo.Context) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ret, err := h.transcoder.GetVideoIndex(path, quality, client, sha)
|
ret, err := h.transcoder.GetVideoIndex(path, int32(video), quality, client, sha)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -109,8 +113,12 @@ func (h *Handler) GetAudioIndex(c echo.Context) error {
|
|||||||
//
|
//
|
||||||
// Retrieve a chunk of a transmuxed video.
|
// Retrieve a chunk of a transmuxed video.
|
||||||
//
|
//
|
||||||
// Path: /:path/:quality/segments-:chunk.ts
|
// Path: /:path/:video/:quality/segments-:chunk.ts
|
||||||
func (h *Handler) GetVideoSegment(c echo.Context) error {
|
func (h *Handler) GetVideoSegment(c echo.Context) error {
|
||||||
|
video, err := strconv.ParseInt(c.Param("video"), 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
quality, err := src.QualityFromString(c.Param("quality"))
|
quality, err := src.QualityFromString(c.Param("quality"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -128,7 +136,14 @@ func (h *Handler) GetVideoSegment(c echo.Context) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ret, err := h.transcoder.GetVideoSegment(path, quality, segment, client, sha)
|
ret, err := h.transcoder.GetVideoSegment(
|
||||||
|
path,
|
||||||
|
int32(video),
|
||||||
|
quality,
|
||||||
|
segment,
|
||||||
|
client,
|
||||||
|
sha,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -285,7 +300,7 @@ func main() {
|
|||||||
|
|
||||||
e.GET("/:path/direct", DirectStream)
|
e.GET("/:path/direct", DirectStream)
|
||||||
e.GET("/:path/master.m3u8", h.GetMaster)
|
e.GET("/:path/master.m3u8", h.GetMaster)
|
||||||
e.GET("/:path/:quality/index.m3u8", h.GetVideoIndex)
|
e.GET("/:path/:video/:quality/index.m3u8", h.GetVideoIndex)
|
||||||
e.GET("/:path/audio/:audio/index.m3u8", h.GetAudioIndex)
|
e.GET("/:path/audio/:audio/index.m3u8", h.GetAudioIndex)
|
||||||
e.GET("/:path/:quality/:chunk", h.GetVideoSegment)
|
e.GET("/:path/:quality/:chunk", h.GetVideoSegment)
|
||||||
e.GET("/:path/audio/:audio/:chunk", h.GetAudioSegment)
|
e.GET("/:path/audio/:audio/:chunk", h.GetAudioSegment)
|
||||||
|
@ -121,7 +121,7 @@ func toSegmentStr(segments []float64) string {
|
|||||||
|
|
||||||
func (ts *Stream) run(start int32) error {
|
func (ts *Stream) run(start int32) error {
|
||||||
// Start the transcode up to the 100th segment (or less)
|
// Start the transcode up to the 100th segment (or less)
|
||||||
length, is_done := ts.file.Keyframes.Length()
|
length, is_done := ts.keyframes.Length()
|
||||||
end := min(start+100, length)
|
end := min(start+100, length)
|
||||||
// if keyframes analysys is not finished, always have a 1-segment padding
|
// if keyframes analysys is not finished, always have a 1-segment padding
|
||||||
// for the extra segment needed for precise split (look comment before -to flag)
|
// for the extra segment needed for precise split (look comment before -to flag)
|
||||||
@ -151,7 +151,7 @@ func (ts *Stream) run(start int32) error {
|
|||||||
log.Printf(
|
log.Printf(
|
||||||
"Starting transcode %d for %s (from %d to %d out of %d segments)",
|
"Starting transcode %d for %s (from %d to %d out of %d segments)",
|
||||||
encoder_id,
|
encoder_id,
|
||||||
ts.file.Path,
|
ts.file.Info.Path,
|
||||||
start,
|
start,
|
||||||
end,
|
end,
|
||||||
length,
|
length,
|
||||||
@ -169,7 +169,7 @@ func (ts *Stream) run(start int32) error {
|
|||||||
// the previous segment is played another time. the -segment_times is way more precise so it does not do the same with this one
|
// the previous segment is played another time. the -segment_times is way more precise so it does not do the same with this one
|
||||||
start_segment = start - 1
|
start_segment = start - 1
|
||||||
if ts.handle.getFlags()&AudioF != 0 {
|
if ts.handle.getFlags()&AudioF != 0 {
|
||||||
start_ref = ts.file.Keyframes.Get(start_segment)
|
start_ref = ts.keyframes.Get(start_segment)
|
||||||
} else {
|
} else {
|
||||||
// the param for the -ss takes the keyframe before the specificed time
|
// the param for the -ss takes the keyframe before the specificed time
|
||||||
// (if the specified time is a keyframe, it either takes that keyframe or the one before)
|
// (if the specified time is a keyframe, it either takes that keyframe or the one before)
|
||||||
@ -178,9 +178,9 @@ func (ts *Stream) run(start int32) error {
|
|||||||
// this can't be used with audio since we need to have context before the start-time
|
// this can't be used with audio since we need to have context before the start-time
|
||||||
// without this context, the cut loses a bit of audio (audio gap of ~100ms)
|
// without this context, the cut loses a bit of audio (audio gap of ~100ms)
|
||||||
if start_segment+1 == length {
|
if start_segment+1 == length {
|
||||||
start_ref = (ts.file.Keyframes.Get(start_segment) + float64(ts.file.Info.Duration)) / 2
|
start_ref = (ts.keyframes.Get(start_segment) + float64(ts.file.Info.Duration)) / 2
|
||||||
} else {
|
} else {
|
||||||
start_ref = (ts.file.Keyframes.Get(start_segment) + ts.file.Keyframes.Get(start_segment+1)) / 2
|
start_ref = (ts.keyframes.Get(start_segment) + ts.keyframes.Get(start_segment+1)) / 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -188,7 +188,7 @@ func (ts *Stream) run(start int32) error {
|
|||||||
if end == length {
|
if end == length {
|
||||||
end_padding = 0
|
end_padding = 0
|
||||||
}
|
}
|
||||||
segments := ts.file.Keyframes.Slice(start_segment+1, end+end_padding)
|
segments := ts.keyframes.Slice(start_segment+1, end+end_padding)
|
||||||
if len(segments) == 0 {
|
if len(segments) == 0 {
|
||||||
// we can't leave that empty else ffmpeg errors out.
|
// we can't leave that empty else ffmpeg errors out.
|
||||||
segments = []float64{9999999}
|
segments = []float64{9999999}
|
||||||
@ -222,17 +222,17 @@ func (ts *Stream) run(start int32) error {
|
|||||||
if end+1 < length {
|
if end+1 < length {
|
||||||
// sometimes, the duration is shorter than expected (only during transcode it seems)
|
// sometimes, the duration is shorter than expected (only during transcode it seems)
|
||||||
// always include more and use the -f segment to split the file where we want
|
// always include more and use the -f segment to split the file where we want
|
||||||
end_ref := ts.file.Keyframes.Get(end + 1)
|
end_ref := ts.keyframes.Get(end + 1)
|
||||||
// it seems that the -to is confused when -ss seek before the given time (because it searches for a keyframe)
|
// it seems that the -to is confused when -ss seek before the given time (because it searches for a keyframe)
|
||||||
// add back the time that would be lost otherwise
|
// add back the time that would be lost otherwise
|
||||||
// this only appens when -to is before -i but having -to after -i gave a bug (not sure, don't remember)
|
// this only appens when -to is before -i but having -to after -i gave a bug (not sure, don't remember)
|
||||||
end_ref += start_ref - ts.file.Keyframes.Get(start_segment)
|
end_ref += start_ref - ts.keyframes.Get(start_segment)
|
||||||
args = append(args,
|
args = append(args,
|
||||||
"-to", fmt.Sprintf("%.6f", end_ref),
|
"-to", fmt.Sprintf("%.6f", end_ref),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
args = append(args,
|
args = append(args,
|
||||||
"-i", ts.file.Path,
|
"-i", ts.file.Info.Path,
|
||||||
// this makes behaviors consistent between soft and hardware decodes.
|
// this makes behaviors consistent between soft and hardware decodes.
|
||||||
// this also means that after a -ss 50, the output video will start at 50s
|
// this also means that after a -ss 50, the output video will start at 50s
|
||||||
"-start_at_zero",
|
"-start_at_zero",
|
||||||
@ -258,7 +258,7 @@ func (ts *Stream) run(start int32) error {
|
|||||||
// segment_times want durations, not timestamps so we must substract the -ss param
|
// segment_times want durations, not timestamps so we must substract the -ss param
|
||||||
// since we give a greater value to -ss to prevent wrong seeks but -segment_times
|
// since we give a greater value to -ss to prevent wrong seeks but -segment_times
|
||||||
// needs precise segments, we use the keyframe we want to seek to as a reference.
|
// needs precise segments, we use the keyframe we want to seek to as a reference.
|
||||||
return seg - ts.file.Keyframes.Get(start_segment)
|
return seg - ts.keyframes.Get(start_segment)
|
||||||
})),
|
})),
|
||||||
"-segment_list_type", "flat",
|
"-segment_list_type", "flat",
|
||||||
"-segment_list", "pipe:1",
|
"-segment_list", "pipe:1",
|
||||||
@ -361,16 +361,16 @@ func (ts *Stream) GetIndex() (string, error) {
|
|||||||
#EXT-X-MEDIA-SEQUENCE:0
|
#EXT-X-MEDIA-SEQUENCE:0
|
||||||
#EXT-X-INDEPENDENT-SEGMENTS
|
#EXT-X-INDEPENDENT-SEGMENTS
|
||||||
`
|
`
|
||||||
length, is_done := ts.file.Keyframes.Length()
|
length, is_done := ts.keyframes.Length()
|
||||||
|
|
||||||
for segment := int32(0); segment < length-1; segment++ {
|
for segment := int32(0); segment < length-1; segment++ {
|
||||||
index += fmt.Sprintf("#EXTINF:%.6f\n", ts.file.Keyframes.Get(segment+1)-ts.file.Keyframes.Get(segment))
|
index += fmt.Sprintf("#EXTINF:%.6f\n", ts.keyframes.Get(segment+1)-ts.keyframes.Get(segment))
|
||||||
index += fmt.Sprintf("segment-%d.ts\n", segment)
|
index += fmt.Sprintf("segment-%d.ts\n", segment)
|
||||||
}
|
}
|
||||||
// do not forget to add the last segment between the last keyframe and the end of the file
|
// do not forget to add the last segment between the last keyframe and the end of the file
|
||||||
// if the keyframes extraction is not done, do not bother to add it, it will be retrived on the next index retrival
|
// if the keyframes extraction is not done, do not bother to add it, it will be retrived on the next index retrival
|
||||||
if is_done {
|
if is_done {
|
||||||
index += fmt.Sprintf("#EXTINF:%.6f\n", float64(ts.file.Info.Duration)-ts.file.Keyframes.Get(length-1))
|
index += fmt.Sprintf("#EXTINF:%.6f\n", float64(ts.file.Info.Duration)-ts.keyframes.Get(length-1))
|
||||||
index += fmt.Sprintf("segment-%d.ts\n", length-1)
|
index += fmt.Sprintf("segment-%d.ts\n", length-1)
|
||||||
index += `#EXT-X-ENDLIST`
|
index += `#EXT-X-ENDLIST`
|
||||||
}
|
}
|
||||||
@ -442,13 +442,13 @@ func (ts *Stream) prerareNextSegements(segment int32) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ts *Stream) getMinEncoderDistance(segment int32) float64 {
|
func (ts *Stream) getMinEncoderDistance(segment int32) float64 {
|
||||||
time := ts.file.Keyframes.Get(segment)
|
time := ts.keyframes.Get(segment)
|
||||||
distances := Map(ts.heads, func(head Head, _ int) float64 {
|
distances := Map(ts.heads, func(head Head, _ int) float64 {
|
||||||
// ignore killed heads or heads after the current time
|
// ignore killed heads or heads after the current time
|
||||||
if head.segment < 0 || ts.file.Keyframes.Get(head.segment) > time || segment >= head.end {
|
if head.segment < 0 || ts.keyframes.Get(head.segment) > time || segment >= head.end {
|
||||||
return math.Inf(1)
|
return math.Inf(1)
|
||||||
}
|
}
|
||||||
return time - ts.file.Keyframes.Get(head.segment)
|
return time - ts.keyframes.Get(head.segment)
|
||||||
})
|
})
|
||||||
if len(distances) == 0 {
|
if len(distances) == 0 {
|
||||||
return math.Inf(1)
|
return math.Inf(1)
|
||||||
|
@ -6,11 +6,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ClientInfo struct {
|
type ClientInfo struct {
|
||||||
client string
|
client string
|
||||||
path string
|
path string
|
||||||
quality *Quality
|
video *VideoKey
|
||||||
audio int32
|
audio int32
|
||||||
head int32
|
vhead int32
|
||||||
|
ahead int32
|
||||||
}
|
}
|
||||||
|
|
||||||
type Tracker struct {
|
type Tracker struct {
|
||||||
@ -56,14 +57,17 @@ func (t *Tracker) start() {
|
|||||||
old, ok := t.clients[info.client]
|
old, ok := t.clients[info.client]
|
||||||
// First fixup the info. Most routes ruturn partial infos
|
// First fixup the info. Most routes ruturn partial infos
|
||||||
if ok && old.path == info.path {
|
if ok && old.path == info.path {
|
||||||
if info.quality == nil {
|
if info.video == nil {
|
||||||
info.quality = old.quality
|
info.video = old.video
|
||||||
}
|
}
|
||||||
if info.audio == -1 {
|
if info.audio == -1 {
|
||||||
info.audio = old.audio
|
info.audio = old.audio
|
||||||
}
|
}
|
||||||
if info.head == -1 {
|
if info.vhead == -1 {
|
||||||
info.head = old.head
|
info.vhead = old.vhead
|
||||||
|
}
|
||||||
|
if info.ahead == -1 {
|
||||||
|
info.ahead = old.ahead
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,11 +80,14 @@ func (t *Tracker) start() {
|
|||||||
if old.audio != info.audio && old.audio != -1 {
|
if old.audio != info.audio && old.audio != -1 {
|
||||||
t.KillAudioIfDead(old.path, old.audio)
|
t.KillAudioIfDead(old.path, old.audio)
|
||||||
}
|
}
|
||||||
if old.quality != info.quality && old.quality != nil {
|
if old.video != info.video && old.video != nil {
|
||||||
t.KillQualityIfDead(old.path, *old.quality)
|
t.KillVideoIfDead(old.path, *old.video)
|
||||||
}
|
}
|
||||||
if old.head != -1 && Abs(info.head-old.head) > 100 {
|
if old.vhead != -1 && Abs(info.vhead-old.vhead) > 100 {
|
||||||
t.KillOrphanedHeads(old.path, old.quality, old.audio)
|
t.KillOrphanedHeads(old.path, old.video, -1)
|
||||||
|
}
|
||||||
|
if old.ahead != -1 && Abs(info.ahead-old.ahead) > 100 {
|
||||||
|
t.KillOrphanedHeads(old.path, nil, old.audio)
|
||||||
}
|
}
|
||||||
} else if ok {
|
} else if ok {
|
||||||
t.KillStreamIfDead(old.path)
|
t.KillStreamIfDead(old.path)
|
||||||
@ -100,9 +107,9 @@ func (t *Tracker) start() {
|
|||||||
|
|
||||||
if !t.KillStreamIfDead(info.path) {
|
if !t.KillStreamIfDead(info.path) {
|
||||||
audio_cleanup := info.audio != -1 && t.KillAudioIfDead(info.path, info.audio)
|
audio_cleanup := info.audio != -1 && t.KillAudioIfDead(info.path, info.audio)
|
||||||
video_cleanup := info.quality != nil && t.KillQualityIfDead(info.path, *info.quality)
|
video_cleanup := info.video != nil && t.KillVideoIfDead(info.path, *info.video)
|
||||||
if !audio_cleanup || !video_cleanup {
|
if !audio_cleanup || !video_cleanup {
|
||||||
t.KillOrphanedHeads(info.path, info.quality, info.audio)
|
t.KillOrphanedHeads(info.path, info.video, info.audio)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -163,19 +170,19 @@ func (t *Tracker) KillAudioIfDead(path string, audio int32) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Tracker) KillQualityIfDead(path string, quality Quality) bool {
|
func (t *Tracker) KillVideoIfDead(path string, video VideoKey) bool {
|
||||||
for _, stream := range t.clients {
|
for _, stream := range t.clients {
|
||||||
if stream.path == path && stream.quality != nil && *stream.quality == quality {
|
if stream.path == path && stream.video != nil && *stream.video == video {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.Printf("Nobody is watching quality %s of %s. Killing it", quality, path)
|
log.Printf("Nobody is watching %s video %d quality %s. Killing it", path, video.idx, video.quality)
|
||||||
|
|
||||||
stream, ok := t.transcoder.streams.Get(path)
|
stream, ok := t.transcoder.streams.Get(path)
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
vstream, vok := stream.videos.Get(quality)
|
vstream, vok := stream.videos.Get(video)
|
||||||
if !vok {
|
if !vok {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -183,27 +190,27 @@ func (t *Tracker) KillQualityIfDead(path string, quality Quality) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Tracker) KillOrphanedHeads(path string, quality *Quality, audio int32) {
|
func (t *Tracker) KillOrphanedHeads(path string, video *VideoKey, audio int32) {
|
||||||
stream, ok := t.transcoder.streams.Get(path)
|
stream, ok := t.transcoder.streams.Get(path)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if quality != nil {
|
if video != nil {
|
||||||
vstream, vok := stream.videos.Get(*quality)
|
vstream, vok := stream.videos.Get(*video)
|
||||||
if vok {
|
if vok {
|
||||||
t.killOrphanedeheads(&vstream.Stream)
|
t.killOrphanedeheads(&vstream.Stream, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if audio != -1 {
|
if audio != -1 {
|
||||||
astream, aok := stream.audios.Get(audio)
|
astream, aok := stream.audios.Get(audio)
|
||||||
if aok {
|
if aok {
|
||||||
t.killOrphanedeheads(&astream.Stream)
|
t.killOrphanedeheads(&astream.Stream, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Tracker) killOrphanedeheads(stream *Stream) {
|
func (t *Tracker) killOrphanedeheads(stream *Stream, is_video bool) {
|
||||||
stream.lock.Lock()
|
stream.lock.Lock()
|
||||||
defer stream.lock.Unlock()
|
defer stream.lock.Unlock()
|
||||||
|
|
||||||
@ -214,13 +221,14 @@ func (t *Tracker) killOrphanedeheads(stream *Stream) {
|
|||||||
|
|
||||||
distance := int32(99999)
|
distance := int32(99999)
|
||||||
for _, info := range t.clients {
|
for _, info := range t.clients {
|
||||||
if info.head == -1 {
|
ihead := info.vhead
|
||||||
continue
|
if is_video {
|
||||||
|
ihead = info.ahead
|
||||||
}
|
}
|
||||||
distance = min(Abs(info.head-head.segment), distance)
|
distance = min(Abs(ihead-head.segment), distance)
|
||||||
}
|
}
|
||||||
if distance > 20 {
|
if distance > 20 {
|
||||||
log.Printf("Killing orphaned head %s %d", stream.file.Path, encoder_id)
|
log.Printf("Killing orphaned head %s %d", stream.file.Info.Path, encoder_id)
|
||||||
stream.KillHead(encoder_id)
|
stream.KillHead(encoder_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,17 +53,19 @@ func (t *Transcoder) GetMaster(path string, client string, sha string) (string,
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
t.clientChan <- ClientInfo{
|
t.clientChan <- ClientInfo{
|
||||||
client: client,
|
client: client,
|
||||||
path: path,
|
path: path,
|
||||||
quality: nil,
|
video: nil,
|
||||||
audio: -1,
|
audio: -1,
|
||||||
head: -1,
|
vhead: -1,
|
||||||
|
ahead: -1,
|
||||||
}
|
}
|
||||||
return stream.GetMaster(), nil
|
return stream.GetMaster(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transcoder) GetVideoIndex(
|
func (t *Transcoder) GetVideoIndex(
|
||||||
path string,
|
path string,
|
||||||
|
video int32,
|
||||||
quality Quality,
|
quality Quality,
|
||||||
client string,
|
client string,
|
||||||
sha string,
|
sha string,
|
||||||
@ -73,13 +75,14 @@ func (t *Transcoder) GetVideoIndex(
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
t.clientChan <- ClientInfo{
|
t.clientChan <- ClientInfo{
|
||||||
client: client,
|
client: client,
|
||||||
path: path,
|
path: path,
|
||||||
quality: &quality,
|
video: &VideoKey{video, quality},
|
||||||
audio: -1,
|
audio: -1,
|
||||||
head: -1,
|
vhead: -1,
|
||||||
|
ahead: -1,
|
||||||
}
|
}
|
||||||
return stream.GetVideoIndex(quality)
|
return stream.GetVideoIndex(video, quality)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transcoder) GetAudioIndex(
|
func (t *Transcoder) GetAudioIndex(
|
||||||
@ -96,13 +99,15 @@ func (t *Transcoder) GetAudioIndex(
|
|||||||
client: client,
|
client: client,
|
||||||
path: path,
|
path: path,
|
||||||
audio: audio,
|
audio: audio,
|
||||||
head: -1,
|
vhead: -1,
|
||||||
|
ahead: -1,
|
||||||
}
|
}
|
||||||
return stream.GetAudioIndex(audio)
|
return stream.GetAudioIndex(audio)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transcoder) GetVideoSegment(
|
func (t *Transcoder) GetVideoSegment(
|
||||||
path string,
|
path string,
|
||||||
|
video int32,
|
||||||
quality Quality,
|
quality Quality,
|
||||||
segment int32,
|
segment int32,
|
||||||
client string,
|
client string,
|
||||||
@ -113,13 +118,14 @@ func (t *Transcoder) GetVideoSegment(
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
t.clientChan <- ClientInfo{
|
t.clientChan <- ClientInfo{
|
||||||
client: client,
|
client: client,
|
||||||
path: path,
|
path: path,
|
||||||
quality: &quality,
|
video: &VideoKey{video, quality},
|
||||||
audio: -1,
|
vhead: segment,
|
||||||
head: segment,
|
audio: -1,
|
||||||
|
ahead: -1,
|
||||||
}
|
}
|
||||||
return stream.GetVideoSegment(quality, segment)
|
return stream.GetVideoSegment(video, quality, segment)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transcoder) GetAudioSegment(
|
func (t *Transcoder) GetAudioSegment(
|
||||||
@ -137,7 +143,8 @@ func (t *Transcoder) GetAudioSegment(
|
|||||||
client: client,
|
client: client,
|
||||||
path: path,
|
path: path,
|
||||||
audio: audio,
|
audio: audio,
|
||||||
head: segment,
|
ahead: segment,
|
||||||
|
vhead: -1,
|
||||||
}
|
}
|
||||||
return stream.GetAudioSegment(audio, segment)
|
return stream.GetAudioSegment(audio, segment)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user