]*>(.*?)<\\/div>/is', $cleanHtml, $blocks, PREG_SET_ORDER)) {
+ foreach ($blocks as $blk) {
+ $full = $blk[0];
+ $inner = $blk[1];
+ if (preg_match('/
]*href=[\"\']([^\"\']+)[\"\']/i', $inner, $am)) {
+ $url = $am[1];
+ $item = $this->buildExternalVideoItemFromUrl($url);
+ if ($item) {
+ $videoItems[] = $item;
+ $cleanHtml = str_replace($full, '', $cleanHtml);
+ }
+ }
+ }
+ }
+
+ return [$cleanHtml, $videoItems];
+ }
+
+ private function buildExternalVideoItemFromUrl(string $url)
+ {
+ $u = trim(html_entity_decode($url, ENT_QUOTES | ENT_HTML5, 'UTF-8'));
+ if ('' === $u) {
+ return null;
+ }
+ $lower = strtolower($u);
+ $mime = null;
+ if (str_contains($lower, 'youtube.com') || str_contains($lower, 'youtu.be')) {
+ $mime = 'video/youtube';
+ } elseif (str_contains($lower, 'vimeo.com')) {
+ $mime = 'video/vimeo';
+ } else {
+ return null; // unsupported provider
+ }
+ $videoParams = [
+ 'sources' => [
+ [
+ 'path' => $u,
+ 'mime' => $mime,
+ ],
+ ],
+ 'visuals' => ['controls' => true],
+ ];
+
+ return [
+ 'content' => [
+ 'params' => $videoParams,
+ 'library' => 'H5P.Video 1.6',
+ 'subContentId' => uniqid(),
+ 'metadata' => [
+ 'license' => 'U',
+ 'contentType' => 'Video',
+ 'title' => 'Video',
+ ],
+ ],
+ 'useSeparator' => 'auto',
+ ];
+ }
+
+ private function extractOtherIframesAndBuildItems(
+ string $html,
+ string $sessionDistDir,
+ string $sessionBaseDir,
+ string $odeSessionId,
+ string $mediaDir,
+ array &$copiedMedia,
+ ): array {
+ $cleanHtml = $html;
+ $items = [];
+
+ // Generic iframe finder
+ if (!preg_match_all('/