# Netflix MSL クライアント仕様: StreamFab (CEF)
共通仕様: [00_common.md](00_common.md)
---
## 1. フロー
```mermaid
%%{init: {'theme': 'dark'}}%%
sequenceDiagram
participant SF as StreamFab (CEF)
participant MSL as MSL Gateway
(www.netflix.com)
participant HTTP as Netflix HTTP API
participant CDM as Widevine CDM
(4.10.2934.0)
rect rgba(100, 50, 50, 0.3)
Note over SF,MSL: 認証・MSL セッション確立
SF->>MSL: MSL handshake
MSL-->>SF: encryption_key_temp (AES-128)
SF->>MSL: aleProvision (pbo_tokens/router)
MSL-->>SF: MSL セッション確立
end
rect rgba(50, 100, 50, 0.3)
Note over SF,CDM: マニフェスト一括取得 (コーデック探索)
SF->>HTTP: /metadata?movieid=81756595
loop コーデック x オーディオ (最大18回)
SF->>HTTP: /licensedmanifest/1 (MSL暗号化)
HTTP-->>SF: licensedmanifest (AES-CBC + gzip)
end
SF->>HTTP: /playapi/cadmium/manifest/1 (非MSL, AV1)
Note over SF: ユーザーがコーデック・トラック選択
end
rect rgba(100, 100, 50, 0.3)
Note over SF,CDM: ライセンス取得 → 復号 → ダウンロード
SF->>CDM: SetServerCertificate
SF->>CDM: CreateSessionAndGenerateRequest
CDM-->>SF: OnSessionMessage (license-request)
SF->>MSL: pbo_licenses/router (license challenge)
MSL-->>SF: license-response (content keys)
SF->>CDM: UpdateSession (license install)
Note over SF: コンテンツ鍵で DASH セグメントを復号
Note over SF: MP4 ファイルとして保存
end
```
---
## 2. 認証
| 項目 | 値 |
|------|---|
| ESN プレフィックス | `NFCDCH-02-` |
| ESN 例 | `NFCDCH-02-MUUR2Y0QQ9K5CJNXC9RUU370H3N702` |
| ESN 取得方法 | 事前割り当て済み |
| 認証スキーム | `NETFLIXID` (Cookie + UIT) |
| MSL 圧縮 | gzip |
### Cookie
```
NetflixId=ct%3DBgjHlOvcAx...
SecureNetflixId=v%3D3%26mac%3DAQEAEQAB...
nfvdid=BQFmAAEBEAQQ...
gsid=45d701df-...
```
### MSL セッション鍵
ハンドシェイク成功時に `encryption_key_temp` を取得 (base64url, 16バイト AES-128 鍵)。
以降の全 MSL 通信はこの鍵で AES-CBC 暗号化される。
---
## 3. マニフェスト取得
### 3.1 licensedmanifest (メイン)
**エンドポイント:** `POST /msl/playapi/cadmium/licensedmanifest/1`
**クエリパラメータ:**
```
reqAttempt=1
reqPriority=20
reqName=licensedManifest
clienttype=akira
uiversion=v930f5871
browsername=chrome
browserversion=144.0.0.0
osname=windows
osversion=10.0
```
### 3.2 コーデック探索戦略
StreamFab は 1 タイトルに対してコーデック x オーディオの全組み合わせで licensedmanifest を取得する:
| videoCodec | 値 | audioCodec | 値 | manifest level 例 |
|------------|---|------------|---|-------------------|
| H.264 HP | 0 | EAC3 | 1 | `H264_HP_EAC` |
| H.264 HP | 0 | AAC | 2 | `H264_HP_AAC` |
| H.264 HP | 0 | Atmos | 0 | `H264_HP_ATMOS` |
| HEVC HDR10 | 2 | EAC3 | 1 | `H265_HDR10_EAC` |
| HEVC HDR10 | 2 | AAC | 2 | `H265_HDR10_AAC` |
| HEVC HDR10 | 2 | Atmos | 0 | `H265_HDR10_ATMOS` |
| VP9 | 4 | (同上3種) | | VP9 → H.264 フォールバック |
| AV1 | 5 | (同上3種) | | `AV1_EAC`, `AV1_AAC`, `AV1_ATMOS` |
同一コーデックではオーディオが異なるだけでビデオストリームは同一。
### 3.3 コーデック別実測データ (videoId: 81756595)
#### H.264
| 解像度 | ビットレート | VMAF | プロファイル | KID |
|--------|------------|------|------------|-----|
| 720x480 | 498 kbps | 72 | `h264mpl30-dash-playready-prk-qc` | `...b9f1` (SD) |
| 1920x1080 | 4941 kbps | 97 | `h264mpl40-dash-playready-prk-qc` | `...b9f2` (HD) |
ストリーム数 2。中間解像度なし。DRM: PlayReady。
#### HEVC HDR10
| 解像度 | ビットレート | VMAF | プロファイル | KID |
|--------|------------|------|------------|-----|
| 608x342 | 92 kbps | 43 | `hevc-main10-L30-dash-cenc-prk-do` | `...b9e7` (SD) |
| 768x432 | 132 kbps | 58 | `hevc-main10-L30-dash-cenc-prk-do` | `...b9e7` (SD) |
| 960x540 | 188 kbps | 68 | `hevc-main10-L30-dash-cenc-prk-do` | `...b9e7` (SD) |
| 1280x720 | 286 kbps | 79 | `hevc-main10-L31-dash-cenc-prk-do` | `...b9e8` (HD) |
| 1280x720 | 433 kbps | 86 | `hevc-main10-L31-dash-cenc-prk-do` | `...b9e8` (HD) |
| 1920x1080 | 788 kbps | 91 | `hevc-main10-L40-dash-cenc-prk-do` | `...b9e8` (HD) |
| 1920x1080 | 1456 kbps | 96 | `hevc-main10-L40-dash-cenc-prk-do` | `...b9e8` (HD) |
ストリーム数 7。Main 10bit HDR10。DRM: CENC。
#### AV1
| 解像度 | ビットレート | VMAF | プロファイル | KID |
|--------|------------|------|------------|-----|
| 480x270 | 54 kbps | 38 | `av1-main-L30-dash-cbcs-prk` | `...b9db` (SD) |
| 608x342 | 95 kbps | 57 | `av1-main-L30-dash-cbcs-prk` | `...b9db` (SD) |
| 608x342 | 118 kbps | 61 | `av1-main-L30-dash-cbcs-prk` | `...b9db` (SD) |
| 608x342 | 167 kbps | 66 | `av1-main-L30-dash-cbcs-prk` | `...b9db` (SD) |
| 768x432 | 237 kbps | 77 | `av1-main-L30-dash-cbcs-prk` | `...b9db` (SD) |
| 960x540 | 331 kbps | 84 | `av1-main-L30-dash-cbcs-prk` | `...b9db` (SD) |
| 1280x720 | 521 kbps | 91 | `av1-main-L31-dash-cbcs-prk` | `...b9de` (HD) |
| 1920x1080 | 847 kbps | 95 | `av1-main-L40-dash-cbcs-prk` | `...b9de` (HD) |
| 1920x1080 | 1412 kbps | 97 | `av1-main-L40-dash-cbcs-prk` | `...b9de` (HD) |
ストリーム数 9。DRM: CBCS。
#### VP9
Netflix は VP9 を提供しない。要求すると H.264 にフォールバック。
### 3.4 manifest API (補助)
**エンドポイント:** `POST /playapi/cadmium/manifest/1` (非 MSL)
AV1 のみ返される。DRM Key ID なし。リクエスト本文:
```json
{
"version": 2,
"url": "manifest",
"id": 177535606868297730,
"languages": ["en-JP"],
"params": {
"type": "standard",
"manifestVersion": "v2",
"viewableId": 82187182,
"profiles": [
"heaac-2-dash", "xheaac-dash",
"playready-h264hpl30-dash", "playready-h264hpl31-dash", "playready-h264hpl40-dash",
"av1-main-L30-dash-cbcs-prk", "av1-main-L31-dash-cbcs-prk",
"av1-main-L40-dash-cbcs-prk", "av1-main-L41-dash-cbcs-prk"
],
"flavor": "SUPPLEMENTAL",
"drmType": "widevine",
"drmVersion": 0,
"usePsshBox": true,
"useHttpsStreams": true,
"clientVersion": "6.0056.273.911",
"platform": "144.0.0.0",
"osVersion": "10.0",
"osName": "windows",
"supportsWatermark": true,
"videoOutputInfo": [{
"type": "DigitalVideoOutputDescriptor",
"outputType": "unknown",
"supportedHdcpVersions": [],
"isHdcpEngaged": false
}],
"maxSupportedLanguages": 2
}
}
```
---
## 4. ライセンスチャレンジ
**エンドポイント:** MSL 経由 `POST /nq/msl_v1/cadmium/pbo_licenses/^1.0.0/router`
### CDM フロー (CEF 内蔵 Widevine)
| ステップ | CDM API | 説明 |
|---------|---------|------|
| 1 | `SetServerCertificate` | Netflix サーバー証明書をセット |
| 2 | `CreateSessionAndGenerateRequest` | PSSH から license-request 生成 |
| 3 | `OnSessionMessage` | license-request (protobuf) を受け取る |
| 4 | (MSL 送信) | license-request を pbo_licenses に POST |
| 5 | (MSL 受信) | license-response を取得 |
| 6 | `UpdateSession` | license-response をインストール |
### Widevine CDM バージョン (同梱)
| バージョン | パス |
|-----------|------|
| 4.10.2934.0 | `WidevineCdm/4.10.2934.0/_platform_specific/mac_x64/libwidevinecdm.dylib` |
| 4.10.2891.0 | 同上 |
| 4.10.2830.0 | 同上 |
| 4.10.2710.0 | 同上 |
CDM は `libcefbase.dylib` 経由で制御。
### CDM セッション (実測, QCef.log)
1タイトルで複数セッションが生成される:
```
CreateSessionAndGenerateRequest
OnSessionMessage session_id = 040F927F156357E593DB9AD358C08012
CreateSessionAndGenerateRequest
OnSessionMessage session_id = E948DF7EB0DAC44114489546DBB9EF90
CreateSessionAndGenerateRequest
OnSessionMessage session_id = 49818D39487813DB1A6BDC3E21C62DEE
```
---
## 5. 偽装パラメータ
| パラメータ | 実値 | 偽装値 |
|-----------|------|-------|
| User-Agent | macOS 15.5 / CEF | `Windows NT 10.0; Win64; x64` Chrome/144.0.0.0 |
| osname | macOS | `windows` |
| osversion | 15.5 | `10.0` |
| browsername | CEF | `chrome` |
| browserversion | (CEF 内蔵) | `144.0.0.0` |
| clienttype | — | `akira` |
`clientVersion: "6.0056.273.911"` と `uiVersion: "shakti-v930f5871"` は Netflix Web アプリのバージョン。定期的に更新が必要。
---
## 6. ダウンロード実行 (実測)
StreamFab がダウンロード開始時にログに記録するパラメータ:
```
website: "Netflix"
strID: "81756595"
Resolution: "4941:1080:1920"
eVideoCodec: 0 (H.264)
eAudioCodec: 3
```
- ストリーミング再生ではなくダウンロード保存が目的
- テレメトリ (`/events`) は送信しない
- ダウンロード完了後 MP4 ファイルとして保存