之前我们已经确定了基本的请求问题
ffmpeg不支持H2协议
根据查看同类库https://github.com/sim0n00ps/OF-DRM (这个库真的帮助了我很多思路)
可以发现使用了一个yt-dlp
我们可以找一个nodejs版本的
测试代码如下
const path = require('path');
const YTDlpWrap = require('yt-dlp-wrap').default;
const ytDlpWrap = new YTDlpWrap(path.join('./yt-dlp_x86.exe'));
let ytDlpEventEmitter = ytDlpWrap
.exec([
'https://cdn3.onlyfans.com/hls/files/a/a2/xxx/xxx.m3u8',
"-f",
"bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best[ext=m4a]",
"--allow-u",
"--no-part",
"--restrict-filenames",
"-N 4",
'--add-headers',
`Cookie:"个人隐私"`,
'-o',
'F:/vmware/output2.mp4',
])
.on('progress', (progress) =>
console.log(
progress.percent,
progress.totalSize,
progress.currentSpeed,
progress.eta
)
)
.on('ytDlpEvent', (eventType, eventData) =>
console.log(eventType, eventData)
)
.on('error', (error) => console.error(error))
.on('close', () => console.log('all done'));
console.log(ytDlpEventEmitter.ytDlpProcess.pid);
我也是刚接触,不一定参数描述的正确,-f表示格式,allow-u表示允许无法格式化的视频下载,no-part不要使用分割部分文件,restrict-filenames貌似是控制短标题和特殊字符的,-N应该是多线程
只有使用这套能绕过DRM的版权下载问题
下载完成后发现依然没法播放
根据研究是视频使用了加密
这个时候可以根据技术栈下手
根据搜索drm找到了"DRM encrypted source cannot be decrypted without a DRM plugin
根据上下文找到videojs字样
![图片.png](data/attachment/forum/202406/21/072412aa7azqadq3zq75tj.png)
所以怀疑是videojs
于是找videojs的DRM库,找到了
https://github.com/videojs/videojs-contrib-eme?tab=readme-ov-file#using
使用例子是
player.eme();
player.src({
src: '<your url here>',
type: 'application/dash+xml',
keySystems: {
'com.widevine.alpha': '<YOUR URL HERE>'
}
});
在网页中搜索eme,发现也能找到,下一个断点之后调试打印src的o内容
![图片.png](data/attachment/forum/202406/21/072511pelavo0r0d9tmdol.png)
根据文档getLicense()- 允许异步检索许可证。
所以我们目前应该主攻getLicense()函数了
其中代码为
getLicense: (e,s,o)=>{
j.vM.xhr({
url: i,
method: "POST",
responseType: "arraybuffer",
body: new Uint8Array(s),
headers: {
"Content-type": "application/octet-stream",
...t
},
withCredentials: !0
}, ((e,i,t)=>{
e ? o(e) : o(null, t)
}
))
}
往上一层看
这里可以看到创建了一个promise,当调用获取许可时会回调y,而y会把数据触发调用promise的Resolve出去,导致普通人很容易跟丢
![图片.png](data/attachment/forum/202406/21/073129mojdh3494dg46lh6.png)
实际上接下来的流程处理在
![图片.png](data/attachment/forum/202406/21/073222bc8jjs9qbbzmaz1a.png)
其中u是MediaKeySession,读取了我们的密钥,而MediaKeySession的接口代表与内容解密模块 (CDM) 进行消息交换的上下文。
以CDM为关键词,可以搜到https://www.freebuf.com/articles/database/375523.html
全球现有三大实现方案,分别为谷歌的Widevine、苹果的FairPlay和微软的PlayReady。其中Widevine实现简单,免费,市场占有率最高,应用最广泛。Widevine客户端主要内置于手机、电视、各大浏览器、播放器等,用于解密被保护的视频。
Widevine拥有三个安全级别——L1、L2和L3。L1是最高的安全级别,解密全过程在硬件中完成,需要设备支持。L3的安全级别最低,解密全程在CDM(Content Decryption Module )软件中完成。L2介于两者之间, 核心解密过程在硬件完成,视频处理阶段在软件中完成。本文只讨论L3级视频的解密方式。
既然我们是谷歌浏览器,那我们大概率是Widevine的DRM保护了
那接下来的目标就是如何解密CDM
待续