我正在尝试找到一种方法来从 youtube 上的每个视频获取音频流 url。我设法获取一些视频的 URL,解析 json 并获取自适应格式 url,但大多数视频使用“signatureCipher”并且该 URL 不起作用。有没有办法解码它以获取 JS 中的工作音频 url?
在 MSEdge 中,打开开发工具控制台并输入“importer(video_id)”。将 video_id 替换为您的视频 ID。所有流链接都将显示在 iframe 下。您必须解锁 CORS。对于此下载 CORS 解锁扩展,请访问此链接:
https://microsoftedge.microsoft.com/addons/detail/cors-unblock/hkjklmhkbkdhlgnnfbbcihcajofmjgbh
事实上,当您在打开控制台的情况下获取 YouTube 地址时,www.youtube.com 会被重定向到 m.youtube.com(Android 应用程序)。您可以通过其他方式访问 m.youtube.com。然后单击您选择的链接以将其显示在 iframe 中,或者复制该链接并将其粘贴到浏览器地址栏中以在新选项卡中访问它。这些不是真正的链接,只是带有文本内容的 div。
这是我写的代码。
<html>
<head>
<style>
body{background:black;}
</style>
</head>
<body>
<input type="button" style="background:black;border:gray solid 4px;border-style:outset;color:green;" onmousedown="importer(document.querySelector('#inp001').value)" value="Importer"/><input id="inp001" style="background:black;color:green;" value="V9PVRfjEBTI"/><br>
<iframe style="height:100%;width:100%;" src="https://www.youtube.com"></iframe>
<script>
async function importer(christ){const r = await fetch(`https://m.youtube.com/watch?v=${christ}`);
const t = await r.text();
const index1 = t.indexOf("jsUrl")+8;
const sub1 = t.substring(index1);
const index2 = sub1.indexOf('"');
const sub2 = sub1.substring(0,index2);
const base = `https://m.youtube.com${sub2}`;
const r2 = await fetch(base);
const t2 = await r2.text();
const index3 = t2.indexOf('a.split("");');
const sub3 = t2.substring(0,index3);
const index4 = sub3.lastIndexOf("function")-4;
const variable1 = sub3.substring(index4,index4+3);
const variable2 = t2.substring(index3+12,index3+12+2);
const index5 = t2.indexOf("var b=a.split(a");
const sub4 = t2.substring(0,index5);
const index6 = sub4.lastIndexOf("function")-4;
const variable3 = sub4.substring(index6,index6+3);
console.log(variable1,variable2,variable3);
const scr = document.createElement("script");
scr.textContent = t2.replace("})(_yt_player);",`window['var1']=eval(${variable3});window['var2']=eval(${variable1});window['var3']=eval(${variable2});})(_yt_player);`);
document.body.insertBefore(scr,document.querySelector("script"));
const doc = document.implementation.createHTMLDocument();
doc.write(t);
console.log(doc);
const arr = doc.querySelectorAll("script");
const scr2 = Array.from(arr).filter((x)=>{if(x.textContent.match("ytInitialPlayerResponse")!==null){return x}});
const scr3 = document.createElement("script");
scr3.textContent = scr2[1].textContent;
document.body.insertBefore(scr3,document.querySelectorAll("script")[1]);
const adapt = ytInitialPlayerResponse.streamingData.adaptiveFormats;
const arr2 = Array.from(adapt);
arr2.forEach((item,index)=>{
const sign = item.signatureCipher;
const para = new URLSearchParams(sign);
const s = para.get("s");
const nsig = window['var2'](s);
const url = para.get("url");
const url2 = new URL(url);
const n = url2.searchParams.get("n");
const n2 = window['var1'](n);
url2.searchParams.set("n",n2);
url2.searchParams.set("sig",nsig);
const div = document.createElement("div");
div.textContent = url2.href;
div.style.color = "green";
div.style.cursor = "grab";
console.log(url2.href);
div.addEventListener("mousedown",function(event){document.querySelector("iframe").src=event.currentTarget.textContent;event.currentTarget.style.color="blue";});
document.body.insertBefore(div,document.querySelector("script"));
const div2 = document.createElement("div");
div2.innerText = "\n\n";
div.after(div2);
});
};
</script>
</body>
</html>
这是一个正在运行的 infinityfreeapp.com 示例。不要忘记在 MsEdge 或 Google Chrome 中打开 Devtools 控制台。这是我自己的网站,因此没有订阅、广告或弹出窗口。
http://leseditionslyriques.infinityfreeapp.com/Youtuber.html
好吧,我已经用纯 Javascript 破译了 SignatureCipher。
为了混合音频和视频流,我推荐 ffmpeg fun tab 扩展,例如,无需桌面应用程序即可在线完成所有工作。你可以在这里找到它:
https://chromewebstore.google.com/detail/ffmpeg-fun-tab/jknbmdhgmkaegnckekoibhlabacgafab
或者直接使用 ffmpeg.exe。