From 74cd668301c9eee0605276ae849fde5a429d1fe7 Mon Sep 17 00:00:00 2001 From: Robbt Date: Sun, 25 Nov 2018 11:36:18 -0500 Subject: [PATCH 1/3] fixed repeating smartblock to not overflow time limit --- airtime_mvc/application/models/Block.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/airtime_mvc/application/models/Block.php b/airtime_mvc/application/models/Block.php index 37bc92341..a061dc131 100644 --- a/airtime_mvc/application/models/Block.php +++ b/airtime_mvc/application/models/Block.php @@ -1355,14 +1355,22 @@ SQL; $sizeOfInsert = count($insertList); // if block is not full and repeat_track is check, fill up more + // additionally still don't overflow the limit while (!$isBlockFull && $repeat == 1 && $sizeOfInsert > 0) { Logging::debug("adding repeated tracks."); Logging::debug("total time = " . $totalTime); $randomEleKey = array_rand(array_slice($insertList, 0, $sizeOfInsert)); - $insertList[] = $insertList[$randomEleKey]; - $totalTime += $insertList[$randomEleKey]['length']; - $totalItems++; + + $projectedTime = $totalTime + $insertList[$randomEleKey]['length']; + if ($projectedTime > $limit['time']) { + $totalItems++; + } + else { + $insertList[] = $insertList[$randomEleKey]; + $totalTime += $insertList[$randomEleKey]['length']; + $totalItems++; + } if ((!is_null($limit['items']) && $limit['items'] == count($insertList)) || $totalItems > 500 || $totalTime > $limit['time']) { break; From e7c7f215d5bea1e4a36134d50b6734efaddf441f Mon Sep 17 00:00:00 2001 From: Robbt Date: Sun, 25 Nov 2018 13:16:26 -0500 Subject: [PATCH 2/3] Added the option to allow smartblocks to overflow their time limits to the UI --- .../application/forms/SmartBlockCriteria.php | 8 +++ airtime_mvc/application/models/Block.php | 72 ++++++++++++++----- .../scripts/form/smart-block-criteria.phtml | 15 ++++ airtime_mvc/public/css/styles.css | 2 +- .../js/airtime/playlist/smart_blockbuilder.js | 22 ++++++ docs/manual/library/index.md | 6 +- 6 files changed, 106 insertions(+), 19 deletions(-) diff --git a/airtime_mvc/application/forms/SmartBlockCriteria.php b/airtime_mvc/application/forms/SmartBlockCriteria.php index b83a6e208..757b09356 100644 --- a/airtime_mvc/application/forms/SmartBlockCriteria.php +++ b/airtime_mvc/application/forms/SmartBlockCriteria.php @@ -446,6 +446,14 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm } $this->addElement($repeatTracks); + $overflowTracks = new Zend_Form_Element_Checkbox('sp_overflow_tracks'); + $overflowTracks->setDecorators(array('viewHelper')) + ->setLabel(_('Overflow Time Limit:')); + if (isset($storedCrit["overflow_tracks"])) { + $overflowTracks->setChecked($storedCrit["overflow_tracks"]["value"] == 1?true:false); + } + $this->addElement($overflowTracks); + $sort = new Zend_Form_Element_Select('sp_sort_options'); $sort->setAttrib('class', 'sp_input_select') ->setDecorators(array('viewHelper')) diff --git a/airtime_mvc/application/models/Block.php b/airtime_mvc/application/models/Block.php index a061dc131..9fe070efc 100644 --- a/airtime_mvc/application/models/Block.php +++ b/airtime_mvc/application/models/Block.php @@ -1262,13 +1262,22 @@ SQL; ->save(); - // insert repeate track option + // insert repeat track option $qry = new CcBlockcriteria(); $qry->setDbCriteria("repeat_tracks") ->setDbModifier("N/A") ->setDbValue($p_criteriaData['etc']['sp_repeat_tracks']) ->setDbBlockId($this->id) ->save(); + + // insert overflow track option + $qry = new CcBlockcriteria(); + $qry->setDbCriteria("overflow_tracks") + ->setDbModifier("N/A") + ->setDbValue($p_criteriaData['etc']['sp_overflow_tracks']) + ->setDbBlockId($this->id) + ->save(); + } /** @@ -1316,6 +1325,7 @@ SQL; $files = $info['files']; $limit = $info['limit']; $repeat = $info['repeat_tracks']; + $overflow = $info['overflow_tracks']; $insertList = array(); $totalTime = 0; @@ -1332,17 +1342,27 @@ SQL; $id = $iterator->current()->getDbId(); $fileLength = $iterator->current()->getCueLength(); $length = Application_Common_DateHelper::calculateLengthInSeconds($fileLength); - // need to check to determine if the track will make the playlist exceed the totalTime before adding it - // this can be quite processor consuming so as a workaround I used the totalItems limit to prevent the - // algorithm from parsing too many items. - $projectedTime = $totalTime + $length; - if ($projectedTime > $limit['time']) { - $totalItems++; - } - else { + // if the block is setup to allow the overflow of tracks this will add the next track even if it becomes + // longer than the time limit + if ($overflow == 1) { $insertList[] = array('id' => $id, 'length' => $length); $totalTime += $length; $totalItems++; + } + // otherwise we need to check to determine if the track will make the playlist exceed the totalTime before + // adding it this could loop through a lot of tracks so I used the totalItems limit to prevent + // the algorithm from parsing too many items. + + else { + $projectedTime = $totalTime + $length; + if ($projectedTime > $limit['time']) { + $totalItems++; + } + else { + $insertList[] = array('id' => $id, 'length' => $length); + $totalTime += $length; + $totalItems++; + } } if ((!is_null($limit['items']) && $limit['items'] == count($insertList)) || $totalItems > 500 || $totalTime > $limit['time']) { $isBlockFull = true; @@ -1361,16 +1381,24 @@ SQL; Logging::debug("total time = " . $totalTime); $randomEleKey = array_rand(array_slice($insertList, 0, $sizeOfInsert)); - - $projectedTime = $totalTime + $insertList[$randomEleKey]['length']; - if ($projectedTime > $limit['time']) { - $totalItems++; - } - else { + // this will also allow the overflow of tracks so that time limited smart blocks will schedule until they + // are longer than the time limit rather than never scheduling past the time limit + if ($overflow == 1) { $insertList[] = $insertList[$randomEleKey]; $totalTime += $insertList[$randomEleKey]['length']; $totalItems++; } + else { + $projectedTime = $totalTime + $insertList[$randomEleKey]['length']; + if ($projectedTime > $limit['time']) { + $totalItems++; + } + else { + $insertList[] = $insertList[$randomEleKey]; + $totalTime += $insertList[$randomEleKey]['length']; + $totalItems++; + } + } if ((!is_null($limit['items']) && $limit['items'] == count($insertList)) || $totalItems > 500 || $totalTime > $limit['time']) { break; @@ -1457,6 +1485,8 @@ SQL; "display_modifier"=>_($modifier)); } else if($criteria == "repeat_tracks") { $storedCrit["repeat_tracks"] = array("value"=>$value); + } else if($criteria == "overflow_tracks") { + $storedCrit["overflow_tracks"] = array("value"=>$value); } else if($criteria == "sort") { $storedCrit["sort"] = array("value"=>$value); } else { @@ -1622,17 +1652,25 @@ SQL; } $repeatTracks = 0; + $overflowTracks = 0; + if (isset($storedCrit['repeat_tracks'])) { $repeatTracks = $storedCrit['repeat_tracks']['value']; } - + + if (isset($storedCrit['overflow_tracks'])) { + $overflowTracks = $storedCrit['overflow_tracks']['value']; + } + + try { $out = $qry->setFormatter(ModelCriteria::FORMAT_ON_DEMAND)->find(); - return array("files"=>$out, "limit"=>$limits, "repeat_tracks"=> $repeatTracks, "count"=>$out->count()); + return array("files"=>$out, "limit"=>$limits, "repeat_tracks"=> $repeatTracks, "overflow_tracks"=> $overflowTracks, "count"=>$out->count()); } catch (Exception $e) { Logging::info($e); } + } public static function organizeSmartPlaylistCriteria($p_criteria) { diff --git a/airtime_mvc/application/views/scripts/form/smart-block-criteria.phtml b/airtime_mvc/application/views/scripts/form/smart-block-criteria.phtml index 3f46c828a..7dccbb7d6 100644 --- a/airtime_mvc/application/views/scripts/form/smart-block-criteria.phtml +++ b/airtime_mvc/application/views/scripts/form/smart-block-criteria.phtml @@ -33,6 +33,21 @@ +
+ +
+
+ element->getElement('sp_overflow_tracks')?> + element->getElement("sp_overflow_tracks")->hasErrors()) : ?> + element->getElement("sp_overflow_tracks")->getMessages() as $error): ?> + + + + + + +
+
diff --git a/airtime_mvc/public/css/styles.css b/airtime_mvc/public/css/styles.css index e9e8ac4ff..c227fdd43 100644 --- a/airtime_mvc/public/css/styles.css +++ b/airtime_mvc/public/css/styles.css @@ -203,7 +203,7 @@ img.logo .airtime_auth_help_icon, .custom_auth_help_icon, .stream_username_help_icon, .playlist_type_help_icon, .repeat_tracks_help_icon, .show_linking_help_icon, -.admin_username_help_icon, .stream_type_help_icon, +.admin_username_help_icon, .stream_type_help_icon, .overflow_tracks_help_icon, .show_timezone_help_icon{ cursor: help; position: relative; diff --git a/airtime_mvc/public/js/airtime/playlist/smart_blockbuilder.js b/airtime_mvc/public/js/airtime/playlist/smart_blockbuilder.js index 15ca8b52f..88aaa5e6f 100644 --- a/airtime_mvc/public/js/airtime/playlist/smart_blockbuilder.js +++ b/airtime_mvc/public/js/airtime/playlist/smart_blockbuilder.js @@ -529,6 +529,28 @@ function setupUI() { at: "right center" } }); + + + $(".overflow_tracks_help_icon").qtip({ + content: { + text: sprintf($.i18n._("The smartblock will normally schedule up to but not over the time limit. This will usually result in a smartblock that is less than the time limit set if there are no tracks short enough to fill the remaining time. Enable this option if you want to add tracks until it is longer than the smartblock. Any tracks longer than the smartblock limit maybe cut off during playback if they exceed a shows boundaries."), PRODUCT_NAME) + }, + hide: { + delay: 500, + fixed: true + }, + style: { + border: { + width: 0, + radius: 4 + }, + classes: "ui-tooltip-dark ui-tooltip-rounded" + }, + position: { + my: "left bottom", + at: "right center" + } + }); } /* Utilizing jQuery this function finds the #datetime_select element on the given row diff --git a/docs/manual/library/index.md b/docs/manual/library/index.md index 3c1a79249..579152226 100644 --- a/docs/manual/library/index.md +++ b/docs/manual/library/index.md @@ -102,7 +102,11 @@ To add an AND criteria, such as **Creator** containing *jimi* AND BPM in the ran By default, a smart block will not contain repeated items, which will limit the duration of the block if you do not have sufficient items meeting the specified criteria in your **Library**. To override the default behaviour, check the **Allow Repeat Tracks** box. The **Sort tracks by** menu offers the options of **random**, **newest** or **oldest** items first. -Smart block repeat tracks +![](static/Screenshot582-Smart_block_repeat_tracks.png) + +In addition Smart Blocks by default will never overflow the Time Limit. For instance if you set a time limit of 1 hour. It will add tracks to the schedule until it can't add any more tracks without exceeding the hour. This is to prevent tracks from being cut-off because they exceed the time limit of a show. + +If you want a smartblock to schedule tracks until it is longer than the Time Limit you can check Overflow Time Limit. This will make LibreTime add tracks that meet the criteria until it equals or is longer than the time limit. The was the default behaviour with the Airtime software. If you have a large number of files which meet the criteria that you specify, you may wish to limit the duration of the smart block using the **Limit to** field, so that it fits within the show you have in mind. Select **hours**, **minutes** or **items** from the drop-down menu, and click the **Generate** button again, if it is a static smart block. Then click the **Save** button. From 4f41b539b50f65314a14e34309d3c78c667ae044 Mon Sep 17 00:00:00 2001 From: Robbt Date: Sun, 25 Nov 2018 18:28:14 -0500 Subject: [PATCH 3/3] Made overflow tracks set checked simpler --- airtime_mvc/application/forms/SmartBlockCriteria.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/airtime_mvc/application/forms/SmartBlockCriteria.php b/airtime_mvc/application/forms/SmartBlockCriteria.php index 757b09356..c05bf6cf2 100644 --- a/airtime_mvc/application/forms/SmartBlockCriteria.php +++ b/airtime_mvc/application/forms/SmartBlockCriteria.php @@ -450,7 +450,7 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm $overflowTracks->setDecorators(array('viewHelper')) ->setLabel(_('Overflow Time Limit:')); if (isset($storedCrit["overflow_tracks"])) { - $overflowTracks->setChecked($storedCrit["overflow_tracks"]["value"] == 1?true:false); + $overflowTracks->setChecked($storedCrit["overflow_tracks"]["value"] == 1); } $this->addElement($overflowTracks);