From 787856a609e73933d86be1bfd65c106b93d01805 Mon Sep 17 00:00:00 2001 From: Vincent Vanwaelscappel Date: Wed, 24 Aug 2022 10:49:41 +0200 Subject: [PATCH] wip #5399 @0.5 --- composer.json | 4 +- src/Html.php | 31 +++- src/WebVideo.php | 370 +++++++++++++++++++++++++++++++---------------- 3 files changed, 273 insertions(+), 132 deletions(-) diff --git a/composer.json b/composer.json index b8cebe0..93901ef 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ "ext-iconv": "*", "laravel/framework": "~5.8|^6.0|^7.0|^8.0", "cubist/net": "dev-master", - "ext-sodium": "*" + "ext-sodium": "*", + "dpb587/microdata-dom": "dev-master" } } - diff --git a/src/Html.php b/src/Html.php index 06e9ec8..c7bc67c 100644 --- a/src/Html.php +++ b/src/Html.php @@ -1,15 +1,32 @@ loadHTML(file_get_contents($url)); + libxml_clear_errors(); + libxml_use_internal_errors(false); + + return $dom; + } } diff --git a/src/WebVideo.php b/src/WebVideo.php index 850086d..28a668a 100644 --- a/src/WebVideo.php +++ b/src/WebVideo.php @@ -1,127 +1,251 @@ filter($url); - list($service, $videoId) = explode(':', $urlf); - if ($service == 'http' || $service == 'https') { - $service = 'generic'; - $videoId = $urlf; - } - $finalUrl = self::getIframeUrl($service, $videoId); - if (!$finalUrl) { - return false; - } - return true; - } - - public static function getIframeUrl($service, $id = null, $options = array()) { - if (null === $id || stristr($service, ':')) { - $filter = new CubeIT_Filter_WebVideo(); - $urlf = $filter->filter($service); - list($service, $id) = explode(':', $urlf); - } - - $s = Text::ucfirst($service, true); - $f = '_get' . $s . 'Url'; - $refl = new \ReflectionClass(get_class()); - if (!$refl->hasMethod($f)) { - return false; - } - return self::$f($id, $options); - } - - protected static function _getGenericUrl($url) { - $meta = Html::getMicrodata($url); - - $res = ''; - foreach ($meta->getElementsByTagName('*') as $m) { - /** @var $m MicrodataDOM\DOMElement */ - if (strcasecmp($m->getAttribute('itemtype'), 'http://schema.org/VideoObject') === 0) { - foreach ($m->getElementsByTagName('*') as $e) { - if (strcasecmp($e->getAttribute('itemprop'), 'embedUrl') === 0) { - /** @var $e MicrodataDOM\DOMElement */ - $res = $e->getAttribute('content'); - } - } - } - } - - if (!$res) { - return false; - } - - if (stristr($url, 'bfmtv')) { - $res = str_replace('idVideo', 'videoId', $res); - } - - return $res; - } - - protected static function _getYoutubeUrl($id, $options = array()) { - $url = 'https://www.youtube.com/embed/' . $id; - return self::_getUrl($url, $options); - } - - protected static function _getCnbcUrl($id, $options = array()) { - $url = 'http://player.cnbc.com/p/gZWlPC/cnbc_global?playertype=synd&byGuid=' . $id; - return self::_getUrl($url, $options); - } - - protected static function _getKalturaUrl($id, $options = array()) { - $confid = $options['playerId']; - $options['playerId'] = 'p_' . rand(1, 100000); - $options['wid'] = $options['widgetId'] = '_' . $options['partnerId']; - - $url = 'http://cdnapi.kaltura.com/html5/html5lib/v1.6.12.40/mwEmbedFrame.php/p/' . $options['partnerId'] - . '/uiconf_id/' . $confid . '/entry_id/' . $id; - - return self::_getUrl($url, $options); - } - - protected static function _getDantubeUrl($id, $options = array()) { - $options['playerId'] = '10247951'; - $options['partnerId'] = '1073192'; - $options['widgetId'] = '1_d89zinhy'; - return self::_getKalturaUrl($id, $options); - } - - protected static function _getDailymotionUrl($id, $options = array()) { - $url = 'https://www.dailymotion.com/embed/video/' . $id; - return self::_getUrl($url, $options); - } - - protected static function _getVimeoUrl($id, $options = array()) { - $url = 'https://player.vimeo.com/video/' . $id; - return self::_getUrl($url, $options); - } - - protected static function _getCubetubeUrl($id, $options = array()) { - $url = 'https://extranet.cubedesigners.com/tools/tube'; - return self::_getUrl($url, $options); - } - - protected static function _getFacebookUrl($id, $options) { - $url = 'https://www.facebook.com/video/embed'; - $options['video_id'] = $id; - return self::_getUrl($url, $options); - } - - protected static function _getUrl($url, $options) { - $res = $url; - $o = array(); - foreach ($options as $k => $v) { - $o[] = $k . '=' . rawurldecode($v); - } - if (count($o)) { - $res .= '?' . implode('&', $o); - } - return $res; - } + +use MicrodataDOM\DOMElement; + +class WebVideo +{ + + public static $_dummyComponents = array('video', 'embed', 'media'); + + /** + * @param $url + * @param $asArray bool + * @return mixed|string + */ + public static function parse($url, bool $asArray = false) + { + if (self::_isParsed($url)) { + list($service, $videoId) = explode(':', $url); + $res = $url; + } else { + $service = self::_findService($url); + if ($service) { + $videoId = self::_findVideoId($url, $service); + if ($videoId) { + $res = $service . ':' . $videoId; + } else { + $videoId = $res = $url; + } + } else { + $service = 'generic'; + $videoId = $res = $url; + } + } + + if ($asArray) { + return ['service' => $service, 'id' => $videoId, 'url' => $res]; + } + return $res; + + } + + public static function isWebVideo($url) + { + if (!$url) { + return false; + } + $video = self::parse($url, true); + + $finalUrl = self::getIframeUrl($video['service'], $video['id']); + if (!$finalUrl) { + return false; + } + return true; + } + + public static function getIframeUrl($service, $id = null, $options = array()) + { + if (null === $id) { + $video = self::parse($service, true); + $service = $video['service']; + $id = $video['id']; + } + + $s = Text::ucfirst($service, true); + $f = '_get' . $s . 'Url'; + if (!is_callable([self::class, $f])) { + return false; + } + return self::$f($id, $options); + } + + public static function _getGenericUrl($url) + { + $meta = Html::getMicrodata($url); + + $res = ''; + foreach ($meta->getElementsByTagName('*') as $m) { + /** @var $m DOMElement */ + if (strcasecmp($m->getAttribute('itemtype'), 'http://schema.org/VideoObject') === 0) { + foreach ($m->getElementsByTagName('*') as $e) { + if (strcasecmp($e->getAttribute('itemprop'), 'embedUrl') === 0) { + /** @var $e DOMElement */ + $res = $e->getAttribute('content'); + } + } + } + } + + if (!$res) { + return false; + } + + if (stristr($url, 'bfmtv')) { + $res = str_replace('idVideo', 'videoId', $res); + } + + return $res; + } + + public static function _getYoutubeUrl($id, $options = array()) + { + $url = 'https://www.youtube.com/embed/' . $id; + return self::_getUrl($url, $options); + } + + public static function _getCnbcUrl($id, $options = array()) + { + $url = 'http://player.cnbc.com/p/gZWlPC/cnbc_global?playertype=synd&byGuid=' . $id; + return self::_getUrl($url, $options); + } + + public static function _getKalturaUrl($id, $options = array()) + { + $confid = $options['playerId']; + $options['playerId'] = 'p_' . rand(1, 100000); + $options['wid'] = $options['widgetId'] = '_' . $options['partnerId']; + + $url = 'http://cdnapi.kaltura.com/html5/html5lib/v1.6.12.40/mwEmbedFrame.php/p/' . $options['partnerId'] + . '/uiconf_id/' . $confid . '/entry_id/' . $id; + + return self::_getUrl($url, $options); + } + + public static function _getDantubeUrl($id, $options = array()) + { + $options['playerId'] = '10247951'; + $options['partnerId'] = '1073192'; + $options['widgetId'] = '1_d89zinhy'; + return self::_getKalturaUrl($id, $options); + } + + public static function _getDailymotionUrl($id, $options = array()) + { + $url = 'https://www.dailymotion.com/embed/video/' . $id; + return self::_getUrl($url, $options); + } + + public static function _getVimeoUrl($id, $options = array()) + { + $url = 'https://player.vimeo.com/video/' . $id; + return self::_getUrl($url, $options); + } + + public static function _getCubetubeUrl($id, $options = array()) + { + $url = 'https://extranet.cubedesigners.com/tools/tube'; + return self::_getUrl($url, $options); + } + + public static function _getFacebookUrl($id, $options) + { + $url = 'https://www.facebook.com/video/embed'; + $options['video_id'] = $id; + return self::_getUrl($url, $options); + } + + public static function _getUrl($url, $options) + { + $res = $url; + $o = array(); + foreach ($options as $k => $v) { + $o[] = $k . '=' . rawurldecode($v); + } + if (count($o)) { + $res .= '?' . implode('&', $o); + } + return $res; + } + + /** + * + * @param string $url + * @return string|boolean + */ + public static function _findService($url) + { + foreach (self::_getServices() as $search => $service) { + if (stripos($url, $search) !== false) { + return $service; + } + } + return false; + } + + public static function _findVideoId($url, $service) + { + $r = Text::parseUrl($url); + if ($service == 'youtube') { + if (isset($r['query_params']['v'])) { + return $r['query_params']['v']; + } + } + if (isset($r['query_params']['video'])) { + return $r['query_params']['video']; + } + + if (isset($r['path_components'])) { + $keeped = array(); + + foreach ($r['path_components'] as $c) { + if (in_array($c, self::$_dummyComponents)) { + continue; + } + $keeped[] = $c; + } + + if (count($keeped) >= 1) { + $k = array_pop($keeped); + if (!self::_videoIdHasUnderscore($service)) { + $e = explode('_', $k); + return $e[0]; + } else { + return $k; + } + } + } + + return false; + } + + public static function _videoIdHasUnderscore($service) + { + if ($service == 'youtube') { + return true; + } + return false; + } + + + public static function _getServices() + { + return array('youtube' => 'youtube', 'youtu.be' => 'youtube', 'dailymotion.com' => 'dailymotion', 'dai.ly' => 'dailymotion', 'vimeo.com' => 'vimeo', 'facebook.com' => 'facebook', 'cnbc.com' => 'cnbc'); + } + + public static function _isParsed($url) + { + $e = explode(':', $url); + if (count($e) != 2) { + return false; + } + $services = array_unique(self::_getServices()); + if (!in_array($e[0], $services)) { + return false; + } + return true; + } + } -- 2.39.5