Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save shalakolee/8618eb479b5b01d89f18aab286acde20 to your computer and use it in GitHub Desktop.

Select an option

Save shalakolee/8618eb479b5b01d89f18aab286acde20 to your computer and use it in GitHub Desktop.
(async () => {
const match = window.location.pathname.match(/video\/([a-zA-Z0-9]+)/);
if (!match) {
console.log("Video ID not found in URL.");
return;
}
const videoId = match[1];
const metaUrl = `https://www.dailymotion.com/player/metadata/video/${videoId}?embedder=${location.hostname}`;
const absolutize = (base, relative) => {
try { return new URL(relative, base).toString(); } catch { return relative; }
};
try {
const metaRes = await fetch(metaUrl);
const data = await metaRes.json();
if (!data?.qualities) {
console.log("No qualities object found in metadata.");
return;
}
// 1) Print whatever qualities are directly listed in metadata (sometimes MP4/progressive appear here)
console.log("=== Metadata qualities (direct) ===");
for (const q of Object.keys(data.qualities)) {
const arr = data.qualities[q];
if (!Array.isArray(arr)) continue;
arr.forEach((s, i) => {
if (s?.url) console.log(`${q}[${i}]: ${s.url}`);
});
}
// 2) If only "auto" exists, it's usually a master HLS playlist containing all variants.
const masterUrl = data?.qualities?.auto?.[0]?.url;
if (!masterUrl) {
console.log("No auto/master m3u8 found at data.qualities.auto[0].url");
return;
}
console.log("\n=== Parsing HLS master playlist (auto) for variants ===");
console.log("Master m3u8:", masterUrl);
const m3u8Res = await fetch(masterUrl);
const m3u8Text = await m3u8Res.text();
// Parse #EXT-X-STREAM-INF blocks
// Format:
// #EXT-X-STREAM-INF:BANDWIDTH=...,RESOLUTION=WxH,CODECS="..."
// <variant-playlist-url>
const lines = m3u8Text.split("\n").map(l => l.trim()).filter(Boolean);
const variants = [];
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
if (line.startsWith("#EXT-X-STREAM-INF:")) {
const attrs = line.substring("#EXT-X-STREAM-INF:".length);
const bw = (attrs.match(/BANDWIDTH=(\d+)/) || [])[1] || "";
const res = (attrs.match(/RESOLUTION=(\d+x\d+)/) || [])[1] || "";
const codecs = (attrs.match(/CODECS="([^"]+)"/) || [])[1] || "";
const next = lines[i + 1]; // usually the URL line
if (next && !next.startsWith("#")) {
variants.push({
bandwidth: bw,
resolution: res,
codecs,
url: absolutize(masterUrl, next),
});
}
}
}
if (!variants.length) {
console.log("No variant streams found in master playlist. (It may be a single-level playlist.)");
return;
}
// Sort: highest resolution (height) first, fallback to bandwidth
variants.sort((a, b) => {
const ah = a.resolution ? parseInt(a.resolution.split("x")[1], 10) : 0;
const bh = b.resolution ? parseInt(b.resolution.split("x")[1], 10) : 0;
if (bh !== ah) return bh - ah;
return (parseInt(b.bandwidth, 10) || 0) - (parseInt(a.bandwidth, 10) || 0);
});
console.table(variants);
// Also print as copy-friendly text
console.log("\nCopy-friendly list:");
console.log(
variants
.map(v => `${v.resolution || "?"} ${v.bandwidth ? `(${v.bandwidth})` : ""}: ${v.url}`)
.join("\n")
);
} catch (e) {
console.error("Failed:", e);
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment