diff --git a/README.md b/README.md
index 1562d41..1ec5188 100644
--- a/README.md
+++ b/README.md
@@ -55,24 +55,31 @@ $localVideo = new Video('/pfad/zum/video.mp4', 'Eigenes Video');
echo $localVideo->generate();
```
-## 🛠 Die Methoden
+Gerne, hier ist die ergänzte Version der Methodenübersicht mit Rückgabetypen:
+
+## 🛠 Die Class
### Konstruktor
```php
-__construct($source, $title = '', $lang = 'de')
+__construct($source, $title = '', $lang = 'de'): void
```
- `$source`: URL oder Pfad zum Video (Pflicht)
- `$title`: Titel des Videos (Optional)
- `$lang`: Sprachcode (Optional, Standard: 'de')
-### Weitere Methoden
+### Methoden
+- `setAttributes(array $attributes): void`: Zusätzliche Player-Attribute
+- `setA11yContent($description, $alternativeUrl = ''): void`: Barrierefreiheits-Infos
+- `setThumbnails($thumbnailsUrl): void`: Thumbnail-Vorschaubilder (VTT-Format)
+- `addSubtitle($src, $kind, $label, $lang, $default = false): void`: Untertitel hinzufügen
+- `generateFull(): string`: Vollständiger HTML-Code mit allen Schikanen
+- `generate(): string`: Einfacher Video-Player ohne Schnickschnack
+- `isMedia($url): bool`: Prüft, ob es sich um eine Mediendatei handelt
+- `isAudio($url): bool`: Prüft, ob es sich um eine Audiodatei handelt
+- `videoOembedHelper(): void`: Registriert einen Output-Filter für oEmbed-Tags
+- `parseOembedTags(string $content): string`: Parst oEmbed-Tags im Inhalt
+- `show_sidebar(\rex_extension_point $ep): ?string`: Generiert Medienvorschau für die Sidebar im Medienpool
-- `setAttributes(array $attributes)`: Zusätzliche Player-Attribute
-- `setA11yContent($description, $alternativeUrl = '')`: Barrierefreiheits-Infos
-- `setThumbnails($thumbnailsUrl)`: Thumbnail-Vorschaubilder (VTT-Format)
-- `addSubtitle($src, $kind, $label, $lang, $default = false)`: Untertitel hinzufügen
-- `generateFull()`: Vollständiger HTML-Code mit allen Schikanen
-- `generate()`: Einfacher Video-Player ohne Schnickschnack
## 📋 Optionen und Pflichtangaben
@@ -224,6 +231,15 @@ $easyVideo = createDefaultVideo('https://youtube.com/watch?v=abcdefg', 'Einfach
echo $easyVideo->generateFull();
```
+## 🎸 Unterstützung für Audio-Dateien
+
+Das Addon unterstützt auch die Einbindung von Audio-Dateien. Genauso wie für Videos:
+
+```php
+$audio = new Video('audio.mp3', 'Mein Lieblingssong');
+echo $audio->generate();
+```
+
## ✔︎ Im Backend schon integriert
Hier muss man nichts machen - außer Videos schauen.
diff --git a/assets/vidstack_helper.js b/assets/vidstack_helper.js
index a01764b..417ac45 100644
--- a/assets/vidstack_helper.js
+++ b/assets/vidstack_helper.js
@@ -1,13 +1,11 @@
-(function() {
+(function () {
let translations = {};
async function loadTranslations() {
try {
- const response = await fetch('/assets/addons/vidstack/translations.json');
- translations = await response.json();
+ translations = await (await fetch('/assets/addons/vidstack/translations.json')).json();
} catch (error) {
console.error('Fehler beim Laden der Übersetzungen:', error);
- // Fallback zu leeren Übersetzungen, wenn das Laden fehlschlägt
translations = { de: {}, en: {} };
}
}
@@ -16,124 +14,107 @@
return (translations[lang] && translations[lang][key]) || key;
}
- async function initializeScript() {
- await loadTranslations();
-
- const consentKey = 'video_consent';
- let videoConsent = JSON.parse(localStorage.getItem(consentKey) || '{}');
+ const consentKey = 'video_consent';
+ let videoConsent = JSON.parse(localStorage.getItem(consentKey) || '{}');
- function setConsent(platform) {
- videoConsent[platform] = true;
- localStorage.setItem(consentKey, JSON.stringify(videoConsent));
- document.cookie = `${platform}_consent=true; path=/; max-age=${30 * 24 * 60 * 60}; SameSite=Lax; Secure`;
- }
+ function setConsent(platform) {
+ videoConsent[platform] = true;
+ localStorage.setItem(consentKey, JSON.stringify(videoConsent));
+ document.cookie = `${platform}_consent=true; path=/; max-age=${30 * 24 * 60 * 60}; SameSite=Lax; Secure`;
+ }
- function hasConsent(platform) {
- return videoConsent[platform] === true || document.cookie.includes(`${platform}_consent=true`);
- }
+ function hasConsent(platform) {
+ return videoConsent[platform] === true || document.cookie.includes(`${platform}_consent=true`);
+ }
- function loadVideo(placeholder) {
- const platform = placeholder.dataset.platform;
- const videoId = placeholder.dataset.videoId;
- const mediaPlayer = placeholder.nextElementSibling;
+ function loadVideo(placeholder) {
+ const { platform, videoId } = placeholder.dataset;
+ const mediaPlayer = placeholder.nextElementSibling;
- if (mediaPlayer && mediaPlayer.tagName.toLowerCase() === 'media-player') {
- mediaPlayer.style.display = '';
- mediaPlayer.setAttribute('src', `${platform}/${videoId}`);
- placeholder.style.display = 'none';
- } else {
- console.error('Media player element not found');
- }
+ if (mediaPlayer?.tagName.toLowerCase() === 'media-player') {
+ mediaPlayer.style.display = '';
+ mediaPlayer.setAttribute('src', `${platform}/${videoId}`);
+ placeholder.style.display = 'none';
+ } else {
+ console.error('Media player element not found');
}
+ }
- function updatePlaceholder(placeholder, consented) {
- const button = placeholder.querySelector('.consent-button');
- const lang = document.documentElement.lang || 'en';
-
- if (consented) {
- button.textContent = getText('Consent given', lang);
- button.disabled = true;
- } else {
- button.textContent = getText('Load Video', lang);
- button.disabled = false;
- }
+ function updatePlaceholder(placeholder, consented) {
+ const button = placeholder.querySelector('.consent-button');
+ const lang = document.documentElement.lang || 'en';
+
+ if (button) {
+ button.textContent = getText(consented ? 'Consent given' : 'Load Video', lang);
+ button.disabled = consented;
}
+ }
- function initializePlaceholders() {
- document.querySelectorAll('.consent-placeholder').forEach(placeholder => {
- const platform = placeholder.dataset.platform;
- const consentButton = placeholder.querySelector('.consent-button');
- const consented = hasConsent(platform);
+ function initializePlaceholder(placeholder) {
+ const platform = placeholder.dataset.platform;
+ const consented = hasConsent(platform);
- updatePlaceholder(placeholder, consented);
+ updatePlaceholder(placeholder, consented);
- if (consented) {
+ if (consented) {
+ loadVideo(placeholder);
+ } else {
+ const consentButton = placeholder.querySelector('.consent-button');
+ if (consentButton) {
+ consentButton.addEventListener('click', () => {
+ setConsent(platform);
+ updatePlaceholder(placeholder, true);
loadVideo(placeholder);
- } else {
- if (consentButton) {
- consentButton.addEventListener('click', () => {
- setConsent(platform);
- updatePlaceholder(placeholder, true);
- loadVideo(placeholder);
- });
- } else {
- console.error('Consent button not found in placeholder');
- }
- }
- });
+ });
+ } else {
+ console.error('Consent button not found in placeholder');
+ }
}
+ }
- function initializeMediaPlayers() {
- document.querySelectorAll('media-player[data-video-platform]').forEach(player => {
- const platform = player.dataset.videoPlatform;
- if (hasConsent(platform)) {
- const videoId = player.dataset.videoId;
- player.style.display = '';
- player.setAttribute('src', `${platform}/${videoId}`);
- const placeholder = player.previousElementSibling;
- if (placeholder?.classList.contains('consent-placeholder')) {
- placeholder.style.display = 'none';
- }
- }
- });
+ function initializeMediaPlayer(player) {
+ const platform = player.dataset.videoPlatform;
+ if (hasConsent(platform)) {
+ const videoId = player.dataset.videoId;
+ player.style.display = '';
+ player.setAttribute('src', `${platform}/${videoId}`);
+ const placeholder = player.previousElementSibling;
+ if (placeholder?.classList.contains('consent-placeholder')) {
+ placeholder.style.display = 'none';
+ }
}
+ }
- function applyTranslations() {
- const videoLayouts = document.querySelectorAll('media-video-layout');
- videoLayouts.forEach(layout => {
+ function applyTranslations() {
+ ['media-video-layout', 'media-audio-layout'].forEach(selector => {
+ document.querySelectorAll(selector).forEach(layout => {
const player = layout.closest('media-player');
const lang = player?.getAttribute('lang') || 'en';
layout.translations = translations[lang] || translations['en'];
});
+ });
+ }
- document.querySelectorAll('.consent-placeholder').forEach(placeholder => {
- const lang = document.documentElement.lang || 'en';
- const button = placeholder.querySelector('.consent-button');
- const text = placeholder.querySelector('p');
- if (button) {
- // button.textContent = getText('Load Video', lang);
- }
- if (text) {
- // text.textContent = getText('Click here to load and play the video.', lang);
- }
- });
- }
-
- initializePlaceholders();
- initializeMediaPlayers();
+ function initializeElements() {
+ document.querySelectorAll('.consent-placeholder').forEach(initializePlaceholder);
+ document.querySelectorAll('media-player[data-video-platform]').forEach(initializeMediaPlayer);
applyTranslations();
+ }
+
+ async function initializeScript() {
+ await loadTranslations();
+ initializeElements();
- // Beobachter für dynamisch hinzugefügte Elemente
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'childList') {
mutation.addedNodes.forEach((node) => {
if (node.nodeType === Node.ELEMENT_NODE) {
if (node.classList.contains('consent-placeholder')) {
- initializePlaceholders();
+ initializePlaceholder(node);
}
if (node.tagName.toLowerCase() === 'media-player') {
- initializeMediaPlayers();
+ initializeMediaPlayer(node);
applyTranslations();
}
}
@@ -145,19 +126,15 @@
observer.observe(document.body, { childList: true, subtree: true });
}
- // Skript bei DOMContentLoaded ausführen
- document.addEventListener('DOMContentLoaded', initializeScript);
+ ['DOMContentLoaded', 'vsrun'].forEach(event =>
+ document.addEventListener(event, initializeScript)
+ );
- // Skript bei rex:ready ausführen, wenn jQuery verfügbar ist
if (typeof jQuery !== 'undefined') {
jQuery(document).on('rex:ready', initializeScript);
}
- // Skript bei vsrun-Event ausführen
- document.addEventListener('vsrun', initializeScript);
-
- // Skript sofort ausführen, wenn das DOM bereits geladen ist
- if (document.readyState === 'complete' || document.readyState === 'interactive') {
+ if (['complete', 'interactive'].includes(document.readyState)) {
initializeScript();
}
})();
diff --git a/lib/video.php b/lib/video.php
index 05e1255..e93b642 100644
--- a/lib/video.php
+++ b/lib/video.php
@@ -23,7 +23,7 @@ public function __construct(string $source, string $title = '', string $lang = '
$this->source = $source;
$this->title = $title;
$this->lang = $lang;
- $this->attributes['lang'] = $lang;
+ $this->attributes['lang'] = $lang;
$this->loadTranslations();
}
@@ -98,7 +98,7 @@ private function getAlternativeUrl(): string
public static function isMedia($url): bool
{
$mediaExtensions = ['mp4', 'mov', 'm4v', 'ogg', 'webm', 'mp3', 'wav', 'aac', 'm4a'];
-
+
if (filter_var($url, FILTER_VALIDATE_URL)) {
$pathInfo = pathinfo(parse_url($url, PHP_URL_PATH));
} else {
@@ -108,14 +108,14 @@ public static function isMedia($url): bool
}
$pathInfo = pathinfo($media->getFileName());
}
-
+
return in_array(strtolower($pathInfo['extension'] ?? ''), $mediaExtensions);
}
public static function isAudio($url): bool
{
$audioExtensions = ['mp3', 'ogg', 'wav', 'aac', 'm4a'];
-
+
if (filter_var($url, FILTER_VALIDATE_URL)) {
$pathInfo = pathinfo(parse_url($url, PHP_URL_PATH));
} else {
@@ -125,7 +125,7 @@ public static function isAudio($url): bool
}
$pathInfo = pathinfo($media->getFileName());
}
-
+
return in_array(strtolower($pathInfo['extension'] ?? ''), $audioExtensions);
}
@@ -145,9 +145,6 @@ private function getVideoInfo(): array
public function generateFull(): string
{
$videoInfo = $this->getVideoInfo();
- $attributesString = $this->generateAttributesString();
- $titleAttr = $this->title ? " title=\"" . rex_escape($this->title) . "\"" : '';
-
$isAudio = self::isAudio($this->source);
$mediaType = $isAudio ? 'audio' : 'video';
@@ -163,28 +160,8 @@ public function generateFull(): string
$code .= $this->generateConsentPlaceholder($consentText, $videoInfo['platform'], $videoInfo['id']);
}
- $code .= "