SproutCMS

This is the code documentation for the SproutCMS project

source of /sprout/Helpers/EmbedVideo.php

  1. <?php
  2. /*
  3.  * Copyright (C) 2017 Karmabunny Pty Ltd.
  4.  *
  5.  * This file is a part of SproutCMS.
  6.  *
  7.  * SproutCMS is free software: you can redistribute it and/or modify it under the terms
  8.  * of the GNU General Public License as published by the Free Software Foundation, either
  9.  * version 2 of the License, or (at your option) any later version.
  10.  *
  11.  * For more information, visit <http://getsproutcms.com>.
  12.  */
  13.  
  14. namespace Sprout\Helpers;
  15.  
  16. use DOMDocument;
  17.  
  18.  
  19. /**
  20. * No description yet.
  21. **/
  22. class EmbedVideo
  23. {
  24.  
  25. const TYPE_YOUTUBE = 1;
  26. const TYPE_VIMEO = 2;
  27.  
  28.  
  29. /**
  30.   * Return HTML for embedding a video, based on the URL.
  31.   * Supports YouTube and Vimeo.
  32.   *
  33.   * Options include:
  34.   * bool autoplay Begin playing the video straight away
  35.   * string title Title attribute
  36.   *
  37.   * @param string $url
  38.   * @param int $width
  39.   * @param int $height
  40.   * @param array $options
  41.   **/
  42. public static function renderEmbed($url, $width = 400, $height = 300, array $options = array()) {
  43. $url = trim(Enc::cleanfunky($url));
  44. $width = (int) $width;
  45. $height = (int) $height;
  46.  
  47. $idtype = self::getVideoIdType($url);
  48. if ($idtype == null) return null;
  49.  
  50. // Determine URL for player
  51. list($type, $video_id) = $idtype;
  52. switch ($type) {
  53. case self::TYPE_YOUTUBE:
  54. $embed_url = '//www.youtube.com/embed/' . $video_id . '?rel=0&wmode=transparent';
  55. break;
  56.  
  57. case self::TYPE_VIMEO:
  58. $embed_url = '//player.vimeo.com/video/' . $video_id . '?title=0&byline=0&portrait=0&color=00ADEF&fullscreen=0';
  59. break;
  60. }
  61.  
  62. // Both players use the same GET param name for this flag
  63. if (isset($options['autoplay']) and $options['autoplay'] == true) {
  64. $embed_url .= '&autoplay=1';
  65. }
  66.  
  67. // Ensure there is a title tag for WCAG compliance
  68. if (empty($options['title'])) {
  69. $options['title'] = 'Embedded video';
  70. }
  71.  
  72. return '<iframe '
  73. . 'width="' . $width . '" height="' . $height. '" '
  74. . 'src="' . Enc::html($embed_url) . '" '
  75. . 'title="' . Enc::html($options['title']) . '" '
  76. . 'frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen>'
  77. . '<a href="' . Enc::html($url) . '">Watch video</a>'
  78. . '</iframe>';
  79. }
  80.  
  81.  
  82. /**
  83.   * Get a thumbnail as a full absolute URL)
  84.   *
  85.   * @param $quality Quality. Higher is better
  86.   **/
  87. public static function getThumbFilename($url, $quality = 1)
  88. {
  89. $url = trim($url);
  90.  
  91. $idtype = self::getVideoIdType($url);
  92. if ($idtype == null) return null;
  93.  
  94. list($type, $video_id) = $idtype;
  95. switch ($type) {
  96. case self::TYPE_YOUTUBE:
  97. if ($quality == 2) {
  98. return "//i1.ytimg.com/vi/{$video_id}/maxresdefault.jpg";
  99. } else {
  100. return "//i1.ytimg.com/vi/{$video_id}/hqdefault.jpg";
  101. }
  102. break;
  103.  
  104. case self::TYPE_VIMEO:
  105. $dom = new DOMDocument();
  106. $vimeo_html = @file_get_contents("http://vimeo.com/{$video_id}");
  107. @$dom->loadHTML($vimeo_html);
  108.  
  109. $metas = $dom->getElementsByTagName('meta');
  110. foreach ($metas as $m) {
  111. if ($m->getAttribute('property') == 'og:image') {
  112. return trim($m->getAttribute('content'));
  113. }
  114. }
  115. break;
  116. }
  117.  
  118. return null;
  119. }
  120.  
  121.  
  122. /**
  123.   * Return the URL for our dynamic thumbnail resizer for a given video url
  124.   *
  125.   * Arguments are the same as `File::resizeUrl`
  126.   * Size spec only supports crop at this time (e.g. c200x150)
  127.   **/
  128. public static function resizedThumb($url, $sizespec)
  129. {
  130. $url = trim($url);
  131.  
  132. $idtype = self::getVideoIdType($url);
  133. if ($idtype == null) return null;
  134.  
  135. list($type, $video_id) = $idtype;
  136.  
  137. return 'embed_video/thumb/' . $sizespec . '/' . $type. '/' . $video_id;
  138. }
  139.  
  140.  
  141. /**
  142.   * Parse the URL into a video-id and type
  143.   **/
  144. public static function getVideoIdType($url)
  145. {
  146. $url = Enc::cleanfunky($url);
  147. if (! preg_match('!^https?://!', $url)) return null;
  148.  
  149. // Get the host of the URL
  150. $urlparts = parse_url($url);
  151. if (! $urlparts['host']) return null;
  152.  
  153. if (strpos($urlparts['host'], 'youtube.com') !== false) {
  154. // YouTube
  155. if (strpos($urlparts['path'], '/v/') === 0) {
  156. return array(self::TYPE_YOUTUBE, substr($urlparts['path'], 3));
  157.  
  158. } else {
  159. $query_parts = explode('&', @$urlparts['query']);
  160. foreach ($query_parts as $part) {
  161. @list($key, $value) = explode('=', $part, 2);
  162. if ($key == 'v') {
  163. return array(self::TYPE_YOUTUBE, $value);
  164. }
  165. }
  166. }
  167.  
  168. } else if (strpos($urlparts['host'], 'youtu.be') !== false) {
  169. // YouTube
  170. $path = parse_url ($url, PHP_URL_PATH);
  171. return array(self::TYPE_YOUTUBE, trim($path, '/'));
  172.  
  173.  
  174. } else if (strpos($urlparts['host'], 'vimeo.com') !== false) {
  175. // Vimeo
  176. $path = preg_replace('/[^0-9]/', '', $urlparts['path']);
  177. $path = (int) $path;
  178.  
  179. if ($path != 0) {
  180. return array(self::TYPE_VIMEO, $path);
  181. }
  182.  
  183. }
  184.  
  185. }
  186.  
  187.  
  188. }
  189.