ニコニコ動画 技術的詳細分析(更新版)
- # ニコニコ動画 技術的詳細分析
- ---
- ## アーキテクチャ概要
- ニコニコ動画はモダンなマイクロサービスアーキテクチャを採用しており、以下のような技術スタックで構成されています:
- - **フロントエンド**: React/Remix ベースの SPA (`nvpc_next` = NicoNico Video Player Client Next)
- - 視聴ページ (`/watch/{id}`) は Remix ベースのコード分割バンドル
- - トップ系ページ (`/`, `/video_top`) は従来型のバンドル (`vendor.js` + `pages_index_*.js`)
- - **共通ヘッダー**: `common-header.nimg.jp/3.9.0/pc/CommonHeader.min.js` (バージョン 3.9.0)
- - **動画配信**: HLS (HTTP Live Streaming) + AWS CloudFront (CDN)
- - **API**: JSON ベースの RESTful API (フロントエンド ID `6` で識別)
- - **コメント**: 専用のコメントサーバー (`public.nvcomment.nicovideo.jp`)
- - **認証**: セッションベースの認証 + JWT トークン (`x-access-right-key`, `threadKey`)
- - **ヘッダー入札**: Prebid.js による多数の SSP/エクスチェンジ統合
- ---
- ## フロントエンド技術スタック
- ### JavaScriptバンドル構造
- ニコニコ動画はページの性質に応じて 2 種類のバンドルを使い分けています:
- ```
- https://resource.video.nimg.jp/web/scripts/
- ├── nvpc_next/assets/ # 視聴ページ用 Remix バンドル (Vite hash付き)
- │ ├── manifest-*.js # マニフェスト
- │ ├── entry.client-*.js # クライアントエントリーポイント
- │ ├── root-*.js # ルートコンポーネント
- │ ├── index-*.js # 共通コンポーネント (複数)
- │ ├── api-client-*.js # API クライアント
- │ ├── use-media-query-*.js # メディアクエリフック
- │ ├── useDeferredLoadable-*.js # 遅延ロードフック
- │ ├── useLayoutType-*.js # レイアウト判定フック
- │ ├── usePreviewVideoStatus-*.js # プレビュー再生フック
- │ ├── ab-testing-*.js # A/B テスト
- │ ├── enum-*.js # 列挙型定数
- │ ├── _web-*.js # 視聴ページ共通ルート
- │ ├── _web.watch._id._-*.js # 動画視聴ページ
- │ ├── _web.random_play._itemId._-*.js # ランダム再生ページ
- │ └── _web.easy_nicos._id._-*.js # 簡単ニコ動ページ
- └── bundle/
- ├── vendor.js # サードパーティライブラリ
- ├── pages_index_TopPage.js # サービス統合トップ (`/`)
- └── pages_index_VideoTop.js # 動画トップ (`/video_top`)
- ```
- ### 主要なフロントエンド機能 (視聴ページ)
- | コンポーネント | 説明 |
- |--------------|------|
- | `PlayerVolumeBar` | プレイヤーボリュームコントロール |
- | `PlayerSeekBar` | プレイヤーシークバー |
- | `VideoCard` / `NicoadVideoCard` | 動画カード表示 (通常版 / ニコニ広告版) |
- | `VideoMediaObject` | 動画メディアオブジェクト (スケルトン付き) |
- | `FollowButton` | ユーザーフォローボタン |
- | `Toast` | 通知表示 |
- | `WakutkoolNotice` | わくくおる通知 (ポータル横断告知) |
- | `TagRelatedBanner` | タグ関連バナー |
- | `SearchRelatedTag` | 関連タグ検索 |
- | `WatchLayoutLazySidebar` / `WatchLayoutLazyBottom` | 視聴ページの遅延ロード領域 |
- | `FloatingBottomRightPresenter` | 右下フローティング UI |
- | `GiftAuditionPresenter` | 動画ギフト + オーディションプレゼンター |
- | `AfkStopMessagePresenter` | 放置検知後の停止メッセージ |
- | `MutedVideoThumbnail` | ミュート扱い動画のサムネイル |
- | `VideoShareTimeInput` | 時刻指定シェアの入力 |
- | `PremiumRegisterRequired` | プレミアム登録誘導モーダル |
- | `CollapsiblePanel` / `Skeleton` / `Tabs` | 汎用 UI プリミティブ |
- | `nicoad` | ニコニ広告機能 |
- ### メタデータ・OGP
- 視聴ページ (`/watch/{id}`) は動画用 OGP に最適化されており、Open Graph Video / Twitter App Card / App Links が含まれます:
- ```html
- <meta property="og:title" content="新・豪血寺一族 -煩悩解放 - レッツゴー!陰陽師">
- <meta property="og:type" content="video.other">
- <meta property="og:site_name" content="ニコニコ動画">
- <meta property="og:locale" content="ja_JP">
- <meta property="og:video" content="https://embed.nicovideo.jp/watch/{id}?autoplay=1">
- <meta property="og:video:type" content="video/mp4">
- <meta property="og:video:width" content="640">
- <meta property="og:video:height" content="360">
- <meta property="video:duration" content="320">
- <meta property="video:release_date" content="2007-03-06T00:33+0900">
- <meta property="fb:app_id" content="378853695459932">
- <meta name="twitter:card" content="summary_large_image">
- <meta name="twitter:site" content="@nico_nico_info">
- <meta name="twitter:app:id:iphone" content="307764057">
- <meta name="twitter:app:url:iphone" content="nico://play/?vid={id}">
- <meta name="twitter:app:id:googleplay" content="jp.nicovideo.android">
- <meta name="twitter:app:url:googleplay" content="nico://watch/{id}">
- <meta property="al:ios:url" content="nico://play/?vid={id}&utm_source=facebook&...">
- <meta property="al:android:url" content="https://www.nicovideo.jp/watch/{id}?...">
- <meta property="al:web:url" content="https://www.nicovideo.jp/watch/{id}">
- ```
- トップページ (`/`) は `og:type="website"`、動画トップ (`/video_top`) は `og:type="article"` という具合にページ種別ごとに切り替わります。
- ---
- ## 主要APIエンドポイント
- ### 1. 動画アクセス権限 API (HLS)
- **エンドポイント**: `POST https://nvapi.nicovideo.jp/v1/watch/{videoId}/access-rights/hls?actionTrackId={actionTrackId}`
- 動画のストリーミング URL を取得するためのアクセス権限を要求します。`actionTrackId` クエリパラメータでセッションを識別し、再リクエスト時には `&__retry=N` が付与されます。
- #### リクエストヘッダー
- ```http
- x-access-right-key: {JWTトークン}
- x-frontend-id: 6
- x-frontend-version: 0
- x-request-with: nicovideo
- x-niconico-language: ja-jp
- Content-Type: application/json
- Accept: application/json;charset=utf-8
- ```
- #### リクエストボディ (初回, `?actionTrackId=...` のみ)
- `outputs` のみ。動画の元素材が許可する全 video×audio 組み合わせを列挙します:
- sm9 (古い動画) の場合:
- ```json
- {
- "outputs": [
- ["video-h264-360p", "audio-aac-128kbps"],
- ["video-h264-360p", "audio-aac-64kbps"],
- ["video-h264-360p-lowest", "audio-aac-128kbps"],
- ["video-h264-360p-lowest", "audio-aac-64kbps"]
- ]
- }
- ```
- sm46309015 (新しい動画) の場合:
- ```json
- {
- "outputs": [
- ["video-h264-720p", "audio-aac-192kbps"],
- ["video-h264-720p", "audio-aac-64kbps"],
- ["video-h264-480p", "audio-aac-192kbps"],
- ["video-h264-480p", "audio-aac-64kbps"],
- ["video-h264-360p", "audio-aac-192kbps"],
- ["video-h264-360p", "audio-aac-64kbps"],
- ["video-h264-144p", "audio-aac-192kbps"],
- ["video-h264-144p", "audio-aac-64kbps"]
- ]
- }
- ```
- #### リクエストボディ (heartbeat 付きの後続呼び出し, `?actionTrackId=...&__retry=N`)
- 再生開始時や状態変化時に、`outputs` に加えて `heartbeat` フィールドで視聴セッションの状態を送信します:
- ```json
- {
- "outputs": [["video-h264-360p", "audio-aac-128kbps"]],
- "heartbeat": {
- "method": "guest",
- "params": {
- "eventType": "start",
- "eventOccurredAt": "2026-05-19T02:27:29+09:00",
- "watchMilliseconds": 0,
- "endCount": 0,
- "additionalParameters": {
- "___pc_v": 1,
- "os": "Windows",
- "os_version": "15.0.0",
- "nicosid": "{nicosid}",
- "is_ad_block": false,
- "is_ad_block_by_as": false,
- "has_playlist": false,
- "playback_rate": "1",
- "loop_count": 0,
- "suspend_count": 0,
- "load_failed": false,
- "preview_play": false,
- "hot_scene_wave": true,
- "seekbar_seek_count": 0,
- "performance": {
- "watch_access_start": 1779125249692,
- "video_loading_start": 1779125249698,
- "end_context": {
- "ad_playing": false,
- "video_playing": false,
- "is_suspending": false
- }
- },
- "__pc_is_ai_comment_visible": true
- }
- }
- }
- }
- ```
- #### レスポンス
- ```json
- {
- "meta": { "status": 201 },
- "data": {
- "contentUrl": "https://delivery.domand.nicovideo.jp/hlsbid/{bid}/playlists/variants/{variantId}.m3u8?session=...&Policy=...&Signature=...&Key-Pair-Id=...",
- "createTime": "2026-05-19T02:27:29+09:00",
- "expireTime": "2026-05-20T02:27:29+09:00"
- }
- }
- ```
- 初回 POST は `201 Created` を返し、heartbeat 付きの後続 POST は `200 OK` を返します。レスポンスに加えて `Set-Cookie: domand_bid=...` (Max-Age=86400, HttpOnly, Secure) が払い出されます。
- ### 2. コメントサーバー API
- **エンドポイント**: `POST https://public.nvcomment.nicovideo.jp/v1/threads?pc=1`
- 動画に紐づくコメントスレッドを取得します。`x-client-os-type: others` ヘッダーと `Content-Type: text/plain;charset=UTF-8` で送信されます。
- #### リクエストボディ
- ```json
- {
- "params": {
- "targets": [
- { "id": "1173108780", "fork": "owner" },
- { "id": "1173108780", "fork": "main" },
- { "id": "1173108780", "fork": "easy" }
- ],
- "language": "ja-jp"
- },
- "threadKey": "{JWTトークン}",
- "additionals": {}
- }
- ```
- #### レスポンス構造
- ```json
- {
- "meta": { "status": 200 },
- "data": {
- "globalComments": [{ "id": "1173108780", "count": 5659900 }],
- "threads": [
- {
- "id": "1173108780",
- "fork": "main",
- "commentCount": 5581324,
- "comments": [
- {
- "id": "882123066398695732",
- "no": 4118020,
- "vposMs": 361140,
- "body": "コメント本文",
- "commands": ["184"],
- "userId": "Yg_6QWiiS_T2mq3WJuzUcp41MvQ",
- "isPremium": true,
- "score": -2200,
- "postedAt": "2013-02-17T21:16:30+09:00",
- "nicoruCount": 137,
- "nicoruId": null,
- "source": "leaf",
- "isMyPost": false
- }
- ]
- }
- ]
- }
- }
- ```
- 旧仕様から増えたフィールド: `nicoruId` (押下したニコるの識別子)、`isMyPost` (自分の投稿か)、`source` は `"leaf"` 以外に `"nicoru"` (ニコる経由で表示されたコメント) を取り得ます。
- ### 3. レコメンデーション API
- **エンドポイント**: `GET https://nvapi.nicovideo.jp/v1/recommend`
- ページ種別ごとに `recipeId` を切り替えて呼び出します:
- | ページ | recipeId |
- |------|----------|
- | 視聴ページ | `video_watch_recommendation` (`recipeVersion=2`) |
- | 動画トップ (`/video_top`) | `video_top_recommend` (`with_reason=true`) |
- ```
- ?recipeId=video_watch_recommendation
- &recipeVersion=2
- &videoId=sm9
- &site=nicovideo
- &limit=25
- &sensitiveContents=mask
- ```
- レスポンス `data.items[].content` には、`owner.visibility` (`visible`/`hidden`)、`requireSensitiveMasking`、`isMuted`、難読化フィールド (`9d091f87`, `acf68865` のような短いキー) が含まれます。
- ### 4. ニコニ広告 API
- 旧来の v1 系と、視聴ページで新規導入された v2 系が併存しています:
- | エンドポイント | 用途 |
- |--------------|------|
- | `GET https://api.nicoad.nicovideo.jp/v1/contents/video/decoration?ids={csv}` | 動画一覧 (`/video_top` 等) のニコニ広告装飾を一括取得 |
- | `GET https://api.nicoad.nicovideo.jp/v2/contents/video/{id}/pickup_supporters?tags=...` | 視聴ページのピックアップサポーター取得 (v2) |
- | `GET https://api.nicoad.nicovideo.jp/v1/nage_video/{id}/gift/effects` | 動画ギフト (投げ銭) の利用可能エフェクト一覧 |
- | `GET https://api.nicoad.nicovideo.jp/v1/contents/nage_video/{id}/totalGiftPoint` | 動画ギフトの累計ポイント |
- ### 5. その他のAPI
- | API | エンドポイント | 用途 |
- |-----|---------------|------|
- | 広場ウィジェット | `GET eapi.beta.hiroba.nicovideo.jp/v1/square-widget?tags=...` | タグから関連コミュニティ広場を提案 |
- | ユーザーフォロー | `user-follow-api.nicovideo.jp/v1/user/followees/` | フォロー情報 |
- | 動画マイキー実績 | `GET mjk.nicovideo.jp/api/v1/content_types/video/contents/{id}/achieved_histories?limit=1&order=honor_class` | 動画の実績バッジ履歴 |
- | ユーザーマイキー実績 | `GET mjk.nicovideo.jp/api/v1/users/{userId}/achieved_histories?limit=1` | ユーザーの実績バッジ履歴 |
- | ストーリーボード | `nvapi.nicovideo.jp/v1/watch/{id}/access-rights/storyboard` | サムネイルシート |
- | マーキー | `GET nvapi.nicovideo.jp/v1/marquee` | プレイヤー上部のマーキー告知 |
- | AI キャラクターコメント | `GET nvapi.nicovideo.jp/v1/ai-comment/characters` | AI コメントの登場キャラクター一覧 (2026 年導入機能) |
- | クリエイターサポート | `GET nvapi.nicovideo.jp/v1/users/{userId}/creator-support` | 投稿者へのサポート (投げ銭/応援) 情報 |
- | オーディション応募 | `GET audition.nicovideo.jp/capi/v1/entry_items?item_type=video&item_id={id}&voting_phase=active&limit=1` | 動画が応募中のオーディション情報 |
- | ニコニ・コモンズ ライセンス | `GET public-api.commons.nicovideo.jp/v1/works/{id}/license` | コモンズ License (404 になることあり) |
- | わくくおる | `GET wktk.nicovideo.jp/v2/wakutkool/frames.json?names=watch-portal-link&tags=...&responseType=pc` | 横断告知 (v2 API) |
- | プリロール広告 | `GET ads.nicovideo.jp/api/video/getAd.json.php?...` | 動画再生前の広告枠 (linearType=preroll) |
- | ステラ (非会員視聴) | `POST stella.nicovideo.jp/v1/watch/nonmember.json` | 動画トップ等での非ログイン視聴セッション初期化 |
- ---
- ## 動画配信システム
- ### Domand (動画配信プラットフォーム)
- ニコニコ動画は **Domand** と呼ばれる社内動画配信プラットフォームを使用しています:
- - **配信ドメイン**: `delivery.domand.nicovideo.jp` (プレイリスト, 暗号鍵)
- - **アセットドメイン**: `asset.domand.nicovideo.jp` (CMAF セグメント, ストーリーボード)
- - **CDN**: AWS CloudFront (`Key-Pair-Id=K11RB80NFXU134`)
- - **ブラウザID クッキー**: `domand_bid` (アクセス権限 API 初回 POST 時に発行)
- ### 配信品質 (動画別に提供される)
- `x-access-right-key` JWT の `v` / `a` フィールドにライセンスされた品質が列挙され、初回 POST の `outputs` で video×audio の組み合わせを全部列挙して送ります。**品質ラベルと実解像度・コーデックは動画の元素材で異なる** ため、ラベルだけでは解像度を一意に決められません。実観測例:
- **古い動画 (sm9, 2007 年投稿) の場合**:
- | ラベル | 実解像度 | フレームレート | コーデック |
- |-------|---------|----------------|------------|
- | `video-h264-360p` | 320x240 | 29.970 | `avc1.4d401e` (H.264 Main L3.0) |
- | `video-h264-360p-lowest` | 480x360 | 29.970 | `avc1.42c01e` (H.264 Constrained Baseline L3.0) |
- | `audio-aac-128kbps` | - | - | `mp4a.40.2` (AAC-LC) |
- | `audio-aac-64kbps` | - | - | `mp4a.40.2` (AAC-LC) |
- (古い動画では品質ラベル名と実解像度が一致しないことに注意。`360p-lowest` の方が解像度が高い変則ケースが存在する。)
- **新しい動画 (sm46309015, 2026 年投稿) の場合**:
- | ラベル | 実解像度 | フレームレート | コーデック |
- |-------|---------|----------------|------------|
- | `video-h264-720p` | 1280x720 | 23.976 | `avc1.4d4020` (H.264 Main L3.2) |
- | `video-h264-480p` | 854x480 | 23.976 | `avc1.4d4020` (H.264 Main L3.2) |
- | `video-h264-360p` | 640x360 | 23.976 | `avc1.4d401e` (H.264 Main L3.0) |
- | `video-h264-144p` | 256x144 | 23.976 | `avc1.4d401e` (H.264 Main L3.0) |
- | `audio-aac-192kbps` | - | - | `mp4a.40.2` (AAC-LC) |
- | `audio-aac-64kbps` | - | - | `mp4a.40.2` (AAC-LC) |
- より高品質な動画では `video-h264-1080p` / `1440p` / `2160p` などのラベルも追加されます。
- ### HLS マスタープレイリスト構造
- ```
- #EXTM3U
- #EXT-X-VERSION:6
- #EXT-X-INDEPENDENT-SEGMENTS
- #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio-aac-192kbps",NAME="Main Audio",DEFAULT=YES,URI="...audio-aac-192kbps.m3u8?..."
- #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio-aac-64kbps",NAME="Main Audio",DEFAULT=YES,URI="...audio-aac-64kbps.m3u8?..."
- #EXT-X-STREAM-INF:BANDWIDTH=3101972,AVERAGE-BANDWIDTH=2261618,CODECS="avc1.4d4020,mp4a.40.2",RESOLUTION=1280x720,FRAME-RATE=23.976,AUDIO="audio-aac-192kbps"
- ...video-h264-720p.m3u8?...
- #EXT-X-STREAM-INF:BANDWIDTH=2905339,AVERAGE-BANDWIDTH=2078234,CODECS="avc1.4d4020,mp4a.40.2",RESOLUTION=1280x720,FRAME-RATE=23.976,AUDIO="audio-aac-64kbps"
- ...video-h264-720p.m3u8?...
- #EXT-X-STREAM-INF:BANDWIDTH=2580733,AVERAGE-BANDWIDTH=1863833,CODECS="avc1.4d4020,mp4a.40.2",RESOLUTION=854x480,FRAME-RATE=23.976,AUDIO="audio-aac-192kbps"
- ...video-h264-480p.m3u8?...
- #EXT-X-STREAM-INF:BANDWIDTH=1100355,AVERAGE-BANDWIDTH=856250,CODECS="avc1.4d401e,mp4a.40.2",RESOLUTION=640x360,FRAME-RATE=23.976,AUDIO="audio-aac-192kbps"
- ...video-h264-360p.m3u8?...
- #EXT-X-STREAM-INF:BANDWIDTH=475614,AVERAGE-BANDWIDTH=405103,CODECS="avc1.4d401e,mp4a.40.2",RESOLUTION=256x144,FRAME-RATE=23.976,AUDIO="audio-aac-192kbps"
- ...video-h264-144p.m3u8?...
- (以下、各 video variant の 64kbps 音声バージョン)
- ```
- ポイント:
- - **HLS v6**, `#EXT-X-INDEPENDENT-SEGMENTS` 指定。
- - 音声トラックは `#EXT-X-MEDIA` (TYPE=AUDIO) として別 m3u8 に分離 (旧 `128kbps` / `64kbps` の他、新しい動画では `192kbps` / `64kbps` 等)。
- - 動画 variant ごとに `#EXT-X-STREAM-INF` で別 m3u8 を参照し、`AUDIO=` で音声グループを指定する **多重化なし** の構成。video × audio の全組み合わせが variant として列挙される。
- - フレームレートは元素材依存 (sm9 では 29.970fps, sm46309015 では 23.976fps)。
- ### URLディレクトリ構造
- ```
- https://delivery.domand.nicovideo.jp/hlsbid/{bid}/
- ├── playlists/
- │ ├── variants/{variantId}.m3u8 # マスタープレイリスト
- │ └── media/
- │ ├── video-h264-360p.m3u8
- │ ├── video-h264-360p-lowest.m3u8
- │ ├── audio-aac-128kbps.m3u8
- │ └── audio-aac-64kbps.m3u8
- └── keys/
- ├── video-h264-360p.key
- ├── video-h264-360p-lowest.key
- ├── audio-aac-128kbps.key
- └── audio-aac-64kbps.key
- https://asset.domand.nicovideo.jp/{bid}/
- ├── video/{track_number}/{quality}/
- │ ├── init01.cmfv # CMAF 初期化セグメント
- │ ├── 01.cmfv # CMAF メディアセグメント
- │ ├── 02.cmfv
- │ └── ...
- └── audio/{track_number}/{quality}/
- ├── init01.cmfa
- ├── 01.cmfa
- └── ...
- ```
- `{track_number}` は同一品質内のトラック番号 (動画は通常 `1` または `12` のようにオフセットあり)。
- ### 暗号化
- HLS セグメントは **AES-128** で暗号化され、鍵 URL は variant の m3u8 から `#EXT-X-KEY` で参照されます。
- ### URL署名 (CloudFront)
- すべての URL に AWS CloudFront の署名が含まれます。マスタープレイリストは Custom Policy (Policy + Signature)、media playlist と key は Canned Policy (Expires + Signature) を使い分けています:
- ```
- # variants (Custom Policy: 当該リソースに長期間有効)
- ?session={session_id}&Policy={base64_policy}&Signature={signature}&Key-Pair-Id=K11RB80NFXU134
- # media playlists / keys / segments (Canned Policy)
- ?session={session_id}&Expires={epoch}&Signature={signature}&Key-Pair-Id=K11RB80NFXU134
- ```
- ---
- ## コメントシステム
- ### スレッド構造
- ニコニコのコメントは「スレッド」と「フォーク」で構成されています:
- | フォーク | 説明 |
- |---------|------|
- | `owner` | 投稿者コメント |
- | `main` | メインコメント |
- | `easy` | 簡易コメント(HTML5プレイヤー用) |
- ### コメントコマンド
- コメントには「コマンド」を適用できます:
- - `184` - 匿名希望(ユーザー ID をハッシュ化して投稿)
- - `ue` / `naka` / `shita` - 表示位置 (上寄せ / 中央 / 下寄せ)
- - `big` / `medium` / `small` - 文字サイズ
- - `ender` - 描画スタイル変更 (アンチエイリアス無効化系)
- - `gothic` / `mincho` / `defont` - フォント
- - `full` - 画面いっぱい (横スクロール無効化)
- - `#RRGGBB` または色名 (`red`, `blue` 等) - 色指定
- ### threadKey JWT
- `threadKey` は JWT (`HS512`) で構成されています。ヘッダーは `{"typ": "JWT", "alg": "HS512"}`。実観測したペイロード (未ログイン時):
- ```json
- {
- "jti": "6a0b4c010f6af",
- "exp": 1779125729.06307,
- "typ": "Thread-Key",
- "d": 320,
- "tids": ["1173108780"],
- "f184s": []
- }
- ```
- | フィールド | 説明 |
- |----------|------|
- | `jti` | JWT ID |
- | `exp` | 有効期限 (浮動小数 Unix エポック秒) |
- | `typ` | トークン種別 (`Thread-Key`) |
- | `d` | 動画長 (秒) |
- | `tids` | 対象スレッドの ID 配列 |
- | `f184s` | 強制 184 (匿名) 対象スレッド ID 配列 |
- ログイン時には `uid` フィールド (ユーザー識別子) も追加されるが、未ログインのゲスト視聴では含まれない。
- ---
- ## 認証・セッション管理
- ### セッションクッキー
- 主な認証・配信用クッキー:
- | クッキー名 | ドメイン | 説明 |
- |------------|----------|------|
- | `nicosid` | `.nicovideo.jp` | セッションID |
- | `user_session` | `.nicovideo.jp` | ユーザーセッション (ログイン時) |
- | `domand_bid` | `.nicovideo.jp` | Domand ブラウザ ID (アクセス権限 API 初回呼び出し時に発行, HttpOnly, Secure) |
- ### 広告・トラッキング系クッキー
- ヘッダー入札や行動計測のために多数の 3rd party クッキーが書き込まれます (主要なもの):
- | クッキー名 | 提供元 |
- |------------|--------|
- | `_ga`, `_ga_*` | Google Analytics 4 (複数測定ID) |
- | `_gcl_au`, `__gads`, `__gpi`, `__eoi` | Google Ads / Ad Manager |
- | `_yjsu_yjad`, `_ly_su` | LINEヤフー |
- | `_tt_enable_cookie`, `_ttp`, `ttcsid*` | TikTok Pixel |
- | `_twpid` | Twitter (X) Pixel |
- | `_clck` | Microsoft Clarity |
- | `pbjs_sharedId` | Prebid.js Shared ID |
- | `_pubcid` | PubCommon ID |
- | `panoramaId` | LiveRamp Panorama |
- | `cto_bidid`, `cto_bundle` | Criteo |
- | `mgniSession` | Magnite (Rubicon) |
- | `_cc_id` | Lotame |
- ### LocalStorage
- ```javascript
- // コメント設定 (NG ユーザー等)
- localStorage['@nvweb-packages/comments:userng:v2']
- // 動画レンダラー設定 (ラウドネス情報を含む)
- localStorage['@nvweb-packages/video-renderer']
- // 視聴ページの UI 状態 (コメントリスト展開状態など)
- localStorage['nvpc:watch']
- // 視聴セッションのタブ間共有
- localStorage['nvpc:watch:tab-sessions']
- // イベント計測テスト
- localStorage['@nvweb-packages/watch-events:TEST_KEY']
- // 共通ヘッダーの掲出順制御
- localStorage['common-header-wktk-premium-lead-frames']
- localStorage['common-header-header-top-priority-period']
- // Magnite/Rubicon セッション
- localStorage['mgniSession']
- ```
- ### x-access-right-key JWT
- 動画配信APIで使用される JWT (`HS512`) ペイロード。実体に基づく正確なフィールド名:
- ```json
- {
- "jti": "6a0b4c0112fdc",
- "exp": 1779125849.0374729633331298828125,
- "typ": "Access-Right-Key",
- "vid": "sm9",
- "rid": "nicovideo-sm9",
- "fid": 6,
- "uid": "6-e3XFe1aMwH_1779125249007",
- "d": 320,
- "v": ["video-h264-360p", "video-h264-360p-lowest"],
- "a": ["audio-aac-128kbps", "audio-aac-64kbps"],
- "s": false,
- "sh": false
- }
- ```
- | フィールド | 説明 |
- |----------|------|
- | `jti` | JWT ID |
- | `exp` | 有効期限 (浮動小数 Unix エポック秒) |
- | `typ` | トークン種別 (`Access-Right-Key`) |
- | `vid` | 動画 ID |
- | `rid` | リソース ID (`nicovideo-{vid}` 形式) |
- | `fid` | フロントエンド ID (PC Web は `6`) |
- | `uid` | ユーザー識別子 (`{fid}-{actionTrackId}` 形式、未ログインでもセッション値) |
- | `d` | 動画長 (秒) |
- | `v` | 許可された動画品質ラベル配列 |
- | `a` | 許可された音声品質ラベル配列 |
- | `s` | (用途不明、観測値は `false`) |
- | `sh` | (用途不明、観測値は `false`) |
- ---
- ## 動画ギフト(投げ銭)システム
- `api.nicoad.nicovideo.jp/v1/nage_video/{id}/gift/effects` で取得可能。エフェクトアセットは `ir.cdn.nimg.jp/res/nage/common_effect/{effect_name}/asset_{effect_name}.json` で配信されます。主なエフェクト:
- `videogift_nicoru`, `videogift_kansha`, `videogift_8888`, `videogift_kami`, `videogift_kusa`, `videogift_upotsu`, `videogift_beer`, `videogift_mochi`, `videogift_makaron1`, `videogift_makaron2`, `videogift_ajisai_momo`, `videogift_xmaspresent`, `videogift_snow1`, `videogift_nengajyo2026`, `videogift_halloween_pumpkin4`, `videogift_matsuri`, `videogift_sticker`, `videogift_banner`, `videogift_bouquet`, `videogift_hoshiimono`, `videogift_premium_logo`, `videogift_premium_logo2`, `videogift_15kinen_densetsu`, `videogift_15kinen_card`, `videogift_fukidashi`, `videogift_saikou`, `videogift_kotonoha_gacha_daijoubu`, `videogift_yukari_omedetou`, `viddeogift_akari_a_moyashishamo` (typo そのまま), `videogift_nyanko_boss`, `videogift_nyanko_maneki`, `videogift_shunen_17_omedeto`.
- ---
- ## 開発に役立つ情報
- ### フロントエンド識別子
- | ヘッダー | 値 | 説明 |
- |---------|-----|------|
- | `x-frontend-id` | `6` | フロントエンドID (PC Web) |
- | `x-frontend-version` | `0` | フロントエンドバージョン |
- | `x-request-with` | `nicovideo` | リクエスト元識別 |
- | `x-niconico-language` | `ja-jp` | 言語 |
- | `x-client-os-type` | `others` | OS 種別 (コメントAPI で使用) |
- ### アクセス権限取得フロー
- 1. ページロード時に埋め込みデータから初期情報を取得 (Remix の `__remixContext`)。
- 2. `x-access-right-key` ヘッダー付きでアクセス権限 API を呼ぶ。最初は `?actionTrackId={id}` のみで `outputs` を全候補列挙し `201` を受領、`contentUrl` (実体URL) を取得。
- 3. レスポンスの `contentUrl` から HLS マスタープレイリスト (`variants/*.m3u8`) を取得。
- 4. プレイヤーが品質ごとの media playlist と AES-128 鍵を取得し、CMAF セグメントを順次ダウンロード。
- 5. 再生中は同じエンドポイントを `&__retry=0` 付きで再 POST し、`heartbeat` パラメータで状態 (再生時間, パフォーマンス計測, AI コメント可視性等) を送信。レスポンスは `200`。
- ### ストーリーボード (サムネイルシート)
- ```
- https://asset.domand.nicovideo.jp/{storyboard_bid}/storyboard/{track}/storyboard/
- ├── storyboard.json # メタデータ
- ├── 0001.jpg # サムネイル画像
- ├── 0002.jpg
- └── ...
- ```
- ### 広告配信スタック
- ニコニコ動画は多数の SSP/エクスチェンジを **Prebid.js** で同時に叩くヘッダー入札構成です:
- - **自社広告**: `ads.nicovideo.jp` (バナー), `ads.nicovideo.jp/api/video/getAd.json.php` (プリロール動画)
- - **Google**: Google Ad Manager / AdSense (`pagead2.googlesyndication.com`, `googleads.g.doubleclick.net`)
- - **Amazon**: TAM/UAM (`web-banner.ads.aps.amazon-adsystem.com`)
- - **Rubicon (Magnite)**: `fastlane.rubiconproject.com`, `prebid-server.rubiconproject.com`
- - **Index Exchange**: `htlb.casalemedia.com`
- - **OpenX**: `rtb.openx.net`
- - **PubMatic**: `hbopenbid.pubmatic.com`
- - **AppNexus (Xandr)**: `ib.adnxs.com`
- - **Media.net**: `prebid.media.net`
- - **Criteo**: `cto_*` クッキー経由
- - **MicroAd**: `s-rtb-pb.send.microad.jp`
- - **AdMatrix (AMoAd)**: `ad.as.amanad.adtdp.com`
- - **Fluct**: `hb.adingo.jp`
- - **United (ad-stir)**: `ad.ad-stir.com`
- - **CCI sociaDM**: `d.socdm.com`
- - **LINE Ads Platform**: `pb.ladsp.com`
- - **Yahoo!/LINE Impact**: `y.one.impact-ad.jp`
- - **ID プロバイダ**: LiveRamp (`api.rlcdn.com`), PubCommon, Prebid Shared ID
- ### 計測スタック
- - Google Analytics 4 (`G-FS29H4ZGX2`, `G-5LM4HED1NJ` 等)
- - Google Tag Manager (`GTM-PN8LFCT`, `GTM-KXT7G5G`)
- - 多数の Google Ads コンバージョン ID (`AW-11471143586`, `AW-11060698458`, `AW-469855517`, `AW-471708133`, `AW-691017027`, `AW-561674311`, `AW-607644388`, `AW-17911115346`, `AW-663701876`)
- - Yahoo! コンバージョン (`apm.yahoo.co.jp`)
- - TikTok Pixel (`analytics.tiktok.com`)
- - Twitter (X) Pixel (`static.ads-twitter.com`)
- - LINEヤフー LytagAd (`tag.flvcdn.net`)
- - Microsoft Clarity (`_clck`)
- ---
- *調査日: 2026年5月19日*
- *調査対象: https://www.nicovideo.jp/, https://www.nicovideo.jp/video_top, https://www.nicovideo.jp/watch/sm9*