nilaoda / N_m3u8DL-CLI

[.NET] m3u8 downloader 开源的命令行m3u8/HLS/dash下载器,支持普通AES-128-CBC解密,多线程,自定义请求头等. 支持简体中文,繁体中文和英文. English Supported.
https://nilaoda.github.io/N_m3u8DL-CLI/
MIT License
14.37k stars 2.17k forks source link

求教DMM视频流破解方法; #473

Open tkbianyuan opened 3 years ago

tkbianyuan commented 3 years ago

EXTM3U

EXT-X-VERSION:3

EXT-X-TARGETDURATION:5

EXT-X-MEDIA-SEQUENCE:0

EXT-X-KEY:METHOD=AES-128,URI="https://www.dmm.com/service/-/drm_iphone?ld=IBaD%2BQ72dPSQw780KGJEaF3mBxEpqAGiYGK7JrXe2Q0o61WY%2BCSjhLGrGhrJaZAsddpvbF173Lrl7xEmiWBWOip1OnExBBrmpp69oaHSCy0%2FD0rGUNb3zsVXMDVpP31PCdEB9xThKpHEjo8ufDHBSw%3D%3D&luid=com"

EXTINF:4.004,

media_b300000_0.ts

EXTINF:4.004,

media_b300000_1.ts

EXTINF:4.004,

media_b300000_2.ts

lvzhenbo commented 1 year ago

cococut 不就行了嗎,, 根本不用搞那麼多

这玩意要钱,连复制链接都要钱

LuisLuii commented 1 year ago

cococut 不就行了嗎,, 根本不用搞那麼多

这玩意要钱,连复制链接都要钱

免費就行, 不用錢

ghyjnb commented 10 months ago

大佬 微信截图_20231223134513 为什么下载不了

Heisenberg5201314 commented 10 months ago

有自动化脚本吗

Kerwin366 commented 7 months ago

4K视频现在要如何抓取呀,现在用的不是m3u8格式而是mpd格式了

lvzhenbo commented 7 months ago

4K视频现在要如何抓取呀,现在用的不是m3u8格式而是mpd格式了

dmm目前还是保留了m3u8格式,就在在线播放的下面的h264

June1210 commented 7 months ago

这两天dmm打开视频都这样,根本没法下一步,都不知道是梯子问题还是fanza问题 微信截图_20240407204252

coky666 commented 7 months ago

这两天dmm打开视频都这样,根本没法下一步,都不知道是梯子问题还是fanza问题 微信截图_20240407204252

那個是VPN的問題,surfshark 日本也不能看,不過切到香港就可以

coky666 commented 7 months ago

大佬 微信截图_20231223134513 为什么下载不了

因為你連結是不對的,stc後面有數字就是不對

Qf0602 commented 7 months ago

这两天dmm打开视频都这样,根本没法下一步,都不知道是梯子问题还是fanza问题 微信截图_20240407204252

那個是VPN的問題,surfshark 日本也不能看,不過切到香港就可以

我也这样诶,不是说需要日本本土IP嘛,为什么香港也可以?

ghost commented 6 months ago

dcv已经可以破解了,没必要再用hls的m3u8模式

lvzhenbo commented 6 months ago

dcv已经可以破解了,没必要再用hls的m3u8模式

所以。。。方法呢

ghost commented 6 months ago

dcv已经可以破解了,没必要再用hls的m3u8模式

所以。。。方法呢

不免费谢谢,全网搜dcv破解的方法没有公开的。你需要可以找我买对应影片的key。

coky666 commented 5 months ago

最近鎖海外IP後,m3u8的方法已經不行了...

ghost commented 5 months ago

最近鎖海外IP後,m3u8的方法已經不行了...

和梯子有关系。5.30刚测试的,m3u8依然可以。虽然我用dcv。

lwx1660677335 commented 5 months ago

surfshark

用无限wifi可以避开这个问题.我用网线也是这样

TTKCB commented 5 months ago

最近鎖海外IP後,m3u8的方法已經不行了...

和梯子有关系。5.30刚测试的,m3u8依然可以。虽然我用dcv。

请问我F12打开全是.m4s 也是网络问题吗?

BlueSkyXN commented 4 months ago

最近鎖海外IP後,m3u8的方法已經不行了...

和梯子有关系。5.30刚测试的,m3u8依然可以。虽然我用dcv。

压根不给m3u8,去哪里弄

SameForYou commented 4 months ago

surfshark

用无限wifi可以避开这个问题.我用网线也是这样

无限wifi是什么

lwx1660677335 commented 4 months ago

surfshark

用无限wifi可以避开这个问题.我用网线也是这样

无限wifi是什么

wifi访问

lvzhenbo commented 3 months ago

dcv文件破解流程

需求工具

安卓开发工具,python

获取cdm

https://forum.videohelp.com/threads/408031-Dumping-Your-own-L3-CDM-with-Android-Studio 根据上面链接所说的方式获得cdm的两个文件

获取keyid

n大给了工具https://github.com/nilaoda/Blog/files/5861846/MP4DecryptGUI_20210124.zip 把dcv文件改名成mp4拖进去获得keyid

获取licenseUID和pssh

这一步需要dmm player v2播放器和抓包软件 登录好以后,启动抓包软件,抓取 https://mlic.dmm.com/drm/widevine/license 请求 在请求头的cookie中能够获得licenseUID 在请求体(文本方式查看)中能够获得可读文本类似下面,这就是content-id

{"v":"2","fid":"这里是文件id","svid":"digital","pl":"xxx","cs":"xxx"}

将这个文本原封不动转成base16 https://github.com/shaka-project/shaka-packager/releases 下载pssh-box.py.tar.gz解压运行

python pssh-box.py --base64 --widevine-system-id --key-id '(KID值)' --content-id '(content-id的base16值)'

输出pssh

获取最终的key

下载工具并解压https://github.com/CrymanChen/WKS-KEYS/releases/tag/v2023.04.07 将cdm的两个文件分别重命名为device_client_id_blobdevice_private_key,放到WKS-KEYS\pywidevine\L3\cdm\devices\android_generic\下 修改header.py文件

headers = { 'Host': 'mlic.dmm.com', 'Cookie': 'licenseUID=xxx' }

运行l3.py,按照提示输入pssh和license_url,url为https://mlic.dmm.com/drm/widevine/license,可获得key,在MP4DecryptGUI中输入key,格式选择HEX进行解密

无需dmm player v2

这里唯一的问题就是如何从dmm的cookie中找到所需的数据转成content-id中的pl和cs,我暂时没有找到方法,不知道有没有人能够帮个忙

ex-hentai commented 3 months ago

https://github.com/KamePT/DMM-Decryptor

SameForYou commented 3 months ago

老哥,感谢你的教程,想问下你这些东西哪里学的,我一点也不懂这方面的技术,只会拿别人的脚本运行,不知道有没有这方面的教程文档能学习一下,感谢

------------------ 原始邮件 ------------------ 发件人: @.>; 发送时间: 2024年7月19日(星期五) 中午1:56 收件人: @.>; 抄送: "The saltwater @.>; @.>; 主题: Re: [nilaoda/N_m3u8DL-CLI] 求教DMM视频流破解方法; (#473)

dcv文件破解流程

需求工具

安卓开发工具,python

获取cdm

https://forum.videohelp.com/threads/408031-Dumping-Your-own-L3-CDM-with-Android-Studio 根据上面链接所说的方式获得cdm的两个文件

获取keyid

n大给了工具https://github.com/nilaoda/Blog/files/5861846/MP4DecryptGUI_20210124.zip 把dcv文件改名成mp4拖进去获得keyid

获取licenseUID和pssh

这一步需要dmm player v2播放器和抓包软件 登录好以后,启动抓包软件,抓取 https://mlic.dmm.com/drm/widevine/license 请求 在请求头的cookie中能够获得licenseUID 在请求体(文本方式查看)中能够获得可读文本类似下面,这就是content-id {"v":"2","fid":"这里是文件id","svid":"digital","pl":"xxx","cs":"xxx"}
将这个文本原封不动转成base16 https://github.com/shaka-project/shaka-packager/releases 下载pssh-box.py.tar.gz解压运行 python pssh-box.py --base64 --widevine-system-id --key-id '(KID值)' --content-id '(content-id的base16值)'
输出pssh

获取最终的key

下载工具并解压https://github.com/CrymanChen/WKS-KEYS/releases/tag/v2023.04.07 修改header.py文件 headers = { 'Host': 'mlic.dmm.com', 'Cookie': 'licenseUID=xxx' }
运行l3.py,按照提示输入pssh和license_url,url为https://mlic.dmm.com/drm/widevine/license,可获得key,在MP4DecryptGUI中输入key,格式选择HEX进行解密

无需dmm player v2

这里唯一的问题就是如何从dmm的cookie中找到所需的数据转成content-id中的pl和cs,我暂时没有找到方法,不知道有没有人能够帮个忙

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>

lvzhenbo commented 3 months ago

@ex-hentai 404 @SameForYou 自己捣鼓,需要一些相关方面的知识,相关的库里都有

ex-hentai commented 3 months ago

404

@lvzhenbo 刚转 public

lvzhenbo commented 3 months ago

@ex-hentai 非常感谢,可以省去一些步骤了

BlueSkyXN commented 3 months ago

404

@lvzhenbo 刚转 public

看了下还是不行啊,404

lvzhenbo commented 3 months ago

@BlueSkyXN 他又重新改成私人库了,我正在用bun做一个,已经有结果了,正在收尾,今天或者明天就能发出来

BlueSkyXN commented 3 months ago

@BlueSkyXN 他又重新改成私人库了,我正在用bun做一个,已经有结果了,正在收尾,今天或者明天就能发出来

有意义,过两天看看效果(☻-☻)

lvzhenbo commented 3 months ago

@BlueSkyXN https://github.com/lvzhenbo/dcv-decryptor

wfb2222wfb commented 2 months ago

@lvzhenbo 你好,我通过上述方式拿到了cdm两个文件,但是使用dcv_decryptor拿密钥axios报400 bad request,是拿cdm播放的视频必须是dmm的视频么,我不清楚播放不同的drm视频拿到的文件是否一样

lvzhenbo commented 2 months ago

@wfb2222wfb 首先,我项目都叫dcv的解密器了,你拿不是dmm的视频去用我的工具有啥用,然后其实解密方式都是通用的都是拿到pssh和kid去请求视频网站的key分发服务器,所以你得找到pssh和kid还有你网站对应的key服务器地址才行

wfb2222wfb commented 2 months ago

@lvzhenbo 不知道是不是我描述的有歧义哈,我前面说的播放视频是指https://forum.videohelp.com/threads/408031-Dumping-Your-own-L3-CDM-with-Android-Studio 这里面播放的drm视频dump bin和key这一步骤,后面解密的dcv的确是dmm下载的,你的意思是说dump这一步骤播放的视频需要和解密的dcv一致吗?

lvzhenbo commented 2 months ago

不需要,只要你能够拿到cdm那两个文件就行了 @wfb2222wfb 然后报400是哪个步骤报400

wfb2222wfb commented 2 months ago

@lvzhenbo 拿密钥的时候,前面 licenceUid 和 pssh都拿到了,有没有可能是模拟器模拟手机版本低导致dump的两个文件dmm那边处理不了,我是根据他选择的pixel6操作的,我后来尝试在模拟器里面播放dmm的付费视频,进入播放页面后会报连接错误,不知道有没有关系。

000795435 commented 2 months ago

dcv文件破解流程

需求工具

安卓开发工具,python

获取cdm

https://forum.videohelp.com/threads/408031-Dumping-Your-own-L3-CDM-with-Android-Studio 根据上面链接所说的方式获得cdm的两个文件

获取keyid

n大给了工具https://github.com/nilaoda/Blog/files/5861846/MP4DecryptGUI_20210124.zip 把dcv文件改名成mp4拖进去获得keyid

获取licenseUID和pssh

这一步需要dmm player v2播放器和抓包软件 登录好以后,启动抓包软件,抓取 https://mlic.dmm.com/drm/widevine/license 请求 在请求头的cookie中能够获得licenseUID 在请求体(文本方式查看)中能够获得可读文本类似下面,这就是content-id

{"v":"2","fid":"这里是文件id","svid":"digital","pl":"xxx","cs":"xxx"}

将这个文本原封不动转成base16 https://github.com/shaka-project/shaka-packager/releases 下载pssh-box.py.tar.gz解压运行

python pssh-box.py --base64 --widevine-system-id --key-id '(KID值)' --content-id '(content-id的base16值)'

输出pssh

获取最终的key

下载工具并解压https://github.com/CrymanChen/WKS-KEYS/releases/tag/v2023.04.07 将cdm的两个文件分别重命名为device_client_id_blobdevice_private_key,放到WKS-KEYS\pywidevine\L3\cdm\devices\android_generic\下 修改header.py文件

headers = { 'Host': 'mlic.dmm.com', 'Cookie': 'licenseUID=xxx' }

运行l3.py,按照提示输入pssh和license_url,url为https://mlic.dmm.com/drm/widevine/license,可获得key,在MP4DecryptGUI中输入key,格式选择HEX进行解密

无需dmm player v2

这里唯一的问题就是如何从dmm的cookie中找到所需的数据转成content-id中的pl和cs,我暂时没有找到方法,不知道有没有人能够帮个忙

请问链接是不是改了, 我Dev Tool 里抓包发现是https://mlic.dmm.co.jp/drm/clearkey/license

lvzhenbo commented 2 months ago

@wfb2222wfb 安卓版本低才是对的,高了才拿不到,然后dmm播放报错是不是你网络问题,不是非要播放dmm视频,只要能拿到cdm的两个文件就行 @000795435 我的方式只是解密dcv文件,mpd流是是其他方式

wfb2222wfb commented 2 months ago

@lvzhenbo 如果这样的话,前期流程应该都没问题,就是不知道为何拿不到密钥😂

lvzhenbo commented 2 months ago

哪个步骤报错 @wfb2222wfb

wfb2222wfb commented 2 months ago

@lvzhenbo 密钥获取失败 response: { status: 400, statusText: "Bad Request", headers: { date: "Fri, 30 Aug 2024 03:09:21 GMT", "content-type": "application/problem+json; charset=utf-8", "transfer-encoding": "chunked", connection: "keep-alive", "cache-control": "no-store", server: "Microsoft-IIS/10.0", "x-powered-by": "ASP.NET",

lvzhenbo commented 2 months ago

@wfb2222wfb 前面几步都是正常的吗,包括登录、获取pssh和uid

wfb2222wfb commented 2 months ago

@lvzhenbo 是的 WX20240830-140219@2x

接口报错

AxiosError {
  stack: "Error\n    at settle (B:/~BUN/root/dcv-decryptor:36182:12)\n    at handleStreamEnd (B:/~BUN/root/dcv-decryptor:37071:17)\n    at emit (native)\n    at endReadableNT (native)\n    at processTicksAndRejections (native)\n    at <anonymous> (B:/~BUN/root/dcv-decryptor:37817:58)\n    at processTicksAndRejections (native)",
  message: "Request failed with status code 400",
  name: "AxiosError",
  code: "ERR_BAD_REQUEST",
  config: {
    transitional: {
      silentJSONParsing: true,
      forcedJSONParsing: true,
      clarifyTimeoutError: false,
    },
    adapter: [ "xhr", "http", "fetch" ],
    transformRequest: [
      [Function: transformRequest]
    ],
    transformResponse: [
      [Function: transformResponse]
    ],
    timeout: 0,
    xsrfCookieName: "XSRF-TOKEN",
    xsrfHeaderName: "X-XSRF-TOKEN",
    maxContentLength: -1,
    maxBodyLength: -1,
    env: {
      FormData: [Function: FormData2],
      Blob: [class Blob],
    },
    validateStatus: [Function: validateStatus],
    headers: {
      Accept: "application/json, text/plain, */*",
      "Content-Type": "application/octet-stream",
      "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) DMMPlayerv2/2.4.0 Chrome/120.0.6099.227 Electron/28.2.0 Safari/537.36",
      Host: "mlic.dmm.com",
      Cookie: "licenseUID=XXX",
      "Content-Length": "2599",
      "Accept-Encoding": "gzip, compress, deflate, br",
      set: [Getter/Setter],
      get: [Getter/Setter],
      has: [Getter/Setter],
      delete: [Getter/Setter],
      clear: [Getter/Setter],
      normalize: [Getter/Setter],
      concat: [Getter/Setter],
      toJSON: [Getter/Setter],
      toString: [Getter/Setter],
      getContentType: [Getter/Setter],
      setContentType: [Getter/Setter],
      hasContentType: [Getter/Setter],
      getContentLength: [Getter/Setter],
      setContentLength: [Getter/Setter],
      hasContentLength: [Getter/Setter],
      getAccept: [Getter/Setter],
      setAccept: [Getter/Setter],
      hasAccept: [Getter/Setter],
      getAcceptEncoding: [Getter/Setter],
      setAcceptEncoding: [Getter/Setter],
      hasAcceptEncoding: [Getter/Setter],
      getUserAgent: [Getter/Setter],
      setUserAgent: [Getter/Setter],
      hasUserAgent: [Getter/Setter],
      getAuthorization: [Getter/Setter],
      setAuthorization: [Getter/Setter],
      hasAuthorization: [Getter/Setter],
      [Symbol(Symbol.iterator)]: [Function],
    },
    responseType: "arraybuffer",
    method: "post",
    url: "https://mlic.dmm.com/drm/widevine/license",
    data: Buffer(2599) [ 8, 1, 18, 159, 18, 18, 201, 1, 10, 198, 1, 10, 175, 1, 18, 16, 105, 151, 57, 244, 237, 4, 51, 190, 188, 44, 179, 23, 128, 53, 52, 70, 34, 154, 1, 123, 34, 118, 34, 58, 34, 50, 34, 44, 34, 102, 105, 100, 34, 58, 34, 55, 49, 103, 97, 115, 115, 48, 48, 48, 48, 49, 34, 44, 34, 115, 118, 105, 100, 34, 58, 34, 100, 105, 103, 105, 116, 97, 108, 34, 44, 34, 112, 108, 34, 58, 34, 101, 121, 74, 119, 97, 87, 81, 105, 79, 105, 73, 51, 77, 87, 100, 104, 99, 51, 77, 119, 77, 68, 65, 119, 77, 87, 82, 115, 78, 105, 73, 115, 73, 109, 82, 108, 98, 71, 108, 50, 90, 88, 74, 53, 88, 51, 82, 53, 99, 71, 85, 105, 79, 105, 74, 107, 98, 67, 74, 57, 34, 44, 34, 99, 115, 34, 58, 34, 48, 100, 56, 54, 57, 101, 50, 48, 53, 54, 102, 49, 53, 101, 97, 101, 102, 99, 97, 99, 97, 49, 50, 102, 57, 57, 97, 53, 48, 97, 57, 102, 34, 125, 16, 2, 26, 16, 32, 129, 68, 35, 180, 126, 152, 44, 142, 21, 76, 223, 78, 193, 135, 46, 24, 1, 32, 196, 184, 197, 182, 6, 48, 21, 56, 173, 156, 174, 245, 2, 66, 192, 16, 10, 20, 108, 105, 99, 101, 110, 115, 101, 46, 119, 105, 100, 101, 118, 105, 110, 101, 46, 99, 111, 109, 18, 16, 23, 5, 185, 23, 204, 18, 4, 134, 139, 6, 51, 58, 47, 119, 42, 140, 26, 128, 14, 230, 205, 166, 164, 43, 49, 135, 31, 250, 120, 106, 15, 86, 51, 188, 143, 177, 169, 41, 233, 235, 47, 253, 229, 183, 50, 112, 88, 56, 230, 68, 82, 81, 83, 41, 241, 1, 53, 22, 165, 82, 80, 3, 168, 115, 183, 119, 146, 5, 91, 80, 109, 34, 244, 177, 113, 112, 13, 121, 13, 87, 130, 52, 214, 108, 26, 175, 190, 253, 2, 205, 50, 130, 152, 146, 21, 233, 244, 7, 213, 246, 34, 70, 239, 9, 54, 33, 28, 255, 218, 3, 178, 41, 88, 101, 86, 35, 231, 23, 164, 196, 64, 191, 237, 124, 138, 99, 126, 115, 167, 142, 197, 10, 105, 161, 94, 7, 147, 206, 65, 243, 131, 51, 248, 19, 90, 44, 231, 106, 45, 121, 130, 236, 194, 190, 136, 226, 131, 212, 104, 64, 121, 232, 157, 202, 146, 200, 116, 153, 204, 168, 246, 149, 219, 106, 145, 155, 118, 60, 22, 194, 73, 7, 119, 77, 3, 157, 198, 113, 40, 234, 43, 27, 253, 123, 170, 197, 216, 18, 119, 211, 139, 140, 134, 151, 101, 191, 67, 62, 126, 88, 203, 207, 67, 220, 62, 47, 0, 215, 136, 11, 94, 69, 204, 19, 140, 95, 142, 240, 198, 248, 30, 110, 251, 60, 158, 195, 206, 192, 247, 91, 94, 238, 6, 147, 68, 13, 246, 77, 99, 206, 100, 124, 198, 190, 132, 50, 201, 174, 199, 73, 107, ... 2086 more ],
  },
  request: ClientRequest {
    _writableState: {
      objectMode: false,
      highWaterMark: 16384,
      finalCalled: true,
      needDrain: false,
      ending: true,
      ended: true,
      finished: true,
      destroyed: false,
      decodeStrings: true,
      defaultEncoding: "utf8",
      length: 0,
      writing: false,
      corked: 0,
      sync: false,
      bufferProcessing: false,
      onwrite: [Function: onwrite],
      writecb: null,
      writelen: 0,
      afterWriteTickInfo: null,
      buffered: [],
      bufferedIndex: 0,
      allBuffers: true,
      allNoop: true,
      pendingcb: 0,
      constructed: true,
      prefinished: true,
      errorEmitted: false,
      emitClose: true,
      autoDestroy: false,
      errored: null,
      closed: false,
      closeEmitted: false,
      [Symbol(kOnFinished)]: [],
      getBuffer: [Function: getBuffer],
      bufferedRequestCount: [Getter],
    },
    _events: {
      abort: [
        [Function]
      ],
      aborted: [
        [Function]
      ],
      connect: [
        [Function]
      ],
      error: [
        [Function]
      ],
      socket: [
        [Function]
      ],
      timeout: [
        [Function]
      ],
    },
    _eventsCount: 6,
    _maxListeners: undefined,
    [Symbol(kCapture)]: false,
    headersSent: false,
    sendDate: true,
    [Symbol(finished)]: false,
    [Symbol(kEndCalled)]: false,
    [Symbol(kAbortController)]: AbortController {
      signal: [AbortSignal ...],
      abort: [Function: abort],
    },
    _httpMessage: [Circular],
    [Symbol(headers)]: Headers {
      "accept": "application/json, text/plain, */*",
      "content-type": "application/octet-stream",
      "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) DMMPlayerv2/2.4.0 Chrome/120.0.6099.227 Electron/28.2.0 Safari/537.36",
      "host": "mlic.dmm.com",
      "cookie": "licenseUID=XXX",
      "content-length": "2599",
      "accept-encoding": "gzip, compress, deflate, br",
    },
    _redirectable: Writable {
      _writableState: [Object ...],
      _events: [Object ...],
      _eventsCount: 3,
      _maxListeners: undefined,
      [Symbol(kCapture)]: false,
      _options: [Object ...],
      _ended: true,
      _ending: true,
      _redirectCount: 0,
      _redirects: [],
      _requestBodyLength: 2599,
      _requestBodyBuffers: [],
      _onNativeResponse: [Function],
      _currentRequest: [Circular],
      _currentUrl: "https://mlic.dmm.com/drm/widevine/license",
      abort: [Function],
      destroy: [Function],
      write: [Function],
      end: [Function],
      setHeader: [Function],
      removeHeader: [Function],
      setTimeout: [Function],
      flushHeaders: [Function],
      getHeader: [Function],
      setNoDelay: [Function],
      setSocketKeepAlive: [Function],
      aborted: [Getter],
      connection: [Getter],
      socket: [Getter],
      _sanitizeOptions: [Function],
      _performRequest: [Function],
      _processResponse: [Function],
      pipe: [Function],
      cork: [Function],
      uncork: [Function],
      setDefaultEncoding: [Function: setDefaultEncoding],
      _write: [Function],
      _writev: null,
      closed: [Getter],
      destroyed: [Getter/Setter],
      writable: [Getter/Setter],
      writableFinished: [Getter],
      writableObjectMode: [Getter],
      writableBuffer: [Getter],
      writableEnded: [Getter],
      writableNeedDrain: [Getter],
      writableHighWaterMark: [Getter],
      writableCorked: [Getter],
      writableLength: [Getter],
      errored: [Getter],
      writableAborted: [Getter],
      _undestroy: [Function: undestroy],
      _destroy: [Function],
      [Symbol(nodejs.rejection)]: [Function],
      setMaxListeners: [Function: setMaxListeners2],
      getMaxListeners: [Function: getMaxListeners2],
      emit: [Function: emit],
      addListener: [Function: addListener],
      on: [Function: addListener],
      prependListener: [Function: prependListener],
      once: [Function: once2],
      prependOnceListener: [Function: prependOnceListener],
      removeListener: [Function: removeListener],
      off: [Function: removeListener],
      removeAllListeners: [Function: removeAllListeners],
      listeners: [Function: listeners],
      rawListeners: [Function: rawListeners],
      listenerCount: [Function: listenerCount2],
      eventNames: [Function: eventNames],
    },
    [Symbol(fakeSocket)]: Socket {
      _readableState: [Object ...],
      _events: [Object ...],
      _eventsCount: 0,
      _maxListeners: undefined,
      [Symbol(kCapture)]: false,
      _writableState: [Object ...],
      allowHalfOpen: true,
      [Symbol(::bunternal::)]: undefined,
      bytesRead: 0,
      bytesWritten: 0,
      connecting: false,
      timeout: 0,
      isServer: false,
      address: [Function: address],
      bufferSize: [Getter],
      connect: [Function: connect],
      _destroy: [Function: _destroy],
      _final: [Function: _final],
      localAddress: [Getter],
      localFamily: [Getter],
      localPort: [Getter],
      pending: [Getter],
      _read: [Function: _read],
      readyState: [Getter],
      ref: [Function: ref],
      remoteAddress: [Getter/Setter],
      remotePort: [Getter/Setter],
      remoteFamily: [Getter/Setter],
      resetAndDestroy: [Function: resetAndDestroy],
      setKeepAlive: [Function: setKeepAlive],
      setNoDelay: [Function: setNoDelay],
      setTimeout: [Function: setTimeout],
      unref: [Function: unref],
      _write: [Function: _write],
      write: [Function],
      cork: [Function],
      uncork: [Function],
      setDefaultEncoding: [Function: setDefaultEncoding],
      _writev: null,
      end: [Function],
      writable: [Getter/Setter],
      writableHighWaterMark: [Getter],
      writableObjectMode: [Getter],
      writableBuffer: [Getter],
      writableLength: [Getter],
      writableFinished: [Getter],
      writableCorked: [Getter],
      writableEnded: [Getter],
      writableNeedDrain: [Getter],
      destroyed: [Getter/Setter],
      on: [Function],
      destroy: [Function: destroy2],
      _undestroy: [Function: undestroy],
      push: [Function],
      unshift: [Function],
      isPaused: [Function],
      setEncoding: [Function],
      read: [Function],
      pipe: [Function],
      unpipe: [Function],
      addListener: [Function],
      removeListener: [Function],
      off: [Function],
      removeAllListeners: [Function],
      resume: [Function],
      pause: [Function],
      wrap: [Function],
      iterator: [Function],
      readable: [Getter/Setter],
      readableDidRead: [Getter],
      readableAborted: [Getter],
      readableHighWaterMark: [Getter],
      readableBuffer: [Getter],
      readableFlowing: [Getter/Setter],
      readableLength: [Getter],
      readableObjectMode: [Getter],
      readableEncoding: [Getter],
      errored: [Getter],
      closed: [Getter],
      readableEnded: [Getter],
      asIndexedPairs: [Function],
      drop: [Function],
      filter: [Function],
      flatMap: [Function],
      map: [Function],
      take: [Function],
      every: [Function],
      forEach: [Function],
      reduce: [Function],
      toArray: [Function],
      some: [Function],
      find: [Function],
      [Symbol(nodejs.rejection)]: [Function],
      [Symbol(Symbol.asyncIterator)]: [Function],
    },
    _closed: true,
    path: [Getter],
    port: [Getter],
    method: [Getter],
    host: [Getter],
    protocol: [Getter],
    agent: [Getter],
    _write: [Function: _write],
    _writev: [Function: _writev],
    _destroy: [Function: _destroy],
    _ensureTls: [Function: _ensureTls],
    _final: [Function: _final],
    aborted: [Getter/Setter],
    abort: [Function: abort],
    setSocketKeepAlive: [Function: setSocketKeepAlive],
    setNoDelay: [Function: setNoDelay],
    setTimeout: [Function: setTimeout],
    [Symbol(kClearTimeout)]: [Function],
    _implicitHeader: [Function],
    appendHeader: [Function],
    flushHeaders: [Function],
    getHeader: [Function],
    getHeaders: [Function],
    getHeaderNames: [Function],
    removeHeader: [Function],
    setHeader: [Function],
    hasHeader: [Function],
    addTrailers: [Function],
    headers: [Getter],
    chunkedEncoding: [Getter/Setter],
    shouldKeepAlive: [Getter/Setter],
    useChunkedEncodingByDefault: [Getter/Setter],
    socket: [Getter/Setter],
    connection: [Getter],
    finished: [Getter],
    pipe: [Function],
    write: [Function],
    cork: [Function],
    uncork: [Function],
    setDefaultEncoding: [Function: setDefaultEncoding],
    end: [Function],
    closed: [Getter],
    destroyed: [Getter/Setter],
    writable: [Getter/Setter],
    writableFinished: [Getter],
    writableObjectMode: [Getter],
    writableBuffer: [Getter],
    writableEnded: [Getter],
    writableNeedDrain: [Getter],
    writableHighWaterMark: [Getter],
    writableCorked: [Getter],
    writableLength: [Getter],
    errored: [Getter],
    writableAborted: [Getter],
    destroy: [Function],
    _undestroy: [Function: undestroy],
    [Symbol(nodejs.rejection)]: [Function],
  },
  response: {
    status: 400,
    statusText: "Bad Request",
    headers: {
      date: "Fri, 30 Aug 2024 05:44:38 GMT",
      "content-type": "application/problem+json; charset=utf-8",
      "transfer-encoding": "chunked",
      connection: "keep-alive",
      "cache-control": "private,max-age=0",
      server: "Microsoft-IIS/10.0",
      "x-powered-by": "ASP.NET",
      set: [Getter/Setter],
      get: [Getter/Setter],
      has: [Getter/Setter],
      delete: [Getter/Setter],
      clear: [Getter/Setter],
      normalize: [Getter/Setter],
      concat: [Getter/Setter],
      toJSON: [Getter/Setter],
      toString: [Getter/Setter],
      getContentType: [Getter/Setter],
      setContentType: [Getter/Setter],
      hasContentType: [Getter/Setter],
      getContentLength: [Getter/Setter],
      setContentLength: [Getter/Setter],
      hasContentLength: [Getter/Setter],
      getAccept: [Getter/Setter],
      setAccept: [Getter/Setter],
      hasAccept: [Getter/Setter],
      getAcceptEncoding: [Getter/Setter],
      setAcceptEncoding: [Getter/Setter],
      hasAcceptEncoding: [Getter/Setter],
      getUserAgent: [Getter/Setter],
      setUserAgent: [Getter/Setter],
      hasUserAgent: [Getter/Setter],
      getAuthorization: [Getter/Setter],
      setAuthorization: [Getter/Setter],
      hasAuthorization: [Getter/Setter],
      [Symbol(Symbol.iterator)]: [Function],
    },
    config: {
      transitional: [Object ...],
      adapter: [ "xhr", "http", "fetch" ],
      transformRequest: [
        [Function: transformRequest]
      ],
      transformResponse: [
        [Function: transformResponse]
      ],
      timeout: 0,
      xsrfCookieName: "XSRF-TOKEN",
      xsrfHeaderName: "X-XSRF-TOKEN",
      maxContentLength: -1,
      maxBodyLength: -1,
      env: [Object ...],
      validateStatus: [Function: validateStatus],
      headers: [AxiosHeaders ...],
      responseType: "arraybuffer",
      method: "post",
      url: "https://mlic.dmm.com/drm/widevine/license",
      data: Buffer(2599) [ 8, 1, 18, 159, 18, 18, 201, 1, 10, 198, 1, 10, 175, 1, 18, 16, 105, 151, 57, 244, 237, 4, 51, 190, 188, 44, 179, 23, 128, 53, 52, 70, 34, 154, 1, 123, 34, 118, 34, 58, 34, 50, 34, 44, 34, 102, 105, 100, 34, 58, 34, 55, 49, 103, 97, 115, 115, 48, 48, 48, 48, 49, 34, 44, 34, 115, 118, 105, 100, 34, 58, 34, 100, 105, 103, 105, 116, 97, 108, 34, 44, 34, 112, 108, 34, 58, 34, 101, 121, 74, 119, 97, 87, 81, 105, 79, 105, 73, 51, 77, 87, 100, 104, 99, 51, 77, 119, 77, 68, 65, 119, 77, 87, 82, 115, 78, 105, 73, 115, 73, 109, 82, 108, 98, 71, 108, 50, 90, 88, 74, 53, 88, 51, 82, 53, 99, 71, 85, 105, 79, 105, 74, 107, 98, 67, 74, 57, 34, 44, 34, 99, 115, 34, 58, 34, 48, 100, 56, 54, 57, 101, 50, 48, 53, 54, 102, 49, 53, 101, 97, 101, 102, 99, 97, 99, 97, 49, 50, 102, 57, 57, 97, 53, 48, 97, 57, 102, 34, 125, 16, 2, 26, 16, 32, 129, 68, 35, 180, 126, 152, 44, 142, 21, 76, 223, 78, 193, 135, 46, 24, 1, 32, 196, 184, 197, 182, 6, 48, 21, 56, 173, 156, 174, 245, 2, 66, 192, 16, 10, 20, 108, 105, 99, 101, 110, 115, 101, 46, 119, 105, 100, 101, 118, 105, 110, 101, 46, 99, 111, 109, 18, 16, 23, 5, 185, 23, 204, 18, 4, 134, 139, 6, 51, 58, 47, 119, 42, 140, 26, 128, 14, 230, 205, 166, 164, 43, 49, 135, 31, 250, 120, 106, 15, 86, 51, 188, 143, 177, 169, 41, 233, 235, 47, 253, 229, 183, 50, 112, 88, 56, 230, 68, 82, 81, 83, 41, 241, 1, 53, 22, 165, 82, 80, 3, 168, 115, 183, 119, 146, 5, 91, 80, 109, 34, 244, 177, 113, 112, 13, 121, 13, 87, 130, 52, 214, 108, 26, 175, 190, 253, 2, 205, 50, 130, 152, 146, 21, 233, 244, 7, 213, 246, 34, 70, 239, 9, 54, 33, 28, 255, 218, 3, 178, 41, 88, 101, 86, 35, 231, 23, 164, 196, 64, 191, 237, 124, 138, 99, 126, 115, 167, 142, 197, 10, 105, 161, 94, 7, 147, 206, 65, 243, 131, 51, 248, 19, 90, 44, 231, 106, 45, 121, 130, 236, 194, 190, 136, 226, 131, 212, 104, 64, 121, 232, 157, 202, 146, 200, 116, 153, 204, 168, 246, 149, 219, 106, 145, 155, 118, 60, 22, 194, 73, 7, 119, 77, 3, 157, 198, 113, 40, 234, 43, 27, 253, 123, 170, 197, 216, 18, 119, 211, 139, 140, 134, 151, 101, 191, 67, 62, 126, 88, 203, 207, 67, 220, 62, 47, 0, 215, 136, 11, 94, 69, 204, 19, 140, 95, 142, 240, 198, 248, 30, 110, 251, 60, 158, 195, 206, 192, 247, 91, 94, 238, 6, 147, 68, 13, 246, 77, 99, 206, 100, 124, 198, 190, 132, 50, 201, 174, 199, 73, 107, ... 2086 more ],
    },
    request: ClientRequest {
      _writableState: [Object ...],
      _events: [Object ...],
      _eventsCount: 6,
      _maxListeners: undefined,
      [Symbol(kCapture)]: false,
      headersSent: false,
      sendDate: true,
      [Symbol(finished)]: false,
      [Symbol(kEndCalled)]: false,
      [Symbol(kAbortController)]: [AbortController ...],
      _httpMessage: [Circular],
      [Symbol(headers)]: Headers [Object ...],
      _redirectable: [Object ...],
      [Symbol(fakeSocket)]: [Object ...],
      _closed: true,
      path: [Getter],
      port: [Getter],
      method: [Getter],
      host: [Getter],
      protocol: [Getter],
      agent: [Getter],
      _write: [Function: _write],
      _writev: [Function: _writev],
      _destroy: [Function: _destroy],
      _ensureTls: [Function: _ensureTls],
      _final: [Function: _final],
      aborted: [Getter/Setter],
      abort: [Function: abort],
      setSocketKeepAlive: [Function: setSocketKeepAlive],
      setNoDelay: [Function: setNoDelay],
      setTimeout: [Function: setTimeout],
      [Symbol(kClearTimeout)]: [Function],
      _implicitHeader: [Function],
      appendHeader: [Function],
      flushHeaders: [Function],
      getHeader: [Function],
      getHeaders: [Function],
      getHeaderNames: [Function],
      removeHeader: [Function],
      setHeader: [Function],
      hasHeader: [Function],
      addTrailers: [Function],
      headers: [Getter],
      chunkedEncoding: [Getter/Setter],
      shouldKeepAlive: [Getter/Setter],
      useChunkedEncodingByDefault: [Getter/Setter],
      socket: [Getter/Setter],
      connection: [Getter],
      finished: [Getter],
      pipe: [Function],
      write: [Function],
      cork: [Function],
      uncork: [Function],
      setDefaultEncoding: [Function: setDefaultEncoding],
      end: [Function],
      closed: [Getter],
      destroyed: [Getter/Setter],
      writable: [Getter/Setter],
      writableFinished: [Getter],
      writableObjectMode: [Getter],
      writableBuffer: [Getter],
      writableEnded: [Getter],
      writableNeedDrain: [Getter],
      writableHighWaterMark: [Getter],
      writableCorked: [Getter],
      writableLength: [Getter],
      errored: [Getter],
      writableAborted: [Getter],
      destroy: [Function],
      _undestroy: [Function: undestroy],
      [Symbol(nodejs.rejection)]: [Function],
    },
    data: Buffer(163) [ 123, 34, 116, 121, 112, 101, 34, 58, 34, 104, 116, 116, 112, 115, 58, 47, 47, 116, 111, 111, 108, 115, 46, 105, 101, 116, 102, 46, 111, 114, 103, 47, 104, 116, 109, 108, 47, 114, 102, 99, 55, 50, 51, 49, 35, 115, 101, 99, 116, 105, 111, 110, 45, 54, 46, 53, 46, 49, 34, 44, 34, 116, 105, 116, 108, 101, 34, 58, 34, 66, 97, 100, 32, 82, 101, 113, 117, 101, 115, 116, 34, 44, 34, 115, 116, 97, 116, 117, 115, 34, 58, 52, 48, 48, 44, 34, 116, 114, 97, 99, 101, 73, 100, 34, 58, 34, 48, 48, 45, 56, 97, 52, 49, 98, 57, 97, 100, 55, 51, 102, 56, 54, 51, 54, 54, 50, 54, 99, 49, 100, 102, 57, 52, 99, 55, 49, 49, 100, 100, 100, 49, 45, 57, 52, 100, 51, 50, 101, 101, 97, 49, 102, 48, 54, 97, 53, 57, 51, 45, 48, 48, 34, 125 ],
  },
  toJSON: [Function: toJSON],
  isAxiosError: true,
  toString: [Function: toString],
}
lvzhenbo commented 2 months ago

@wfb2222wfb 我刚刚试了一部,是可以的,那我能想到的就是网络问题了,不用开梯子,可以直连,然后你其实可以自己试试我上面说的手动的方式

wfb2222wfb commented 2 months ago

@lvzhenbo 手动之前试过了,也不行,还有两个问题,再请教一下 1、你dcv用的是r18资源吗? 2、会不会跟dump那两个文件选的模拟器机型有关,你是按照教程选的吗?

lvzhenbo commented 2 months ago

@wfb2222wfb 是fanza的,机型其实无关,其实那个帖子后面评论也给了很多这两个文件,然后也说明了高版本系统怎么获取,你都看看,我现在用的cdm就是按照教程搞出来的

wfb2222wfb commented 2 months ago

@lvzhenbo 好的,我再研究一下,多谢

000795435 commented 2 months ago

@wfb2222wfb 安卓版本低才是对的,高了才拿不到,然后dmm播放报错是不是你网络问题,不是非要播放dmm视频,只要能拿到cdm的两个文件就行 @000795435 我的方式只是解密dcv文件,mpd流是是其他方式

哦哦明白了, 你的意思是下载DMM Player V2 这个软件然后播放视频在后台抓包,我之前理解的是DMM网页端的播放器。 谢谢, 我再琢磨一下。

atiAkizuki commented 2 months ago

@lvzhenbo 拿密钥的时候,前面 licenceUid 和 pssh都拿到了,有没有可能是模拟器模拟手机版本低导致dump的两个文件dmm那边处理不了,我是根据他选择的pixel6操作的,我后来尝试在模拟器里面播放dmm的付费视频,进入播放页面后会报连接错误,不知道有没有关系。

可以使用https://github.com/sim0n00ps/L3-Dumping 这个一键脚本,具体用什么虚拟机系统看它的issue页面,有人回复 我拿他成功解密了fanza的视频

atiAkizuki commented 2 months ago

现在的验证地址没有变,具体可以用reqable抓PC端DMM Player V2的登陆和验证逻辑,另外只是widevine DRM加密的视频,那CDM文件就通用,所以上面的方式获取的CDM适用于fanza