fix Youtube
This commit is contained in:
58
app.js
58
app.js
@@ -3,38 +3,18 @@
|
|||||||
|
|
||||||
var TWITCH_CHANNEL = "duda_xd";
|
var TWITCH_CHANNEL = "duda_xd";
|
||||||
|
|
||||||
/* ------------------------------------------------------------------
|
/* Rendert die Video-IDs aus videos.js als iframes.
|
||||||
* YouTube: Liest die Datei videos.json, die auf dem Server von
|
* Standard-iframe laut YouTube-Empfehlung. Bewusst OHNE
|
||||||
* fetch_videos.py (einmal am Tag per Cron) mit den aktuellen
|
* referrerpolicy und OHNE ?si-Parameter: Dann sendet der Browser
|
||||||
* Video-IDs deines Kanals aktualisiert wird.
|
* immer einen Referer (auch bei HTTP-Seite), den YouTube braucht,
|
||||||
*
|
* um den Embedder zu erkennen (sonst Fehler 152/153). */
|
||||||
* Dein API-Key ist dabei NIE im Browser - er bleibt komplett auf
|
function renderYouTubeGrid(videoIds) {
|
||||||
* dem Server versteckt (siehe fetch_videos.py).
|
|
||||||
* ------------------------------------------------------------------ */
|
|
||||||
function loadYouTube() {
|
|
||||||
var grid = document.getElementById("yt-grid");
|
var grid = document.getElementById("yt-grid");
|
||||||
if (!grid) return;
|
if (!grid) return;
|
||||||
|
if (!videoIds || !videoIds.length) {
|
||||||
fetch("videos.json", { cache: "no-cache" })
|
|
||||||
.then(function (r) {
|
|
||||||
if (!r.ok) throw new Error("HTTP " + r.status);
|
|
||||||
return r.json();
|
|
||||||
})
|
|
||||||
.then(function (ids) {
|
|
||||||
if (!Array.isArray(ids) || !ids.length) {
|
|
||||||
grid.innerHTML = '<div class="loading">Noch keine Videos vorhanden.</div>';
|
grid.innerHTML = '<div class="loading">Noch keine Videos vorhanden.</div>';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
renderYouTubeGrid(ids);
|
|
||||||
})
|
|
||||||
.catch(function () {
|
|
||||||
grid.innerHTML =
|
|
||||||
'<div class="loading error">Videos konnten nicht geladen werden.</div>';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderYouTubeGrid(videoIds) {
|
|
||||||
var grid = document.getElementById("yt-grid");
|
|
||||||
var html = "";
|
var html = "";
|
||||||
for (var i = 0; i < videoIds.length; i++) {
|
for (var i = 0; i < videoIds.length; i++) {
|
||||||
var id = String(videoIds[i]).trim();
|
var id = String(videoIds[i]).trim();
|
||||||
@@ -42,17 +22,31 @@
|
|||||||
html +=
|
html +=
|
||||||
'<div class="video-card">' +
|
'<div class="video-card">' +
|
||||||
'<div class="video-wrapper">' +
|
'<div class="video-wrapper">' +
|
||||||
'<iframe src="https://www.youtube.com/embed/' + id +
|
'<iframe width="560" height="315" ' +
|
||||||
'" title="Duda17 Video" ' +
|
'src="https://www.youtube.com/embed/' + id + '" ' +
|
||||||
'frameborder="0" allow="accelerometer; autoplay; clipboard-write; ' +
|
'title="YouTube video player" ' +
|
||||||
'encrypted-media; gyroscope; picture-in-picture; web-share" ' +
|
'frameborder="0" ' +
|
||||||
'referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>' +
|
'allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" ' +
|
||||||
|
'allowfullscreen></iframe>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
}
|
}
|
||||||
grid.innerHTML = html || '<div class="loading">Keine Videos gefunden.</div>';
|
grid.innerHTML = html || '<div class="loading">Keine Videos gefunden.</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------
|
||||||
|
* YouTube: Liest die Video-IDs aus videos.js, die auf dem Server
|
||||||
|
* von fetch_videos.py (einmal am Tag per Cron) mit den aktuellen
|
||||||
|
* Video-IDs deines Kanals aktualisiert wird.
|
||||||
|
*
|
||||||
|
* Dein API-Key ist dabei NIE im Browser - er bleibt komplett auf
|
||||||
|
* dem Server versteckt (siehe fetch_videos.py).
|
||||||
|
* ------------------------------------------------------------------ */
|
||||||
|
function loadYouTube() {
|
||||||
|
var ids = (typeof DUDA17_VIDEOS !== "undefined") ? DUDA17_VIDEOS : [];
|
||||||
|
renderYouTubeGrid(ids);
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------
|
/* ------------------------------------------------------------------
|
||||||
* Twitch: Live-Player einbetten.
|
* Twitch: Live-Player einbetten.
|
||||||
* ------------------------------------------------------------------ */
|
* ------------------------------------------------------------------ */
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ Dieses Skript laeuft auf deinem Server (einmal am Tag per Cron)
|
|||||||
und holt automatisch die aktuellen Video-IDs deines YouTube-Kanals
|
und holt automatisch die aktuellen Video-IDs deines YouTube-Kanals
|
||||||
ueber die offizielle YouTube Data API v3.
|
ueber die offizielle YouTube Data API v3.
|
||||||
|
|
||||||
Es schreibt die Video-IDs in die Datei "videos.json", die deine
|
Es schreibt die Video-IDs in die Datei "videos.js", die deine
|
||||||
Webseite dann einfach liest und anzeigt. So bleibt dein API-Key
|
Webseite dann per Script-Tag laedt und anzeigt. So bleibt dein API-Key
|
||||||
auf dem Server versteckt und ist NICHT im Browser/DevTools sichtbar.
|
auf dem Server versteckt und ist NICHT im Browser/DevTools sichtbar.
|
||||||
|
|
||||||
EINRICHTUNG:
|
EINRICHTUNG:
|
||||||
@@ -102,14 +102,18 @@ def main():
|
|||||||
# hier nach Erscheinungsdatum sortieren, um sicherzugehen)
|
# hier nach Erscheinungsdatum sortieren, um sicherzugehen)
|
||||||
items.sort(key=lambda x: x.get("published") or "", reverse=True)
|
items.sort(key=lambda x: x.get("published") or "", reverse=True)
|
||||||
|
|
||||||
# Nur die IDs in die Datei schreiben - schlank fuer die Webseite,
|
# Nur die Video-IDs in die Datei "videos.js" schreiben.
|
||||||
# die nur die Embed-URLs braucht.
|
# videos.js wird per Script-Tag geladen - dadurch gibt es KEINE
|
||||||
|
# CORS-/fetch-Probleme und die Seite funktioniert ueberall.
|
||||||
video_ids = [v["id"] for v in items]
|
video_ids = [v["id"] for v in items]
|
||||||
|
|
||||||
os.makedirs(OUT_DIR, exist_ok=True)
|
os.makedirs(OUT_DIR, exist_ok=True)
|
||||||
out_path = os.path.join(OUT_DIR, "videos.json")
|
out_path = os.path.join(OUT_DIR, "videos.js")
|
||||||
with open(out_path, "w", encoding="utf-8") as f:
|
with open(out_path, "w", encoding="utf-8") as f:
|
||||||
json.dump(video_ids, f, ensure_ascii=False, indent=2)
|
f.write("/* Automatisch generiert von fetch_videos.py - nicht manuell editieren. */\n")
|
||||||
|
f.write("var DUDA17_VIDEOS = ")
|
||||||
|
json.dump(video_ids, f, ensure_ascii=False, indent=4)
|
||||||
|
f.write(";\n")
|
||||||
|
|
||||||
print(f"Erfolgreich. {len(video_ids)} Videos geschrieben nach {out_path}")
|
print(f"Erfolgreich. {len(video_ids)} Videos geschrieben nach {out_path}")
|
||||||
|
|
||||||
|
|||||||
@@ -162,6 +162,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
<script src="videos.js"></script>
|
||||||
<script src="app.js"></script>
|
<script src="app.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
[
|
/* Automatisch generiert von fetch_videos.py - nicht manuell editieren. */
|
||||||
|
var DUDA17_VIDEOS = [
|
||||||
"HPEbsIInMEg",
|
"HPEbsIInMEg",
|
||||||
"4I8ay7l4Gfk",
|
"4I8ay7l4Gfk",
|
||||||
"AZycMlj2FJc",
|
"AZycMlj2FJc",
|
||||||
@@ -7,4 +8,4 @@
|
|||||||
"8TJGbSExWTc",
|
"8TJGbSExWTc",
|
||||||
"KIpWKm5puIw",
|
"KIpWKm5puIw",
|
||||||
"HPKnQa6Dv4k"
|
"HPKnQa6Dv4k"
|
||||||
]
|
];
|
||||||
Reference in New Issue
Block a user