Skip to content
3 changes: 3 additions & 0 deletions config.default.ini.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@
; If false, a clickable video thumbnail is used instead. This avoids sending a referrer to YouTube or only getting the error 153 if suppressing the referrer browser-wide.
iframe = true

; If still getting error 153 you can selfhost the link over this rss-bridge instance, which should avoid this error.
rss-bridge-iframe = false

; Use the youtube-nocookie.com domain instead of youtube.com for iframe embeds.
; Only relevant if youtube.iframe is true.
; See the following for a description:
Expand Down
13 changes: 12 additions & 1 deletion lib/html.php
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,7 @@ function handleYoutube(string $string)
{
$useIframe = Configuration::getConfig('youtube', 'iframe');
$useNocookie = Configuration::getConfig('youtube', 'nocookie');
$useRssBridgeIframe = Configuration::getConfig('youtube', 'rss-bridge-iframe');

// sourced from https://gist.github.com/afeld/1254889?permalink_comment_id=3580082#gistcomment-3580082
$regex = '#(?:https?://|//)?(?:www\.|m\.|.+\.)?(?:youtu\.be/|youtube(?:-nocookie)\.com/(?:embed/|v/|shorts/|feeds/api/videos/|watch\?v=|watch\?.+&v=))([\w-]{11})#i';
Expand All @@ -564,7 +565,7 @@ function handleYoutube(string $string)
return '';
}

if ($useIframe) {
if ($useIframe == true) {
if ($useNocookie) {
$embedUri = 'https://www.youtube-nocookie.com/embed/' . $videoID;
} else {
Expand All @@ -575,6 +576,16 @@ function handleYoutube(string $string)
<iframe width="560" height="315" src="%s" title="YouTube video player" frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerpolicy="strict-origin" allowfullscreen></iframe>'
EOD
, $embedUri);
} elseif ($useIframe == true && $useRssBridgeIframe == true) {
$rssbridgedir = dirname($_SERVER['PHP_SELF']);
$embedUri = 'https://' . $_SERVER['SERVER_NAME'] . $rssbridgedir . '/templates/youtube-iframe.html?v=' . $videoID;

return sprintf(<<<EOD
<iframe width="560" height="315" src="%s" title="YouTube video player" frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerpolicy="strict-origin" allowfullscreen></iframe>'
EOD
, $embedUri);
} else {
Expand Down
92 changes: 92 additions & 0 deletions templates/youtube-iframe.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<meta name="referrer" content="strict-origin-when-cross-origin">
<title>YouTube Video</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

html, body {
width: 100%;
height: 100%;
overflow: hidden;
background: #000;
}

#player {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: 0;
}
</style>
</head>
<body>
<iframe
id="player"
allowfullscreen
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerpolicy="strict-origin-when-cross-origin"
></iframe>

<script>
(function() {
// Parse URL parameters
const urlParams = new URLSearchParams(window.location.search);

// Get video ID (required)
const videoId = urlParams.get('v');
if (!videoId) {
document.body.innerHTML = '<div style="color: white; padding: 20px; text-align: center;">Error: Missing video ID parameter (?v=VIDEO_ID)</div>';
return;
}

// Get optional parameters with defaults
const autoplay = urlParams.get('autoplay') || '0';
const loop = urlParams.get('loop') || '0';
const mute = urlParams.get('mute') || '0';
const playlist = urlParams.get('playlist') || videoId;
const controls = urlParams.get('controls') || '1';
const rel = urlParams.get('rel') || '0';
const modestbranding = urlParams.get('modestbranding') || '1';
const playsinline = urlParams.get('playsinline') || '1';

// Build YouTube embed URL parameters
const embedParams = new URLSearchParams({
autoplay: autoplay,
controls: controls,
rel: rel,
modestbranding: modestbranding,
playsinline: playsinline,
enablejsapi: '1',
origin: window.location.origin
});

// Add loop and playlist if loop is enabled
if (loop === '1') {
embedParams.append('loop', '1');
embedParams.append('playlist', playlist);
}

// Add mute if enabled
if (mute === '1') {
embedParams.append('mute', '1');
}

// Construct final URL
const embedUrl = `https://www.youtube-nocookie.com/embed/${encodeURIComponent(videoId)}?${embedParams.toString()}`;

// Set iframe src
document.getElementById('player').src = embedUrl;
})();
</script>
</body>
</html>
Loading