A scheduled channel that fell more than a few seconds behind joined its next airing part way in, losing however much it was late of the start. Up to two minutes late, the next airing now plays from its top and loses that much of its end instead, as a broadcaster running long would.
- commit
- e268f0f0c355959355ff9ca4f6dc8fff71299eea
- parent
- 2bfb8c61c376ae5f166359c42abb93f088bf5325
- author
- FelineStateMachine <226808055+FelineStateMachine@users.noreply.github.com>
- kind
- fix risk score 1.8 of 3, Jev's estimate
| M | internal/ | 13 | +++++++++++++ |
| M | internal/ | 13 | +++++++++++-- |
@@ -282,6 +282,19 @@ func TestScheduledCue(t *testing.T) {
282282 t.Errorf("after the block: %+v", c)283283 }284284 285+ // Running late, the next episode starts at its top and loses its end;286+ // much later, it's joined part way through.287+ cue = scheduled("test", f.lineup)288+ run(cue, at(5, 20, 0, 0), true)289+ if c := run(cue, at(5, 21, 1, 30), true); c != (cued{false, "Episode 1", 3510, 0}) {290+ t.Errorf("late: %+v", c)291+ }292+ cue = scheduled("test", f.lineup)293+ run(cue, at(5, 20, 0, 0), true)294+ if c := run(cue, at(5, 21, 5, 0), true); c != (cued{false, "Episode 1", 3300, 300}) {295+ t.Errorf("very late: %+v", c)296+ }297+285298 // Tuning in part way through.286299 cue = scheduled("test", f.lineup)287300 if c := run(cue, at(5, 20, 10, 0), true); c != (cued{false, "Episode 3", 3000, 600}) {@@ -284,8 +284,12 @@ func play(ctx context.Context, w io.Writer, ffmpeg, label string, get lineup) er
284284 285285 const (286286 // cueSlack is how far a scheduled stream may fall behind the clock287- // before it skips ahead to catch up.287+ // before it catches up.288288 cueSlack = 5 * time.Second289+ // maxCatchUp is how late a stream may be and still catch up as a290+ // broadcaster does, playing the next airing from its top and cutting291+ // its end (the credits), rather than cutting into it (its cold open).292+ maxCatchUp = 2 * time.Minute289293 // slateChunk is the longest a slate plays before the schedule is290294 // looked at again, so changes to it show.291295 slateChunk = time.Minute@@ -355,8 +359,13 @@ func scheduled(label string, get lineup) cueFunc {
355359 if next := items[(on.I+1)%len(items)].Captions; next != nil {356360 next.start()357361 }362+ it, skip := items[on.I], max(framesIn(t.Sub(on.Start)), 0)363+ if late := t.Sub(on.Start); skip > 0 && on.Start.Equal(end) && late <= maxCatchUp && late < frameDuration(it.Frames)/2 {364+ log.Printf("%s: %s late, cutting the end of %s to catch up", label, late.Round(time.Second), airingName(it))365+ it.Frames, skip = it.Frames-skip, 0366+ }358367 last, end = on, on.End359- return items[on.I], max(framesIn(t.Sub(on.Start)), 0), nil368+ return it, skip, nil360369 }361370 }362371