diff --git a/bridges/YoutubeBridge.php b/bridges/YoutubeBridge.php index e597fe3a..c021fdc1 100644 --- a/bridges/YoutubeBridge.php +++ b/bridges/YoutubeBridge.php @@ -45,9 +45,25 @@ class YoutubeBridge extends BridgeAbstract { 'type' => 'number', 'exampleValue' => 1 ) + ), + 'global' => array( + 'duration_min' => array( + 'name' => 'min. duration (minutes)', + 'type' => 'number', + 'title' => 'Minimum duration for the video in minutes', + 'exampleValue' => 5 + ), + 'duration_max' => array( + 'name' => 'max. duration (minutes)', + 'type' => 'number', + 'title' => 'Maximum duration for the video in minutes', + 'exampleValue' => 10 + ) ) ); + private $feedName = ''; + private function ytBridgeQueryVideoInfo($vid, &$author, &$desc, &$time){ $html = $this->ytGetSimpleHTMLDOM(self::URI . "watch?v=$vid"); @@ -113,6 +129,17 @@ class YoutubeBridge extends BridgeAbstract { private function ytBridgeParseHtmlListing($html, $element_selector, $title_selector, $add_parsed_items = true) { $limit = $add_parsed_items ? 10 : INF; $count = 0; + + $duration_min = $this->getInput('duration_min') ?: -1; + $duration_min = $duration_min * 60; + + $duration_max = $this->getInput('duration_max') ?: INF; + $duration_max = $duration_max * 60; + + if($duration_max < $duration_min) { + returnClientError('Max duration must be greater than min duration!'); + } + foreach($html->find($element_selector) as $element) { if($count < $limit) { $author = ''; @@ -121,6 +148,20 @@ class YoutubeBridge extends BridgeAbstract { $vid = str_replace('/watch?v=', '', $element->find('a', 0)->href); $vid = substr($vid, 0, strpos($vid, '&') ?: strlen($vid)); $title = $this->ytBridgeFixTitle($element->find($title_selector, 0)->plaintext); + + // The duration comes in one of the formats: + // hh:mm:ss / mm:ss / m:ss + // 01:03:30 / 15:06 / 1:24 + $durationText = trim($element->find('span[class="video-time"]', 0)->plaintext); + $durationText = preg_replace('/([\d]{1,2})\:([\d]{2})/', '00:$1:$2', $durationText); + + sscanf($durationText, '%d:%d:%d', $hours, $minutes, $seconds); + $duration = $hours * 3600 + $minutes * 60 + $seconds; + + if($duration < $duration_min || $duration > $duration_max) { + continue; + } + if($title != '[Private Video]' && strpos($vid, 'googleads') === false) { if ($add_parsed_items) { $this->ytBridgeQueryVideoInfo($vid, $author, $desc, $time); @@ -168,7 +209,7 @@ class YoutubeBridge extends BridgeAbstract { } if(!empty($url_feed) && !empty($url_listing)) { - if($xml = $this->ytGetSimpleHTMLDOM($url_feed)) { + if(!$this->skipFeeds() && $xml = $this->ytGetSimpleHTMLDOM($url_feed)) { $this->ytBridgeParseXmlFeed($xml); } elseif($html = $this->ytGetSimpleHTMLDOM($url_listing)) { $this->ytBridgeParseHtmlListing($html, 'li.channels-content-item', 'h3'); @@ -182,7 +223,7 @@ class YoutubeBridge extends BridgeAbstract { $html = $this->ytGetSimpleHTMLDOM($url_listing) or returnServerError("Could not request YouTube. Tried:\n - $url_listing"); $item_count = $this->ytBridgeParseHtmlListing($html, 'tr.pl-video', '.pl-video-title a', false); - if ($item_count <= 15 && ($xml = $this->ytGetSimpleHTMLDOM($url_feed))) { + if ($item_count <= 15 && !$this->skipFeeds() && ($xml = $this->ytGetSimpleHTMLDOM($url_feed))) { $this->ytBridgeParseXmlFeed($xml); } else { $this->ytBridgeParseHtmlListing($html, 'tr.pl-video', '.pl-video-title a'); @@ -215,6 +256,10 @@ class YoutubeBridge extends BridgeAbstract { } } + private function skipFeeds() { + return ($this->getInput('duration_min') || $this->getInput('duration_max')); + } + public function getName(){ // Name depends on queriedContext: switch($this->queriedContext) {