fix: playlist allocates inaccurate time to smartblocks (#3026)

### Description

In the existing logic of `retrieveMediaFiles`, the time remaining in
show is calculated incorrectly in some scenarios. Each time a duration
is subtracted from `showLimit`, it is not the duration of the files just
added, but instead the length of all files scheduled. This can cause
cases where a smart block set to "time remaining in show" fails to
completely fill the program.

For example, given a 30 minute show, and a playlist like follows:

1. a 5 minute track
2. another 5 minute track
3. smart block, set to time remaining in show

When item 1 is added, `showLimit` is reduced by 5 minutes as expected.
When item 2 is added, `showLimit` is reduced by 10 minutes (as both
items 1 and 2 are counted). As a result, the smart block is only run to
fill 15 minutes, leaving 5 minutes unfilled.

This PR resolves this issue, by recalculating `showLimit` from the
original duration rather than subtracting from a running total.

This change not does implement a new feature and should not require any
changes to documentation.

### Testing Notes

**What I did:**

- On a dev environment, set up a playlist as described above.
- Before applying this PR, created a show and scheduled playlist, and
confirmed issue was reproducible
- Applied PR and repeated, and confirmed show was filled completely.

Also repeated this testing with sample data from our production
instance.

Here is a sample schedule of the "before" case with sample data, showing
the issue

![image](https://github.com/libretime/libretime/assets/8541186/f91849fb-606f-410e-bef5-a7abc8e7b7f4)
The smartblock that scheduled the music is set to allow last track to
overflow, but 3m55s was left unscheduled.

Using the same playlist and same track library, here is a sample
schedule after the PR applied:

![image](https://github.com/libretime/libretime/assets/8541186/e9d46fbb-50e6-4859-a3de-f5a90a6021c0)
As expected, the show is fully scheduled with the last track
overflowing.
 
Additionally, I've applied this PR as a hot fix to our production
instance, where it has been running for a week without issue.

Also performed spot tests of playlists without smart blocks, smart
blocks scheduled directly (not in playlists) and autoloading playlists,
with no change in behaviour observed as a result of this change.

**How you can replicate my testing:**

Same test steps as I followed should be able to reproduce issue &
validate fix on any instance.

### **Links**

Not directly related to issue fixed by #3019, but also addresses the
issue of dead air left at end of blocks.

Co-authored-by: Kyle Robbertze <paddatrapper@users.noreply.github.com>
This commit is contained in:
Rob Hailman 2024-06-05 12:01:57 -04:00 committed by GitHub
parent 10996e847b
commit 2b43e51ed1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 2 additions and 1 deletions

View File

@ -219,6 +219,7 @@ final class Application_Model_Scheduler
// if there is a show we need to set a show limit to pass to smart blocks in case they use time remaining // if there is a show we need to set a show limit to pass to smart blocks in case they use time remaining
$showInstance = new Application_Model_ShowInstance($show); $showInstance = new Application_Model_ShowInstance($show);
$showLimit = $showInstance->getSecondsRemaining(); $showLimit = $showInstance->getSecondsRemaining();
$originalShowLimit = $showLimit;
$files = []; $files = [];
if ($type === 'audioclip') { if ($type === 'audioclip') {
@ -310,7 +311,7 @@ final class Application_Model_Scheduler
} }
// if this is a playlist it might contain multiple time remaining smart blocks // if this is a playlist it might contain multiple time remaining smart blocks
// since the schedule isn't updated until after this insert we need to keep tally // since the schedule isn't updated until after this insert we need to keep tally
$showLimit -= $this->timeLengthOfFiles($files); $showLimit = $originalShowLimit - $this->timeLengthOfFiles($files);
} }
} elseif ($type == 'stream') { } elseif ($type == 'stream') {
// need to return // need to return