メインコンテンツまでスキップ

投稿元の国・地域フィルター

検索結果を「投稿元の国・地域」で絞り込めるフィルター機能。

関連 Issue: #157

背景

海外チャンネルの学習用途や、特定地域のコンテンツを探したいというユーザー要望に応えるため、検索結果を「どの国・地域から投稿された動画か」で絞り込めるようにする。

本機能の定義

「投稿元の国・地域」= 動画を投稿している YouTube チャンネルが自身で設定している国・地域

  • データソースは channels.list?part=snippetsnippet.country(ISO-3166-1 alpha-2)
  • チャンネルオーナーが YouTube Studio 上で任意設定する項目であり、設定していないチャンネルが多数存在する(約 30%、Filmot 実測参考値)
  • 話者の国籍・撮影地・対象視聴者の国とは必ずしも一致しない

なぜ「投稿元の国・地域」という独自ラベル?

候補として検討したラベル:

候補ラベル採用しなかった理由
「国」どの国(視聴者?チャンネル?撮影?)か判別できない
「チャンネルの国」「チャンネルって何?」と戸惑うライトユーザーがいる
「動画の国」YouTube API に動画単位の国フィールドは存在しない(recordingDetails.location は 2017-06-01 に deprecated)ため実態と乖離する
「投稿元の国・地域」「投稿 = 動画をアップロードしているチャンネル」を自然に想起させる。「国・地域」は ISO-3166-1 に含まれる香港・台湾等への配慮

YouTube Data API の制約

調査の結果、YouTube Data API v3 には動画単体の「国」フィールドは存在しない:

フィールド状況
videos.recordingDetails.location(撮影地)2017-06-01 に deprecated 済み、取得不可
videos.snippet.defaultAudioLanguage / defaultLanguage言語であって国ではない
videos.contentDetails.regionRestriction視聴可否であり制作国ではない
channels.snippet.country唯一の公式ソース(ISO-3166-1 alpha-2)

よって本機能では「投稿元の国・地域 = チャンネル設定の snippet.country」と定義する。

字幕言語フィルターとの違い

「投稿元の国・地域」と「字幕の言語」は完全に独立した別概念である。

概念UI ラベルデータソース格納先関連仕様
投稿元の国・地域投稿元の国・地域channels.snippet.countrychannels.country本仕様書
字幕の言語字幕の言語youtube-transcript-plus のキャプショントラックMeilisearch language字幕言語フィルター

動画が「日本のチャンネルが投稿した英語字幕動画」の場合、投稿元は JP、字幕言語は en となる。両フィルターは AND で組み合わせて使われる(複数国 + 複数言語)。

UI 仕様

ラベル

  • 日本語: 「投稿元の国・地域」
  • 英語: Uploader country/region

選択モード

複数選択(Autocomplete / Combobox パターン)。例: JP + US + KR で 3 ヶ国のチャンネルの動画を横断検索できる。

  • 既存の言語・カテゴリフィルターと UX を揃える
  • URL パラメータ: co=JP,US,KR(カンマ区切り)
  • 「未設定」を選択する場合は co=unknown、混在も可 co=JP,unknown

並び順

shadcn Combobox の Groups パターンで地域別にグルーピングする:

  • 東アジア / 東南アジア / 南アジア / 中東 / 北米 / 中南米 / オセアニア / ヨーロッパ / アフリカ

Autocomplete の検索入力で国名・ISO コードともに絞り込める。

国旗絵文字は使わない

Regional Indicator Symbol(🇯🇵 等)は Windows で表示できないプラットフォーム差異があるため、絵文字は使わず国名ローカライズのみで表示する。国名は Intl.DisplayNames でロケール自動解決する(依存ゼロ、249 国対応)。

件数ファセット

各国の該当件数を国名の横に表示する(Filmot 同様):

投稿元の国・地域(選択式)
┌─────────────────────────────┐
│ [Search...] │
│ │
│ 東アジア │
│ [ ] 日本 (523) │
│ [ ] 韓国 (22) │
│ [ ] 中国 (15) │
│ │
│ 北米 │
│ [ ] アメリカ合衆国 (41) │
│ │
│ 未設定 (104) │
└─────────────────────────────┘

Meilisearch の facetDistribution 機能を使って検索クエリごとに件数を再計算する。件数 0 の国は候補に出さず、「未設定」のみ常に表示。

ヘルプダイアログ

ラベル横に Lucide HelpCircle アイコンを配置し、クリックで shadcn Dialog を開く。

ダイアログタイトル: 「『投稿元の国・地域』について」

本文:

「投稿元の国・地域」とは

動画を投稿している YouTube チャンネル自身が設定している国・地域のことです。Subseek は YouTube Data API から取得できるこの情報のみを使用しており、独自に推定は行っていません。

「未設定」とは

YouTube のチャンネルオーナーが自身のチャンネルに国・地域を設定していない場合、「未設定」に分類されます。これはオーナーによる任意設定項目のため、多くのチャンネルが「未設定」となる可能性があります。チャンネルオーナーが後から設定した場合は、次回のチャンネル情報再取得時に反映されます。

注意

投稿元の国・地域は、話者の国籍・撮影地・対象視聴者の国とは必ずしも一致しません。

閉じるボタンラベル: 「閉じる」(CLAUDE.md 規約: 情報表示ダイアログは「キャンセル」ではなく「閉じる」)

アクセシビリティ:

  • アイコンに aria-label="『投稿元の国・地域』についての説明"
  • Tab フォーカス / Enter で開く / Esc で閉じる

データ設計

DB(Turso)

channels.country カラム(詳細は データ保存戦略#channels テーブル):

  • 型: TEXT、NULL 許容
  • 値: ISO-3166-1 alpha-2(例: JP, US, HK、大文字)または NULL
  • 取得タイミング: channels.list?part=snippet を叩いたとき(初回取得・差分取得・手動再同期)

Meilisearch インデックス

subtitles インデックスの各ドキュメントに channelCountry フィールドを持たせる(チャンネル単位の値だが、セグメント単位のドキュメントに冗長に保存):

  • 型: string | null
  • filterableAttributes に追加
  • 検索 API は facetDistribution を有効化する(channelCountry のみ)

検索 API クエリパラメータ

パラメータ必須デフォルト説明
coNo未指定(全件)投稿元の国・地域(カンマ区切り、ISO-3166-1 alpha-2 または unknownco=JP,US,unknown

URL 例:

# 日本と米国のチャンネルの動画を検索
/search?q=ゲーム&co=JP,US

# 未設定のチャンネルの動画のみ検索
/search?q=ゲーム&co=unknown

# 複数国 + 未設定の混在
/search?q=ゲーム&co=JP,unknown

Meilisearch フィルタ変換

入力Meilisearch filter
co 未指定なし(全件)
co=JPchannelCountry = "JP"
co=JP,USchannelCountry IN ["JP", "US"]
co=unknownchannelCountry NOT EXISTS
co=JP,unknown(channelCountry = "JP" OR channelCountry NOT EXISTS)

「未設定」の扱い

なぜ「未設定」を常に表示するか

Filmot で「ヒカキン」を検索した場合、Japan 513 件 / N/A 265 件(全体の約 30%)となっている。これは以下の理由による:

  • channels.snippet.country は YouTube オーナーの任意入力項目
  • 古いチャンネルや個人チャンネルは未設定のまま放置されがち

未設定を隠す設計にすると「検索結果総数 ≠ 各国ファセット件数の合計」となり、ユーザーが混乱する。

日本語ラベルは「未設定」

英語 UI は Unknown を使う(Filmot は N/A だが、英語ネイティブ向けには Unknown の方が明快)。

バックフィル

本番運用開始前に導入するため、既存データのバックフィルは不要。次回以降のチャンネル取り込み・24h 差分更新で channels.country が順次埋まる。本番運用後に channels.snippet.country のフェッチ漏れが発覚した場合は、全チャンネル channels.list 再実行のスクリプトを別 Issue で用意する。

将来拡張(本スコープ外)

  • channels.snippet.country が空のチャンネル向けに、ユーザー手動タグ付け機能
  • 動画の defaultAudioLanguage からの補助的国旗表示
  • viewerCountry 等の受信側国フィルタ(CF IP 由来)

参考資料