├── CHANGELOG.md ├── phpstan.neon ├── ecs.php ├── src ├── config.php ├── templates │ ├── embeds │ │ ├── youtube-live-stream.twig │ │ ├── youtube-live-chat.twig │ │ ├── youtube-live-chat-amp.twig │ │ └── youtube-live-stream-amp.twig │ └── settings.twig ├── translations │ └── en │ │ └── youtubeliveembed.php ├── controllers │ └── InfoController.php ├── models │ └── Settings.php ├── services │ ├── ServicesTrait.php │ └── Embed.php ├── icon.svg ├── variables │ └── YoutubeLiveEmbedVariable.php ├── YoutubeLiveEmbed.php └── helpers │ └── PluginTemplate.php ├── Makefile ├── LICENSE.md ├── composer.json └── README.md /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # YouTube Live Embed Changelog 2 | 3 | ## 5.0.0 - 2025.01.04 4 | ### Added 5 | * Initial Craft CMS 5 release 6 | -------------------------------------------------------------------------------- /phpstan.neon: -------------------------------------------------------------------------------- 1 | includes: 2 | - %currentWorkingDirectory%/vendor/craftcms/phpstan/phpstan.neon 3 | 4 | parameters: 5 | level: 5 6 | paths: 7 | - src 8 | -------------------------------------------------------------------------------- /ecs.php: -------------------------------------------------------------------------------- 1 | paths([ 8 | __DIR__ . '/src', 9 | __FILE__, 10 | ]); 11 | $ecsConfig->parallel(); 12 | $ecsConfig->sets([SetList::CRAFT_CMS_4]); 13 | }; 14 | -------------------------------------------------------------------------------- /src/config.php: -------------------------------------------------------------------------------- 1 | '', 28 | "isLive" => false, 29 | ]; 30 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | MAJOR_VERSION?=5 2 | PLUGINDEV_PROJECT_DIR?=/Users/andrew/webdev/sites/plugindev/cms_v${MAJOR_VERSION}/ 3 | VENDOR?=nystudio107 4 | PROJECT_PATH?=${VENDOR}/$(shell basename $(CURDIR)) 5 | 6 | .PHONY: dev docs release 7 | 8 | # Start up the buildchain dev server 9 | dev: 10 | # Start up the docs dev server 11 | docs: 12 | ${MAKE} -C docs/ dev 13 | # Run code quality tools, tests, and build the buildchain & docs in preparation for a release 14 | release: --code-quality --code-tests --buildchain-clean-build --docs-clean-build 15 | # The internal targets used by the dev & release targets 16 | --buildchain-clean-build: 17 | --code-quality: 18 | ${MAKE} -C ${PLUGINDEV_PROJECT_DIR} -- ecs check vendor/${PROJECT_PATH}/src --fix 19 | ${MAKE} -C ${PLUGINDEV_PROJECT_DIR} -- phpstan analyze -c vendor/${PROJECT_PATH}/phpstan.neon 20 | --code-tests: 21 | --docs-clean-build: 22 | ${MAKE} -C docs/ clean 23 | ${MAKE} -C docs/ image-build 24 | ${MAKE} -C docs/ fix 25 | -------------------------------------------------------------------------------- /src/templates/embeds/youtube-live-stream.twig: -------------------------------------------------------------------------------- 1 | {# @var craft \craft\web\twig\variables\CraftVariable #} 2 | {# 3 | /** 4 | * YouTube Live Embed plugin for Craft CMS 5 | * 6 | * YouTube Live Embed Settings.twig 7 | * 8 | * @author nystudio107 9 | * @copyright Copyright (c) 2019 nystudio107 10 | * @link https://nystudio107.com 11 | * @package YoutubeLiveEmbed 12 | * @since 1.0.0 13 | */ 14 | #} 15 | 16 | 32 |
33 | 35 |
36 | -------------------------------------------------------------------------------- /src/templates/embeds/youtube-live-chat.twig: -------------------------------------------------------------------------------- 1 | {# @var craft \craft\web\twig\variables\CraftVariable #} 2 | {# 3 | /** 4 | * YouTube Live Embed plugin for Craft CMS 5 | * 6 | * YouTube Live Embed Settings.twig 7 | * 8 | * @author nystudio107 9 | * @copyright Copyright (c) 2019 nystudio107 10 | * @link https://nystudio107.com 11 | * @package YoutubeLiveEmbed 12 | * @since 1.0.0 13 | */ 14 | #} 15 | 31 |
32 | 34 |
35 | -------------------------------------------------------------------------------- /src/translations/en/youtubeliveembed.php: -------------------------------------------------------------------------------- 1 | '{name} plugin loaded', 18 | 'YouTube Channel ID' => 'YouTube Channel ID', 19 | 'Error rendering template string -> {error}' => 'Error rendering template string -> {error}', 20 | 'Error rendering `{template}` -> {error}' => 'Error rendering `{template}` -> {error}', 21 | 'Enter your YouTube channel ID here. If you do not know it, [here is how to find it](https://support.google.com/youtube/answer/3250431?hl=en).' => 'Enter your YouTube channel ID here. If you do not know it, [here is how to find it](https://support.google.com/youtube/answer/3250431?hl=en).', 22 | ]; 23 | -------------------------------------------------------------------------------- /src/templates/settings.twig: -------------------------------------------------------------------------------- 1 | {# @var craft \craft\web\twig\variables\CraftVariable #} 2 | {# 3 | /** 4 | * YouTube Live Embed plugin for Craft CMS 5 | * 6 | * YouTube Live Embed Settings.twig 7 | * 8 | * @author nystudio107 9 | * @copyright Copyright (c) 2019 nystudio107 10 | * @link https://nystudio107.com 11 | * @package YoutubeLiveEmbed 12 | * @since 1.0.0 13 | */ 14 | #} 15 | 16 | {% import "_includes/forms" as forms %} 17 | 18 | {{ forms.textField({ 19 | label: 'YouTube Channel ID'|t('youtubeliveembed'), 20 | instructions: 'Enter your YouTube channel ID here. If you do not know it, [here is how to find it](https://support.google.com/youtube/answer/3250431?hl=en).'|t('youtubeliveembed'), 21 | id: 'youtubeChannelId', 22 | name: 'youtubeChannelId', 23 | value: settings['youtubeChannelId'] 24 | }) }} 25 | {{ forms.lightswitchField({ 26 | label: 'Is the stream live?', 27 | instructions: 'Manually choose whether the stream is live or not', 28 | id: 'isLive', 29 | name: 'isLive', 30 | on: settings['isLive'] 31 | }) }} 32 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2022 nystudio107 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /src/templates/embeds/youtube-live-chat-amp.twig: -------------------------------------------------------------------------------- 1 | {# @var craft \craft\web\twig\variables\CraftVariable #} 2 | {# 3 | /** 4 | * YouTube Live Embed plugin for Craft CMS 5 | * 6 | * YouTube Live Embed Settings.twig 7 | * 8 | * @author nystudio107 9 | * @copyright Copyright (c) 2019 nystudio107 10 | * @link https://nystudio107.com 11 | * @package YoutubeLiveEmbed 12 | * @since 1.0.0 13 | */ 14 | #} 15 | 31 |
32 | 38 | 39 |
40 | -------------------------------------------------------------------------------- /src/templates/embeds/youtube-live-stream-amp.twig: -------------------------------------------------------------------------------- 1 | {# @var craft \craft\web\twig\variables\CraftVariable #} 2 | {# 3 | /** 4 | * YouTube Live Embed plugin for Craft CMS 5 | * 6 | * YouTube Live Embed Settings.twig 7 | * 8 | * @author nystudio107 9 | * @copyright Copyright (c) 2019 nystudio107 10 | * @link https://nystudio107.com 11 | * @package YoutubeLiveEmbed 12 | * @since 1.0.0 13 | */ 14 | #} 15 | 16 | 32 |
33 | 39 | 40 |
41 | -------------------------------------------------------------------------------- /src/controllers/InfoController.php: -------------------------------------------------------------------------------- 1 | embed->isLive(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/models/Settings.php: -------------------------------------------------------------------------------- 1 | ''], 46 | ['isLive', 'boolean'], 47 | ]; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/services/ServicesTrait.php: -------------------------------------------------------------------------------- 1 | [ 35 | 'embed' => EmbedService::class, 36 | ], 37 | ]; 38 | } 39 | 40 | /** 41 | * Returns the embed service 42 | * 43 | * @return EmbedService The embed service 44 | * @throws InvalidConfigException 45 | */ 46 | public function getEmbed(): EmbedService 47 | { 48 | return $this->get('embed'); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nystudio107/craft-youtubeliveembed", 3 | "description": "This plugin allows you to embed a YouTube live stream and/or live chat on your webpage", 4 | "type": "craft-plugin", 5 | "version": "5.0.0", 6 | "keywords": [ 7 | "craft", 8 | "cms", 9 | "craftcms", 10 | "craft-plugin", 11 | "youtube", 12 | "live", 13 | "stream", 14 | "chat", 15 | "embed" 16 | ], 17 | "support": { 18 | "docs": "https://nystudio107.com/docs/youtubeliveembed/", 19 | "issues": "https://nystudio107.com/plugins/youtube-live-embed/support", 20 | "source": "https://github.com/nystudio107/craft-youtubeliveembed" 21 | }, 22 | "license": "MIT", 23 | "authors": [ 24 | { 25 | "name": "nystudio107", 26 | "homepage": "https://nystudio107.com" 27 | } 28 | ], 29 | "require": { 30 | "craftcms/cms": "^5.0.0" 31 | }, 32 | "require-dev": { 33 | "craftcms/ecs": "dev-main", 34 | "craftcms/phpstan": "dev-main", 35 | "craftcms/rector": "dev-main" 36 | }, 37 | "scripts": { 38 | "phpstan": "phpstan --ansi --memory-limit=1G", 39 | "check-cs": "ecs check --ansi", 40 | "fix-cs": "ecs check --fix --ansi" 41 | }, 42 | "config": { 43 | "allow-plugins": { 44 | "craftcms/plugin-installer": true, 45 | "yiisoft/yii2-composer": true 46 | } 47 | }, 48 | "autoload": { 49 | "psr-4": { 50 | "nystudio107\\youtubeliveembed\\": "src/" 51 | } 52 | }, 53 | "extra": { 54 | "class": "nystudio107\\youtubeliveembed\\YoutubeLiveEmbed", 55 | "handle": "youtubeliveembed", 56 | "name": "YouTube Live Embed" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 12 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/nystudio107/craft-youtubeliveembed/badges/quality-score.png?b=v5)](https://scrutinizer-ci.com/g/nystudio107/craft-youtubeliveembed/?branch=v5) [![Code Coverage](https://scrutinizer-ci.com/g/nystudio107/craft-youtubeliveembed/badges/coverage.png?b=v5)](https://scrutinizer-ci.com/g/nystudio107/craft-youtubeliveembed/?branch=v5) [![Build Status](https://scrutinizer-ci.com/g/nystudio107/craft-youtubeliveembed/badges/build.png?b=v5)](https://scrutinizer-ci.com/g/nystudio107/craft-youtubeliveembed/build-status/v5) [![Code Intelligence Status](https://scrutinizer-ci.com/g/nystudio107/craft-youtubeliveembed/badges/code-intelligence.svg?b=v5)](https://scrutinizer-ci.com/code-intelligence) 2 | 3 | # YouTube Live Embed plugin for Craft CMS 4 | 5 | This plugin allows you to embed a YouTube live stream and/or live chat on your webpage 6 | 7 | ![Screenshot](./docs/docs/resources/img/plugin-logo.png) 8 | 9 | ## Requirements 10 | 11 | This plugin requires Craft CMS 5.0.0 or later 12 | 13 | ## Installation 14 | 15 | To install the plugin, follow these instructions. 16 | 17 | 1. Open your terminal and go to your Craft project: 18 | 19 | cd /path/to/project 20 | 21 | 2. Then tell Composer to load the plugin: 22 | 23 | composer require nystudio107/craft-youtubeliveembed 24 | 25 | 3. Install the plugin via `./craft install/plugin youtubeliveembed` via the CLI, or in the Control Panel, go to Settings → Plugins and click the “Install” button for YouTube Live Embed. 26 | 27 | You can also install YouTube Live Embed via the **Plugin Store** in the Craft Control Panel. 28 | 29 | ## Documentation 30 | 31 | Click here -> [YouTube Live Embed Documentation](https://nystudio107.com/plugins/youtube-live-embed/documentation) 32 | 33 | ## YouTube Live Embed Roadmap 34 | 35 | Some things to do, and ideas for potential features: 36 | 37 | * Release it 38 | 39 | Brought to you by [nystudio107](https://nystudio107.com) 40 | -------------------------------------------------------------------------------- /src/variables/YoutubeLiveEmbedVariable.php: -------------------------------------------------------------------------------- 1 | embed->embedStream($aspectRatioX, $aspectRatioY); 36 | } 37 | 38 | /** 39 | * Renders the responsive Google AMP iframe for the live stream video 40 | * 41 | * @param int $aspectRatioX 42 | * @param int $aspectRatioY 43 | * 44 | * @return Markup 45 | */ 46 | public function embedStreamAmp(int $aspectRatioX = 16, int $aspectRatioY = 9): Markup 47 | { 48 | return YoutubeLiveEmbed::$plugin->embed->embedStreamAmp($aspectRatioX, $aspectRatioY); 49 | } 50 | 51 | /** 52 | * Renders the responsive iframe HTML for the live stream chat 53 | * 54 | * @param int $aspectRatioX 55 | * @param int $aspectRatioY 56 | * 57 | * @return Markup 58 | */ 59 | public function embedChat(int $aspectRatioX = 16, int $aspectRatioY = 9): Markup 60 | { 61 | return YoutubeLiveEmbed::$plugin->embed->embedChat($aspectRatioX, $aspectRatioY); 62 | } 63 | 64 | /** 65 | * Renders the responsive Google AMP iframe HTML for the live stream chat 66 | * 67 | * @param int $aspectRatioX 68 | * @param int $aspectRatioY 69 | * 70 | * @return Markup 71 | */ 72 | public function embedChatAmp(int $aspectRatioX = 16, int $aspectRatioY = 9): Markup 73 | { 74 | return YoutubeLiveEmbed::$plugin->embed->embedChatAmp($aspectRatioX, $aspectRatioY); 75 | } 76 | 77 | /** 78 | * Sets the YouTube Channel ID to $channelId 79 | * 80 | * @param string $channelId 81 | * 82 | * @return string 83 | */ 84 | public function setChannelId(string $channelId): string 85 | { 86 | YoutubeLiveEmbed::$plugin->embed->setChannelId($channelId); 87 | 88 | return ''; 89 | } 90 | 91 | /** 92 | * Returns whether the stream is currently live 93 | * 94 | * @return bool 95 | */ 96 | public function isLive(): bool 97 | { 98 | return YoutubeLiveEmbed::$plugin->embed->isLive(); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/YoutubeLiveEmbed.php: -------------------------------------------------------------------------------- 1 | getSettings(); 78 | self::$youtubeChannelId = $settings->youtubeChannelId; 79 | 80 | Event::on( 81 | CraftVariable::class, 82 | CraftVariable::EVENT_INIT, 83 | static function(Event $event) { 84 | /** @var CraftVariable $variable */ 85 | $variable = $event->sender; 86 | $variable->set('youtubelive', YoutubeLiveEmbedVariable::class); 87 | } 88 | ); 89 | 90 | Craft::info( 91 | Craft::t( 92 | 'youtubeliveembed', 93 | '{name} plugin loaded', 94 | ['name' => $this->name] 95 | ), 96 | __METHOD__ 97 | ); 98 | } 99 | 100 | // Protected Methods 101 | // ========================================================================= 102 | 103 | /** 104 | * @inheritdoc 105 | */ 106 | protected function createSettingsModel(): Settings 107 | { 108 | return new Settings(); 109 | } 110 | 111 | /** 112 | * @inheritdoc 113 | */ 114 | protected function settingsHtml(): ?string 115 | { 116 | return Craft::$app->view->renderTemplate( 117 | 'youtubeliveembed/settings', 118 | [ 119 | 'settings' => $this->getSettings(), 120 | ] 121 | ); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/helpers/PluginTemplate.php: -------------------------------------------------------------------------------- 1 | getView()->renderString($templateString, $params); 33 | } catch (\Exception $e) { 34 | $html = Craft::t( 35 | 'youtubeliveembed', 36 | 'Error rendering template string -> {error}', 37 | ['error' => $e->getMessage()] 38 | ); 39 | Craft::error($html, __METHOD__); 40 | } 41 | 42 | return $html; 43 | } 44 | 45 | /** 46 | * Render a plugin template 47 | * 48 | * @param string $templatePath 49 | * @param array $params 50 | * 51 | * @return Markup 52 | */ 53 | public static function renderPluginTemplate(string $templatePath, array $params = []): Markup 54 | { 55 | // Stash the old template mode, and set it Control Panel template mode 56 | $oldMode = Craft::$app->view->getTemplateMode(); 57 | try { 58 | Craft::$app->view->setTemplateMode(View::TEMPLATE_MODE_CP); 59 | } catch (Exception $e) { 60 | Craft::error($e->getMessage(), __METHOD__); 61 | } 62 | 63 | // Render the template with our vars passed in 64 | try { 65 | $htmlText = Craft::$app->view->renderTemplate('youtubeliveembed/' . $templatePath, $params); 66 | $templateRendered = true; 67 | } catch (\Exception $e) { 68 | $htmlText = Craft::t( 69 | 'youtubeliveembed', 70 | 'Error rendering `{template}` -> {error}', 71 | ['template' => $templatePath, 'error' => $e->getMessage()] 72 | ); 73 | Craft::error($htmlText, __METHOD__); 74 | $templateRendered = false; 75 | } 76 | 77 | // If we couldn't find a plugin template, look for a frontend template 78 | if (!$templateRendered) { 79 | try { 80 | Craft::$app->view->setTemplateMode(View::TEMPLATE_MODE_SITE); 81 | } catch (Exception $e) { 82 | Craft::error($e->getMessage(), __METHOD__); 83 | } 84 | // Render the template with our vars passed in 85 | try { 86 | $htmlText = Craft::$app->view->renderTemplate($templatePath, $params); 87 | $templateRendered = true; 88 | } catch (\Exception $e) { 89 | $htmlText = Craft::t( 90 | 'youtubeliveembed', 91 | 'Error rendering `{template}` -> {error}', 92 | ['template' => $templatePath, 'error' => $e->getMessage()] 93 | ); 94 | Craft::error($htmlText, __METHOD__); 95 | $templateRendered = false; 96 | } 97 | } 98 | 99 | // Restore the old template mode 100 | try { 101 | Craft::$app->view->setTemplateMode($oldMode); 102 | } catch (Exception $e) { 103 | Craft::error($e->getMessage(), __METHOD__); 104 | } 105 | 106 | return Template::raw($htmlText); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/services/Embed.php: -------------------------------------------------------------------------------- 1 | ($aspectRatioY / $aspectRatioX) * 100, 52 | 'iframeUrl' => $this->getYoutubeStreamUrl(), 53 | ] 54 | ); 55 | } 56 | 57 | /** 58 | * Renders the responsive Google AMP iframe for the live stream video 59 | * 60 | * @param int $aspectRatioX 61 | * @param int $aspectRatioY 62 | * 63 | * @return Markup 64 | */ 65 | public function embedStreamAmp(int $aspectRatioX = 16, int $aspectRatioY = 9): Markup 66 | { 67 | return PluginTemplate::renderPluginTemplate( 68 | 'embeds/youtube-live-stream-amp.twig', 69 | [ 70 | 'aspectRatio' => ($aspectRatioY / $aspectRatioX) * 100, 71 | 'iframeUrl' => $this->getYoutubeStreamUrl(), 72 | ] 73 | ); 74 | } 75 | 76 | /** 77 | * Renders the responsive iframe HTML for the live stream chat 78 | * 79 | * @param int $aspectRatioX 80 | * @param int $aspectRatioY 81 | * 82 | * @return Markup 83 | */ 84 | public function embedChat(int $aspectRatioX = 16, int $aspectRatioY = 9): Markup 85 | { 86 | return PluginTemplate::renderPluginTemplate( 87 | 'embeds/youtube-live-chat.twig', 88 | [ 89 | 'aspectRatio' => ($aspectRatioY / $aspectRatioX) * 100, 90 | 'iframeUrl' => $this->getYoutubeChatUrl(), 91 | 'embedDomain' => $this->getSiteDomain(), 92 | ] 93 | ); 94 | } 95 | 96 | /** 97 | * Renders the responsive Google AMP iframe HTML for the live stream chat 98 | * 99 | * @param int $aspectRatioX 100 | * @param int $aspectRatioY 101 | * 102 | * @return Markup 103 | */ 104 | public function embedChatAmp(int $aspectRatioX = 16, int $aspectRatioY = 9): Markup 105 | { 106 | return PluginTemplate::renderPluginTemplate( 107 | 'embeds/youtube-live-chat-amp.twig', 108 | [ 109 | 'aspectRatio' => ($aspectRatioY / $aspectRatioX) * 100, 110 | 'iframeUrl' => $this->getYoutubeChatUrl(), 111 | 'embedDomain' => $this->getSiteDomain(), 112 | ] 113 | ); 114 | } 115 | 116 | /** 117 | * Sets the YouTube Channel ID to $channelId 118 | * 119 | * @param string $channelId 120 | */ 121 | public function setChannelId(string $channelId): void 122 | { 123 | YoutubeLiveEmbed::$youtubeChannelId = $channelId; 124 | } 125 | 126 | /** 127 | * Returns whether the stream is currently live 128 | * 129 | * @return bool 130 | */ 131 | public function isLive(): bool 132 | { 133 | /** @var Settings $settings */ 134 | $settings = YoutubeLiveEmbed::$plugin->getSettings(); 135 | return $settings->isLive; 136 | } 137 | 138 | // Protected Methods 139 | // ========================================================================= 140 | 141 | /** 142 | * Returns the URL to the live video YouTube page 143 | * 144 | * @return string 145 | */ 146 | protected function getYoutubeStreamUrl(): string 147 | { 148 | return UrlHelper::urlWithParams(self::YOUTUBE_STREAM_URL, [ 149 | 'channel' => YoutubeLiveEmbed::$youtubeChannelId, 150 | ]); 151 | } 152 | 153 | /** 154 | * Returns the URL to the live chat YouTube page 155 | * 156 | * @return string 157 | */ 158 | protected function getYoutubeChatUrl(): string 159 | { 160 | $url = ''; 161 | $videoId = $this->getVideoIdFromLiveStream(); 162 | if ($videoId) { 163 | $url = UrlHelper::urlWithParams(self::YOUTUBE_CHAT_URL, [ 164 | 'v' => $this->getVideoIdFromLiveStream(), 165 | 'embed_domain' => $this->getSiteDomain(), 166 | ]); 167 | } 168 | 169 | return $url; 170 | } 171 | 172 | 173 | /** 174 | * Returns the domain of the host site 175 | * 176 | * @return string 177 | */ 178 | protected function getSiteDomain(): string 179 | { 180 | $site = Craft::$app->getSites()->currentSite; 181 | $request = Craft::$app->getRequest(); 182 | $domain = parse_url($site->getBaseUrl(), PHP_URL_HOST); 183 | 184 | return $domain ?? $request->getHostName(); 185 | } 186 | 187 | /** 188 | * Extracts the Video ID of the current live stream video 189 | * 190 | * @return ?string 191 | */ 192 | protected function getVideoIdFromLiveStream(): ?string 193 | { 194 | $videoId = null; 195 | $liveUrl = $this->getYoutubeStreamUrl(); 196 | // Fetch the livestream page 197 | // Find the video ID in there 198 | if (($data = @file_get_contents($liveUrl)) && preg_match('/\"VIDEO_ID\":\"(.*?)\"/', $data, $matches)) { 199 | $videoId = $matches[1]; 200 | } 201 | 202 | return $videoId; 203 | } 204 | } 205 | --------------------------------------------------------------------------------