From 0ba25294f29973aebfd874a6438a108def3fa42d Mon Sep 17 00:00:00 2001 From: DanieL Date: Wed, 10 Aug 2022 14:09:36 -0300 Subject: [PATCH] EPG updates --- .gitignore | 1 - install/checkConfiguration.php | 2 +- install/database.sql | 2 + objects/aVideoEncoderReceiveImage.json.php | 2 +- objects/functions.php | 5 + objects/video.php | 117 ++++-- objects/videoAddNew.json.php | 3 + plugin/AD_Server/AD_Server.php | 52 +-- plugin/AD_Server/footer.php | 45 +-- plugin/Bookmark/Bookmark.php | 10 - plugin/Bookmark/footer.php | 31 +- plugin/Layout/Layout.php | 27 ++ plugin/Layout/epg.php | 343 ---------------- plugin/PlayerSkins/PlayerSkins.php | 73 +++- plugin/PlayerSkins/actionButton.php | 11 + plugin/PlayerSkins/actionButtonGallery.php | 11 + plugin/PlayerSkins/epg.php | 443 +++++++++++++++++++++ plugin/PlayerSkins/epgButton.css | 14 + plugin/PlayerSkins/epgButton.js | 20 + updatedb/updateDb.v12.1.sql | 13 + view/css/main.css | 24 +- view/js/script.js | 8 +- view/managerVideos_body.php | 4 + view/managerVideos_form.php | 13 +- 24 files changed, 783 insertions(+), 491 deletions(-) delete mode 100644 plugin/Layout/epg.php create mode 100644 plugin/PlayerSkins/actionButton.php create mode 100644 plugin/PlayerSkins/actionButtonGallery.php create mode 100644 plugin/PlayerSkins/epg.php create mode 100644 plugin/PlayerSkins/epgButton.css create mode 100644 plugin/PlayerSkins/epgButton.js create mode 100644 updatedb/updateDb.v12.1.sql diff --git a/.gitignore b/.gitignore index a205de8f77..e8c083523a 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,6 @@ /plugin/AutoShare/ /plugin/Backup/ /plugin/Blackblaze_B2/ -/plugin/Bookmark/ /plugin/Chat2/ /plugin/CountryRedirect/ /plugin/CreateUserManager/ diff --git a/install/checkConfiguration.php b/install/checkConfiguration.php index 83686c45dc..57b4d61dc1 100644 --- a/install/checkConfiguration.php +++ b/install/checkConfiguration.php @@ -4,7 +4,7 @@ if (file_exists("../videos/configuration.php")) { exit; } -$installationVersion = "12.0"; +$installationVersion = "12.1"; error_log("Installation: ".__LINE__." ". json_encode($_POST)); header('Content-Type: application/json'); diff --git a/install/database.sql b/install/database.sql index f7d21f63b5..86295c76ee 100644 --- a/install/database.sql +++ b/install/database.sql @@ -181,6 +181,7 @@ CREATE TABLE IF NOT EXISTS `videos` ( `likes` INT(11) NULL DEFAULT NULL, `dislikes` INT(11) NULL DEFAULT NULL, `users_id_company` INT(11) NULL DEFAULT NULL, + `epg_link` VARCHAR(400) NULL DEFAULT NULL, PRIMARY KEY (`id`), INDEX `fk_videos_users1_idx` (`users_id_company` ASC), INDEX `fk_videos_users_idx` (`users_id` ASC), @@ -197,6 +198,7 @@ CREATE TABLE IF NOT EXISTS `videos` ( INDEX `videos_dislikes_index` (`dislikes` ASC), INDEX `fk_videos_live_transmitions_history1_idx` (`live_transmitions_history_id` ASC), INDEX `total_sec_watchinindex` (`total_seconds_watching` ASC), + INDEX `index_epg_link` (`epg_link` ASC), FULLTEXT INDEX `index17vname` (`title`), FULLTEXT INDEX `index18vdesc` (`description`), CONSTRAINT `fk_videos_sites1` diff --git a/objects/aVideoEncoderReceiveImage.json.php b/objects/aVideoEncoderReceiveImage.json.php index 34497a05a0..0a7d422279 100644 --- a/objects/aVideoEncoderReceiveImage.json.php +++ b/objects/aVideoEncoderReceiveImage.json.php @@ -24,7 +24,7 @@ if (empty($_POST)) { useVideoHashOrLogin(); if (!User::canUpload()) { - $obj->msg = __("Permission denied to receive a file: " . json_encode($_POST)); + $obj->msg = __("Permission denied to receive a image: " . json_encode($_POST)); _error_log("ReceiveImage: " . $obj->msg); die(json_encode($obj)); } diff --git a/objects/functions.php b/objects/functions.php index 55c7101649..f215c63374 100644 --- a/objects/functions.php +++ b/objects/functions.php @@ -1620,6 +1620,11 @@ function im_resize($file_src, $file_dest, $wd, $hd, $q = 80) { if (empty($file_dest)) { return false; } + + if(preg_match('/notfound_/', $file_dest)){ + return false; + } + if (!file_exists($file_src)) { _error_log("im_resize: Source not found: {$file_src}"); return false; diff --git a/objects/video.php b/objects/video.php index f8c72c78e0..a9f0cbeca5 100644 --- a/objects/video.php +++ b/objects/video.php @@ -64,6 +64,7 @@ if (!class_exists('Video')) { protected $dislikes; protected $users_id_company; protected $created; + protected $epg_link; public static $statusDesc = [ 'a' => 'Active', 'k' => 'Active and Encoding', @@ -571,7 +572,7 @@ if (!class_exists('Video')) { } } } - return [$videoFound, audioFound]; + return [$videoFound, $audioFound]; } public function setClean_title($clean_title) { @@ -2767,7 +2768,7 @@ if (!class_exists('Video')) { } $name = "getVideoTags{$video_id}"; - + if (!class_exists('Cache')) { AVideoPlugin::loadPlugin('Cache'); } @@ -4205,13 +4206,13 @@ if (!class_exists('Video')) { $return->posterPortraitPath = "{$path['path']}{$path['filename']}_portrait.jpg"; $return->posterPortrait = "{$path['url']}{$path['filename']}_portrait.jpg"; } - - if(defaultIsLandscape()){ - $return->default = array('url'=>$return->posterLandscape, 'path'=>$return->posterLandscapePath); - }else{ - $return->default = array('url'=>$return->posterPortrait, 'path'=>$return->posterPortraitPath); + + if (defaultIsLandscape()) { + $return->default = array('url' => $return->posterLandscape, 'path' => $return->posterLandscapePath); + } else { + $return->default = array('url' => $return->posterPortrait, 'path' => $return->posterPortraitPath); } - + return $return; } @@ -5443,15 +5444,15 @@ if (!class_exists('Video')) { static function getSeoTags($videos_id) { global $advancedCustom, $_getSeoTags; - - if(!isset($_getSeoTags)){ + + if (!isset($_getSeoTags)) { $_getSeoTags = array(); } - - if(!empty($_getSeoTags[$videos_id])){ + + if (!empty($_getSeoTags[$videos_id])) { return $_getSeoTags[$videos_id]; } - + $video = new Video('', '', $videos_id); $H1_title = getSEOTitle($video->getTitle()); @@ -5468,19 +5469,19 @@ if (!class_exists('Video')) { } $keywords = strip_tags($advancedCustom->keywords); - if(AVideoPlugin::isEnabledByName('VideoTags')){ + if (AVideoPlugin::isEnabledByName('VideoTags')) { //$keywords .= ", $videos_id"; $tags = VideoTags::getArrayFromVideosId($videos_id); - if(!empty($tags)){ - if(!empty($keywords)){ + if (!empty($tags)) { + if (!empty($keywords)) { $keywords .= ', '; } - $keywords .= implode(', ',$tags); + $keywords .= implode(', ', $tags); } } - + $image = Video::getImageFromID($videos_id); - + $tags = array( 'h1' => $H1_title, 'h2' => $H2_Short_summary, @@ -5498,38 +5499,98 @@ if (!class_exists('Video')) { 'uploadDate' => $video->getCreated(), 'description' => $MetaDescription ); - + $head = ''; foreach ($meta as $key => $value) { - if(empty($value)){ + if (empty($value)) { continue; } - $head .= ''; + $head .= ''; } $body = '
'; foreach ($tags as $key => $value) { - if(empty($value)){ + if (empty($value)) { continue; } $body .= "<{$key}>{$value}"; } - + foreach ($itemprops as $key => $value) { - if(empty($value)){ + if (empty($value)) { continue; } - $body .= ""; + $body .= ""; } $body .= '
'; $response = array(); - $response['assets'] = array('tags'=>$tags, 'meta'=>$meta, 'itemprops'=>$itemprops); + $response['assets'] = array('tags' => $tags, 'meta' => $meta, 'itemprops' => $itemprops); $response['head'] = $head; $response['body'] = $body; $_getSeoTags[$videos_id] = $response; //var_dump($_getSeoTags);exit; return $_getSeoTags[$videos_id]; - + } + public function getEpg_link() { + return $this->epg_link; + } + + public function setEpg_link($epg_link): void { + $this->epg_link = $epg_link; + } + + static public function getAllActiveEPGs() { + global $config; + $sql = "SELECT * FROM `videos` WHERE epg_link IS NOT NULL AND epg_link != '';"; + $res = sqlDAL::readSql($sql); + $fullResult2 = sqlDAL::fetchAllAssoc($res); + sqlDAL::close($res); + + $rows = []; + if ($res !== false) { + foreach ($fullResult2 as $row) { + $rows[] = $row; + } + } else { + die($sql . '\nError : (' . $global['mysqli']->errno . ') ' . $global['mysqli']->error); + } + return $rows; + } + + static public function getEPG($videos_id) { + global $config, $_getEPG; + + if(!isset($_getEPG)){ + $_getEPG = array(); + } + + if(!isset($_getEPG[$videos_id])){ + $sql = "SELECT * FROM `videos` WHERE id = ? AND epg_link IS NOT NULL AND epg_link != ''"; + $res = sqlDAL::readSql($sql, 'i', array($videos_id)); + + $video = sqlDAL::fetchAssoc($res); + sqlDAL::close($res); + if(empty($video) || !isValidURL($video['epg_link'])){ + $_getEPG[$videos_id] = false; + }else{ + $_getEPG[$videos_id] = $video['epg_link']; + } + } + return $_getEPG[$videos_id]; + } + + + + static public function getEPGLink($videos_id) { + global $global; + $epg = self::getEPG($videos_id); + if(!empty($epg)){ + $url = $global['webSiteRootURL'].'plugin/PlayerSkins/epg.php'; + $url = addQueryStringParameter($url, 'videos_id', $videos_id); + return $url; + }else{ + return false; + } } } diff --git a/objects/videoAddNew.json.php b/objects/videoAddNew.json.php index fb92824fe9..6c5b931f95 100644 --- a/objects/videoAddNew.json.php +++ b/objects/videoAddNew.json.php @@ -71,6 +71,9 @@ if (!empty($_POST['videoLink'])) { $_POST['videoLinkType'] = "linkVideo"; } $obj->setVideoLink($_POST['videoLink']); + if(empty($_POST['epg_link']) || isValidURL($_POST['epg_link'])){ + $obj->setEpg_link($_POST['epg_link']); + } if (in_array($extension, $audioLinks) || in_array($extension, $videoLinks)) { if (in_array($extension, $audioLinks)) { diff --git a/plugin/AD_Server/AD_Server.php b/plugin/AD_Server/AD_Server.php index 0d6bc4d936..bd651ab3ef 100644 --- a/plugin/AD_Server/AD_Server.php +++ b/plugin/AD_Server/AD_Server.php @@ -10,8 +10,8 @@ global $global; require_once $global['systemRootPath'] . 'plugin/Plugin.abstract.php'; require_once $global['systemRootPath'] . 'plugin/AD_Server/Objects/VastCampaigns.php'; -class AD_Server extends PluginAbstract -{ +class AD_Server extends PluginAbstract { + public function getTags() { return [ PluginTags::$MONETIZATION, @@ -98,7 +98,7 @@ class AD_Server extends PluginAbstract return $obj; } - static function addVideoIdIntoCampaignId($videos_id, $vast_campaigns_id){ + static function addVideoIdIntoCampaignId($videos_id, $vast_campaigns_id) { if (!empty($vast_campaigns_id)) { $vc = new VastCampaigns($vast_campaigns_id); if (!empty($vc->getName())) { @@ -175,9 +175,6 @@ class AD_Server extends PluginAbstract $css = '' . ''; - if (!empty($obj->showMarkers)) { - $css .= ''; - } $css .= ''; return $css; } @@ -232,44 +229,26 @@ class AD_Server extends PluginAbstract $vmapURL = self::addVMAPS($vmapURL, $vmaps); //var_dump($vmapURL, $vmaps);exit; PlayerSkins::setIMAADTag($vmapURL); - $onPlayerReady = ""; if (!empty($obj->showMarkers)) { - $onPlayerReady .= " - player.markers({ - markerStyle: { - 'width': '5px', - 'background-color': 'yellow' - }, - markerTip: { - display: true, - text: function (marker) { - return marker.text; - } - }, - markers: ["; + $rows = array(); foreach ($vmaps as $value) { $vastCampaingVideos = new VastCampaignsVideos($value['VAST']['campaing']); $video = new Video("", "", $vastCampaingVideos->getVideos_id()); if (!empty($video_length) && $value['timeOffsetSeconds'] >= $video_length) { $value['timeOffsetSeconds'] = $video_length - 5; } - - $onPlayerReady .= "{time: {$value['timeOffsetSeconds']}, text: \"" . addcslashes($video->getTitle(), '"') . "\"},"; + $rows[] = array('timeInSeconds' => $value['timeOffsetSeconds'], 'name' => $video->getTitle()); } - $onPlayerReady .= "]});"; + + PlayerSkins::createMarker($rows); } - - PlayerSkins::getStartPlayerJS($onPlayerReady); $js = ''; $js .= ''; $js .= ''; $js .= ''; - if (!empty($obj->showMarkers)) { - $js .= ''; - } return $js; } @@ -413,21 +392,22 @@ class AD_Server extends PluginAbstract } public function onNewVideo($videos_id) { - if(!empty($_REQUEST['return_vars'])){ + if (!empty($_REQUEST['return_vars'])) { $json = json_decode($_REQUEST['return_vars']); - if(!empty($json) && !empty($json->callback)){ + if (!empty($json) && !empty($json->callback)) { $callback = json_decode(base64_decode($json->callback)); - if(!empty($callback) && !empty($callback->vast_campaigns_id)){ + if (!empty($callback) && !empty($callback->vast_campaigns_id)) { return self::addVideoIdIntoCampaignId($videos_id, $callback->vast_campaigns_id); } } } return false; } + } -class VMAP -{ +class VMAP { + public $timeOffset; public $timeOffsetSeconds; public $VAST; @@ -468,10 +448,11 @@ class VMAP $secs = floor($seconds % 60); return sprintf('%02d:%02d:%02d.000', $hours, $mins, $secs); } + } -class VAST -{ +class VAST { + public $id; public $campaing; @@ -484,4 +465,5 @@ class VAST $this->campaing = false; } } + } diff --git a/plugin/AD_Server/footer.php b/plugin/AD_Server/footer.php index 30b617717d..e152a866df 100644 --- a/plugin/AD_Server/footer.php +++ b/plugin/AD_Server/footer.php @@ -7,39 +7,7 @@ var options = {id: 'mainVideo', adTagUrl: 'plugin/AD_Server/VMAP.php?video_length=&vmap_id=&random='}; player.ima(options); $(document).ready(function () { -showMarkers)) { -?> - $.getScript("plugin/AD_Server/videojs-markers/videojs-markers.js", function (data, textStatus, jqxhr) { - if (typeof player == 'undefined') { - player = videojs('mainVideo'); - } - player.markers({ - markerStyle: { - 'width': '5px', - 'background-color': 'yellow' - }, - markerTip: { - display: true, - text: function (marker) { - return marker.text; - } - }, - markers: [ - VAST->campaing); - $video = new Video("", "", $vastCampaingVideos->getVideos_id()); ?> - {time: timeOffsetSeconds; ?>, text: "getTitle(), '"'); ?>"}, - - ] - }); - }); - // Remove controls from the player on iPad to stop native controls from stealing // our click var contentPlayer = document.getElementById('content_video_html5_api'); @@ -65,3 +33,16 @@ if (!empty($obj->showMarkers)) { }, 100); }); +showMarkers)) { + + $rows = array(); + foreach ($vmaps as $value) { + $vastCampaingVideos = new VastCampaignsVideos($value->VAST->campaing); + $video = new Video("", "", $vastCampaingVideos->getVideos_id()); + $rows[] = array('timeInSeconds'=>$value->timeOffsetSeconds,'name'=>$video->getTitle()); + } + + PlayerSkins::createMarker($rows); +} +?> \ No newline at end of file diff --git a/plugin/Bookmark/Bookmark.php b/plugin/Bookmark/Bookmark.php index 784e1b86c6..06ece30409 100644 --- a/plugin/Bookmark/Bookmark.php +++ b/plugin/Bookmark/Bookmark.php @@ -23,16 +23,6 @@ class Bookmark extends PluginAbstract { $filename = $global['systemRootPath'] . 'plugin/Bookmark/pluginMenu.html'; return file_get_contents($filename); } - - - public function getHeadCode() { - if(empty($_GET['videoName'])){ - return false; - } - global $global; - $css = ''; - return $css; - } public function getFooterCode() { if(empty($_GET['videoName'])){ diff --git a/plugin/Bookmark/footer.php b/plugin/Bookmark/footer.php index e0c7df6b71..800a7c3aca 100644 --- a/plugin/Bookmark/footer.php +++ b/plugin/Bookmark/footer.php @@ -1,30 +1,3 @@ - - \ No newline at end of file +PlayerSkins::createMarker($rows); +?> \ No newline at end of file diff --git a/plugin/Layout/Layout.php b/plugin/Layout/Layout.php index ab2ab45529..2db79fded9 100644 --- a/plugin/Layout/Layout.php +++ b/plugin/Layout/Layout.php @@ -527,6 +527,7 @@ class Layout extends PluginAbstract { //return $html; //var_dump(self::$tags['script']);exit; if (!empty(self::$tags['tagcss'])) { + self::$tags['tagcss'] = self::removeDuplicated(self::$tags['tagcss']); $html = str_replace('', PHP_EOL.implode(PHP_EOL, array_unique(self::$tags['tagcss'])) . '', $html); } //return $html; @@ -534,6 +535,7 @@ class Layout extends PluginAbstract { $html = str_replace('', '', $html); } if (!empty(self::$tags['tagscript'])) { + self::$tags['tagscript'] = self::removeDuplicated(self::$tags['tagscript']); usort(self::$tags['tagscript'], "_sortJS"); $html = str_replace('', PHP_EOL.implode(PHP_EOL, array_unique(self::$tags['tagscript'])) . '', $html); } @@ -682,6 +684,31 @@ class Layout extends PluginAbstract { echo $html; } + static private function removeDuplicated($list) { + $cleanList = array(); + $srcList = array(); + foreach ($list as $key => $value) { + preg_match('/setURL($epg); - $Parser->temp_dir = getCacheDir(); - try { - $Parser->parseURL(); - $epgData = $Parser->getEpgdata(); - $channels = $Parser->getChannels(); - - //$Parser->setTargetTimeZone('Europe/Skopje'); - // $Parser->setChannelfilter('prosiebenmaxx.de'); //optional - // $Parser->setIgnoreDescr('Keine Details verfügbar.'); //optional - foreach ($channels as $key => $value) { - $channels[$key]['epgData'] = array(); - foreach ($epgData as $key2 => $program) { - if ($program['channel'] != $value['id']) { - continue; - } - $minutes = getDurationInMinutes(date('Y-d-m 00:00:00'), $program['stop']); - if ($minutes > 0) { - $channels[$key]['epgData'][] = $program; - setMinDate($program['start']); - setMaxDate($program['stop']); - } - unset($epgData[$key2]); - } - usort($channels[$key]['epgData'], "cmpPrograms"); - $channelsList[] = $channels[$key]; - } - } catch (Exception $e) { - throw new \RuntimeException($e); - } - } - usort($channelsList, "cmpChannels"); - - $_channels = $channelsList; - $_channelsMinDate = $minDate; - $_channelsMaxDate = $maxDate; - $epgData = new stdClass(); - $epgData->channels = $_channels; - $epgData->channelsMinDate = $_channelsMinDate; - $epgData->channelsMaxDate = $_channelsMaxDate; - - //var_dump($epgData);exit; - ObjectYPT::setCache($cacheName, $epgData); -} -//var_dump($epgData);exit; -//var_dump($channelsList);exit; -function cmpPrograms($a, $b) { - $AStartTime = strtotime($a['start']); - $BStartTime = strtotime($b['start']); - if ($AStartTime == $BStartTime) { - return 0; - } - return ($AStartTime < $BStartTime) ? -1 : 1; -} - -function cmpChannels($a, $b) { - return strcasecmp($a['display-name'], $b['display-name']); -} - -function getDurationInMinutes($start, $stop) { - $timeStart = strtotime($start); - $timeStop = strtotime($stop); - //var_dump(date('Y-m-d H:i:s',$timeStart), date('Y-m-d H:i:s',$timeStop)); - $seconds = $timeStop - $timeStart; - - $minutes = intval($seconds / 60); - return $minutes; -} - -function setMaxDate($date) { - global $maxDate; - - if (empty($maxDate)) { - $maxDate = 0; - } - - $newDate = strtotime($date); - if ($newDate > $maxDate) { - $maxDate = $newDate; - } -} - -function setMinDate($date) { - global $minDate; - - if (empty($minDate)) { - $minDate = strtotime('+30 days'); - } - - $newDate = strtotime($date); - if ($newDate < $minDate) { - $minDate = $newDate; - } -} - -function createEPG($channel) { - global $minuteSize, $Date; - $channel = object_to_array($channel); - $displayname = $channel['display-name']; - $channelId = $channel['id']; - $firstProgram = $channel['epgData'][0]; - ?> -
-
- -
-
- $program) { - $minutesSinceZeroTime = getDurationInMinutes("{$Date} 00:00:00", $program['start']); - if ($minutesSinceZeroTime < 0) { - continue; - } - $minutes = getDurationInMinutes($program['start'], $program['stop']); - $left = ($minuteSize * $minutesSinceZeroTime) + $timeLineElementSize; - $width = ($minuteSize * $minutes); - if ($width <= $minimumWidth) { - $text = ""; - } else { - $startTime = date('m-d H:i', strtotime($program['start'])); - $stopTime = date('m-d H:i', strtotime($program['stop'])); - $text = "{$program['title']}
{$minutes} Min
"; - } - - echo "
{$text}
"; - } - ?> -
-
- - - - EPG - - - - - -
-
-
- channelsMaxDate; - //var_dump($lastStopDate);exit; - $maxDate = 0; - $count = 0; - $countElements = 0; - while ($lastStopDate > $maxDate && $count < 600) { - $tomorrowDate = date('Y-m-d', strtotime("+{$count} days")); - for ($i = 0; $i < 24; $i++) { - $hour = $i; - $amPm = 'AM'; - if ($i > 12) { - $hour = $i - 12; - $amPm = 'PM'; - } - $hour = sprintf("%02d", $hour); - - for ($j = 0; $j < 60; $j += $timeLineElementMinutes) { - $minutes = sprintf("%02d", $j); - $text = "{$tomorrowDate}
{$hour}:{$minutes} {$amPm}
"; - $left = ($countElements * $timeLineElementSize) + $timeLineElementSize; - echo "
{$text}
"; - - setMaxDate("$tomorrowDate $i:$minutes:00"); - $countElements++; - if ($lastStopDate < $maxDate) { - break; - } - } - if ($lastStopDate < $maxDate) { - break; - } - } - $count++; - } - ?> -
-
-
- channels as $channel) { - createEPG($channel); - } - ?> -
-
-
- - - - - \ No newline at end of file diff --git a/plugin/PlayerSkins/PlayerSkins.php b/plugin/PlayerSkins/PlayerSkins.php index 4c63d46309..1523123e24 100644 --- a/plugin/PlayerSkins/PlayerSkins.php +++ b/plugin/PlayerSkins/PlayerSkins.php @@ -5,6 +5,8 @@ require_once $global['systemRootPath'] . 'plugin/AVideoPlugin.php'; class PlayerSkins extends PluginAbstract { + static public $hasMarks = false; + public function getTags() { return array( PluginTags::$FREE, @@ -264,6 +266,10 @@ class PlayerSkins extends PluginAbstract { $css .= ""; } } + $videos_id = getVideos_id(); + if (!empty($videos_id) && Video::getEPG($videos_id)) { + $css .= ""; + } $url = urlencode(getSelfURI()); $oembed = ''; @@ -315,6 +321,10 @@ class PlayerSkins extends PluginAbstract { $js .= ""; } } + $videos_id = getVideos_id(); + if (!empty($videos_id) && Video::getEPG($videos_id)) { + PlayerSkins::getStartPlayerJS(file_get_contents("{$global['systemRootPath']}plugin/PlayerSkins/epgButton.js")); + } } if (isAudio()) { $videos_id = getVideos_id(); @@ -331,7 +341,12 @@ class PlayerSkins extends PluginAbstract { } include $global['systemRootPath'] . 'plugin/PlayerSkins/mediaSession.php'; - PlayerSkins::addOnPlayerReady('if(typeof updateMediaSessionMetadata === "function"){updateMediaSessionMetadata();}'); + PlayerSkins::addOnPlayerReady('if(typeof updateMediaSessionMetadata === "function"){updateMediaSessionMetadata();}'); + + if (self::$hasMarks) { + $js .= ''; + $js .= ''; + } return $js; } @@ -678,6 +693,62 @@ class PlayerSkins extends PluginAbstract { } return array($tags); } + + /** + * + * @param type $markersList array(array('timeInSeconds'=>10,'name'=>'abc'),array('timeInSeconds'=>20,'name'=>'abc20'),array('timeInSeconds'=>25,'name'=>'abc25')....); + * @param type $width + * @param type $color + */ + public static function createMarker($markersList, $width = 10, $color = 'yellow') { + global $global; + + $bt = debug_backtrace(); + $file = str_replace($global['systemRootPath'], '', $bt[0]['file']); + + $onPlayerReady .= " /* {$file} */ + player.markers({markerStyle: { + 'width': '{$width}px', + 'background-color': '{$color}' + }, + markerTip: { + display: true, + text: function (marker) { + return marker.text; + } + }, + markers: "; + $markers = array(); + $addedSomething = false; + foreach ($markersList as $value) { + $obj = new stdClass(); + $obj->time = $value['timeInSeconds']; + $obj->text = $value['name']; + if (empty($obj->text)) { + continue; + } + $addedSomething = true; + $markers[] = $obj; + } + + $onPlayerReady .= json_encode($markers); + $onPlayerReady .= "});"; + if ($addedSomething) { + self::$hasMarks = true; + PlayerSkins::getStartPlayerJS($onPlayerReady); + } + } + + + public function getWatchActionButton($videos_id) { + global $global, $video; + include $global['systemRootPath'] . 'plugin/PlayerSkins/actionButton.php'; + } + + public function getGalleryActionButton($videos_id) { + global $global; + include $global['systemRootPath'] . 'plugin/PlayerSkins/actionButtonGallery.php'; + } } diff --git a/plugin/PlayerSkins/actionButton.php b/plugin/PlayerSkins/actionButton.php new file mode 100644 index 0000000000..9feae9bb86 --- /dev/null +++ b/plugin/PlayerSkins/actionButton.php @@ -0,0 +1,11 @@ + + + \ No newline at end of file diff --git a/plugin/PlayerSkins/actionButtonGallery.php b/plugin/PlayerSkins/actionButtonGallery.php new file mode 100644 index 0000000000..ad03e8ad78 --- /dev/null +++ b/plugin/PlayerSkins/actionButtonGallery.php @@ -0,0 +1,11 @@ + + + \ No newline at end of file diff --git a/plugin/PlayerSkins/epg.php b/plugin/PlayerSkins/epg.php new file mode 100644 index 0000000000..5ea167d07d --- /dev/null +++ b/plugin/PlayerSkins/epg.php @@ -0,0 +1,443 @@ +channels)) { + _error_log('EPG expired creating again'); + foreach ($epgs as $epg) { + $videos_id = $epg['id']; + $programCacheName = 'program_' . md5($epg['epg_link']); + $timeout = random_int(21600, 43200); //6 to 12 hours + $programData = ObjectYPT::getCache($programCacheName, $timeout); + if ($forceRecreate || empty($programData)) { + _error_log("EPG program expired creating again videos_id={$videos_id} " . $programCacheName); + //var_dump($epg['epg_link']);exit; + $Parser = new \buibr\xmlepg\EpgParser(); + $Parser->setURL($epg['epg_link']); + $Parser->temp_dir = getCacheDir(); + try { + $Parser->parseURL(); + $epgData = $Parser->getEpgdata(); + $channels = $Parser->getChannels(); + //var_dump($channels, $epgData); + //$Parser->setTargetTimeZone('Europe/Skopje'); + // $Parser->setChannelfilter('prosiebenmaxx.de'); //optional + // $Parser->setIgnoreDescr('Keine Details verfügbar.'); //optional + foreach ($channels as $key => $value) { + $channels[$key]['epgData'] = array(); + foreach ($epgData as $key2 => $program) { + if ($program['channel'] != $value['id']) { + continue; + } + $minutes = getDurationInMinutes(date('Y-m-d 00:00:00'), $program['stop']); + //var_dump(date('Y-m-d 00:00:00'), $program['stop'], $minutes); + if ($minutes > 0) { + $channels[$key]['epgData'][] = $program; + setMinDate($program['start']); + setMaxDate($program['stop']); + } + unset($epgData[$key2]); + } + //var_dump($channels[$key]); + if (!empty($channels[$key])) { + usort($channels[$key]['epgData'], "cmpPrograms"); + $channels[$key]['videos_id'] = $videos_id; + $channelsList[] = $channels[$key]; + //var_dump($channelsList[0]);exit; + } + } + $file = ObjectYPT::setCache($programCacheName, $channelsList); + _error_log("EPG program cache created videos_id={$videos_id} " . json_encode($file)); + } catch (Exception $e) { + throw new \RuntimeException($e); + } + } else { + $channelsList = object_to_array($programData); + } + } + usort($channelsList, "cmpChannels"); + + $epgData = new stdClass(); + $epgData->video = $epg; + $epgData->channels = $channelsList; + $epgData->channelsMinDate = $minDate; + $epgData->channelsMaxDate = $maxDate; + + //var_dump($epgData);exit; + $file = ObjectYPT::setCache($cacheName, $epgData); + _error_log('EPG cache created ' . json_encode($file)); +} else { + $channelsList = $epgData->channels; +} + +//var_dump($epgData);exit; +//var_dump($channelsList);exit; +function cmpPrograms($a, $b) { + $AStartTime = strtotime($a['start']); + $BStartTime = strtotime($b['start']); + if ($AStartTime == $BStartTime) { + return 0; + } + return ($AStartTime < $BStartTime) ? -1 : 1; +} + +function cmpChannels($a, $b) { + return strcasecmp($a['display-name'], $b['display-name']); +} + +function getDurationInMinutes($start, $stop) { + $timeStart = strtotime($start); + $timeStop = strtotime($stop); + //var_dump(date('Y-m-d H:i:s',$timeStart), date('Y-m-d H:i:s',$timeStop)); + $seconds = $timeStop - $timeStart; + + $minutes = intval($seconds / 60); + return $minutes; +} + +function setMaxDate($date) { + global $maxDate; + + if (empty($maxDate)) { + $maxDate = 0; + } + + $newDate = strtotime($date); + if ($newDate > $maxDate) { + $maxDate = $newDate; + } +} + +function setMinDate($date) { + global $minDate; + + if (empty($minDate)) { + $minDate = strtotime('+30 days'); + } + + $newDate = strtotime($date); + if ($newDate < $minDate) { + $minDate = $newDate; + } +} + +function createEPG($channel) { + global $minuteSize, $Date, $minimumWidth, $videos_id; + $channel = object_to_array($channel); + $displayname = $channel['display-name']; + $channelId = $channel['id']; + $this_videos_id = $channel['videos_id']; + $firstProgram = $channel['epgData'][0]; + + $class = ''; + if ($this_videos_id == $videos_id) { + $class = 'active'; + } + //var_dump($channel);exit; + ?> + +
+
+ +
+
+ $program) { + $minutesSinceZeroTime = getDurationInMinutes("{$Date} 00:00:00", $program['start']); + if ($minutesSinceZeroTime < 0) { + continue; + } + $minutes = getDurationInMinutes($program['start'], $program['stop']); + $left = ($minuteSize * $minutesSinceZeroTime) + $timeLineElementSize; + $width = ($minuteSize * $minutes); + $_stopTime = strtotime($program['stop']); + $class = ''; + if ($width <= $minimumWidth) { + $text = ""; + } else { + $startTime = date('m-d H:i', strtotime($program['start'])); + $stopTime = date('m-d H:i',$_stopTime); + $text = "{$program['title']}
{$minutes} Min
"; + } + if($_stopTime<$nowTime){ + $class = 'finished'; + } + echo "
" + . "{$text}" + . "
"; + } + ?> +
+
+
+ + + + EPG + + + + + +
+
+
+ channelsMaxDate; + //var_dump($lastStopDate);exit; + $maxDate = 0; + $count = 0; + $countElements = 0; + while ($lastStopDate > $maxDate && $count < 600) { + $tomorrowDate = date('Y-m-d', strtotime("+{$count} days")); + for ($i = 0; $i < 24; $i++) { + $hour = $i; + $amPm = 'AM'; + if ($i > 12) { + $hour = $i - 12; + $amPm = 'PM'; + } + $hour = sprintf("%02d", $hour); + + for ($j = 0; $j < 60; $j += $timeLineElementMinutes) { + $minutes = sprintf("%02d", $j); + if(empty($count)){ + $text = "
{$hour}:{$minutes} {$amPm}
"; + }else{ + $text = "{$tomorrowDate}
{$hour}:{$minutes} {$amPm}
"; + } + $left = ($countElements * $timeLineElementSize) + $timeLineElementSize; + echo "
{$text}
"; + + setMaxDate("$tomorrowDate $i:$minutes:00"); + $countElements++; + if ($lastStopDate < $maxDate) { + break; + } + } + if ($lastStopDate < $maxDate) { + break; + } + } + $count++; + } + ?> +
+
+
+ channels as $channel) { + createEPG($channel); + } + ?> +
+
+
+ + + + + \ No newline at end of file diff --git a/plugin/PlayerSkins/epgButton.css b/plugin/PlayerSkins/epgButton.css new file mode 100644 index 0000000000..c196055a9a --- /dev/null +++ b/plugin/PlayerSkins/epgButton.css @@ -0,0 +1,14 @@ +.EPG-button{ + outline: none; +} +.EPG-button:before { + display: inline-block; + font-style: normal; + font-variant: normal; + text-rendering: auto; + content: "\f022"; + font-size: 1.2em; + line-height: 1.0em; + font-family: "Font Awesome\ 5 Free"; + font-weight: 900; +} \ No newline at end of file diff --git a/plugin/PlayerSkins/epgButton.js b/plugin/PlayerSkins/epgButton.js new file mode 100644 index 0000000000..38362a9ca6 --- /dev/null +++ b/plugin/PlayerSkins/epgButton.js @@ -0,0 +1,20 @@ +var Button = videojs.getComponent('Button'); + +var EPGButton = videojs.extend(Button, { + //constructor: function(player, options) { + constructor: function () { + Button.apply(this, arguments); + this.addClass('EPG-button'); + this.controlText("EPG"); + setTimeout(function(){avideoTooltip(".EPG-button","EPG");},1000); + }, + handleClick: function () { + var url = webSiteRootURL+'plugin/PlayerSkins/epg.php'; + url = addQueryStringParameter(url, 'videos_id', mediaId); + console.log('epg clicked'); + avideoModalIframeFullTransparent(url); + } +}); + +videojs.registerComponent('EPGButton', EPGButton); +player.getChild('controlBar').addChild('EPGButton', {}, getPlayerButtonIndex('fullscreenToggle') - 1); \ No newline at end of file diff --git a/updatedb/updateDb.v12.1.sql b/updatedb/updateDb.v12.1.sql new file mode 100644 index 0000000000..dcdc87d3d2 --- /dev/null +++ b/updatedb/updateDb.v12.1.sql @@ -0,0 +1,13 @@ +SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; +SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; +SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES'; + +ALTER TABLE `videos` +ADD COLUMN `epg_link` VARCHAR(400) NULL DEFAULT NULL, +ADD INDEX `index_epg_link` (`epg_link` ASC); + +UPDATE configurations SET version = '12.1', modified = now() WHERE id = 1; + +SET SQL_MODE=@OLD_SQL_MODE; +SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; +SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS; diff --git a/view/css/main.css b/view/css/main.css index 68fb768edf..b3bff603c9 100644 --- a/view/css/main.css +++ b/view/css/main.css @@ -1048,7 +1048,8 @@ li.dropdown-submenu > ul > li > a{ .swal-modal.swal-modal-iframe-xsmall .swal-content, .swal-modal.swal-modal-iframe-small .swal-content, .swal-modal.swal-modal-iframe-large .swal-content, -.swal-modal.swal-modal-iframe-full .swal-content{ +.swal-modal.swal-modal-iframe-full .swal-content, +.swal-modal.swal-modal-iframe-full-transparent .swal-content{ width: 100%; height: 100%; } @@ -1056,7 +1057,8 @@ li.dropdown-submenu > ul > li > a{ .swal-modal.swal-modal-iframe-xsmall iframe, .swal-modal.swal-modal-iframe-small iframe, .swal-modal.swal-modal-iframe-large iframe, -.swal-modal.swal-modal-iframe-full iframe{ +.swal-modal.swal-modal-iframe-full iframe, +.swal-modal.swal-modal-iframe-full-transparent iframe{ width: 100%; height: calc(100% - 50px); } @@ -1086,7 +1088,8 @@ li.dropdown-submenu > ul > li > a{ max-width: 100%; max-height: 100%; } -.swal-modal-iframe-full { +.swal-modal-iframe-full, +.swal-modal-iframe-full-transparent { margin: 0; position: fixed; top: 0; @@ -1096,17 +1099,26 @@ li.dropdown-submenu > ul > li > a{ max-width: 100%; max-height: 100%; } -.swal-modal.swal-modal-iframe-full iframe{ +.swal-modal.swal-modal-iframe-full iframe, +.swal-modal.swal-modal-iframe-full-transparent iframe{ height: 100%; } -.swal-modal-iframe-full #avideoModalIframeDiv{ +.swal-modal-iframe-full-transparent iframe, +.swal-modal-iframe-full-transparent .swal-content, +.swal-modal-iframe-full-transparent{ + background-color: transparent; +} + +.swal-modal-iframe-full #avideoModalIframeDiv, +.swal-modal-iframe-full-transparent #avideoModalIframeDiv{ display: block; margin: 0; } .swal-modal.swal-modal-iframe-large .swal-content, -.swal-modal.swal-modal-iframe-full .swal-content{ +.swal-modal.swal-modal-iframe-full .swal-content, +.swal-modal-iframe-full-transparent .swal-content{ padding: 0; margin: 0; } diff --git a/view/js/script.js b/view/js/script.js index 9046764133..8a8f47295a 100644 --- a/view/js/script.js +++ b/view/js/script.js @@ -1421,6 +1421,10 @@ function avideoModalIframeFullScreen(url) { avideoModalIframeWithClassName(url, 'swal-modal-iframe-full', true); } +function avideoModalIframeFullTransparent(url) { + avideoModalIframeWithClassName(url, 'swal-modal-iframe-full-transparent', false); +} + function avideoModalIframeFullScreenClose() { if (typeof swal === 'function') { $('.swal-overlay iframe').attr('src', 'about:blank'); @@ -1566,7 +1570,7 @@ function avideoModalIframeWithClassName(url, className, updateURL) { clearTimeout(avideoModalIframeWithClassNameTimeout); avideoModalIframeWithClassNameTimeout = setTimeout(function () { if (!$('#avideoModalIframe').contents().find("body").length) { - //console.log('avideoModalIframeWithClassName content loaded 5'); + console.log('avideoModalIframeWithClassName content NOT loaded'); // is not loaded url = addGetParam(url, 'avideoIframe', 0); if (isSameDomain(url)) { @@ -1608,6 +1612,8 @@ function avideoModalIframeIsVisible() { modal = $('.swal-modal-iframe-large'); } else if ($('.swal-modal-iframe-full').length) { modal = $('.swal-modal-iframe-full'); + } else if ($('.swal-modal-iframe-full-transparent').length) { + modal = $('.swal-modal-iframe-full-transparent'); } else { modal = $('.swal-modal-iframe'); } diff --git a/view/managerVideos_body.php b/view/managerVideos_body.php index 88aa5c7121..fd09512917 100644 --- a/view/managerVideos_body.php +++ b/view/managerVideos_body.php @@ -737,6 +737,7 @@ if (empty($advancedCustomUser->userCanNotChangeUserGroup) || Permissions::canAdm isArticle = 0; if ((row.type === 'embed') || (row.type === 'linkVideo') || (row.type === 'linkAudio')) { $('#videoLink').val(row.videoLink); + $('#epg_link').val(row.epg_link); $('#videoLinkType').val(row.type); } else { $('#videoLinkContent').slideUp(); @@ -1003,6 +1004,7 @@ echo AVideoPlugin::getManagerVideosAddNew(); "trailer1": $('#inputTrailer').val(), "video_password": $('#inputVideoPassword').val(), "videoLink": $('#videoLink').val(), + "epg_link": $('#epg_link').val(), "videoLinkType": $('#videoLinkType').val(), "clean_title": $('#inputCleanTitle').val(), disableHTMLDescription)) { $('#videoIsAdControl, #videoExtraDetails, #videoLinkContent').slideUp(); $('#postersImage').slideDown(); $('#videoLink').val(''); + $('#epg_link').val(''); $('#videoStartSecond').val('00:00:00'); $('#videoLinkType').val("article"); disableHTMLDescription)) { $('#postersImage, #videoIsAdControl, .titles').slideUp(); $('#videoLinkContent').slideDown(); $('#videoLink').val(''); + $('#epg_link').val(''); $('#videoStartSecond').val('00:00:00'); $('#videoLinkType').val("linkVideo");
- - http://www.your-embed-link.com/video" required> +
+
+ + http://www.your-embed-link.com/video" required> +
+
+ + "> +
+
- F