【Flutter】Youtube APIを用いて動画情報を検索するFlutter PackageにPR送ってみた

## 概要
**目的**
開発中のアプリ内で、YouTubeの特定のチャンネルの動画を検索したい。

**やったこと**
Flutterでyoutube動画の情報を取得するFlutter Packageを用いてみる

**できなかったこと**
特定のchannel内の動画を検索する

**解決策**
Flutter Packageのコードを書き換える。
ついでにPackageのレポジトリに向けてPRを作ってみた。

## はじめに
### YoutubeAPIへの登録
とりあえずまずはYouTubeApiに登録して、apiを利用できるようにしておく。
手順がなかなかのってなかったり、記事と違う画面だったりで戸惑ったので、記録として残す。

https://developers.google.cn/youtube/v3/getting-started?hl=ja

#### プロジェクトの作成(選択)
上記記事から、Google Cloud Platformのページ(Google Cloud Console)に行き、新しいプロジェクトを作成する。
もしくは、もともとあるプロジェクトを選択する。

![リソースの管理_–_Google_Cloud_Platform.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/dd080d60-97ae-2898-ec93-21066e49dd10.jpeg)

#### YoutubeAPIの有効化

選んだプロジェクトのAPIのダッシュボードを表示する

![ホーム_–_map-app-youtube_–_Google_Cloud_Platform.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/7bcd97d9-9c92-88d5-8618-46d4ad684b02.jpeg)

デフォルトでは、YoutubeAPIは有効化されていない。

![API_とサービス_–_API_とサービス_–_My_Project_–_Google_Cloud_Platform.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/1078a536-e265-8fd8-0c2a-89046e3a49ec.jpeg)

ゆえに、ページ上部のリンクからyoutube APIを検索し、有効にする。

![API_とサービス_–_API_とサービス_–_My_Project_–_Google_Cloud_Platform-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/6ebc77fa-0384-fced-5f4b-163a95570161.jpeg)

![ライブラリ_–_API_とサービス_–_My_Project_–_Google_Cloud_Platform.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/d111f84f-16f6-753e-ff48-a6fe6962532e.jpeg)

有効にすると、一覧の中に加わっている！！

![API_とサービス_–_API_とサービス_–_My_Project_–_Google_Cloud_Platform-3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/f5c55e5d-3ded-e354-960b-c9ccfd612663.jpeg)

#### APIキーの取得
すでにAPIkeyを取得している場合は、そのAPIkeyのパーミッションを更新する。
![API_キーの制限と名前変更_–_API_とサービス_–_My_Project_–_Google_Cloud_Platform.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/324913b9-b2f9-d98f-4356-293d282a51ff.jpeg)


まだ持っていない場合は、新たに作成する。
![認証情報_–_API_とサービス_–_My_Project_–_Google_Cloud_Platform.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/cb705ef5-9374-1f47-2bc9-455d0d6ea98d.jpeg)

これで、APIKeyが取得できた！


## いざ実装
やりたいことは、特定のyoutuberの動画の中から、ユーザが入力した文字列にヒットする動画を取得すること。
YouTube DataのAPIのページを見ると、searchにchannelIdで特定のchannelのidを渡せばいけそうだということがわかった。

https://developers.google.com/youtube/v3/docs/search/list?hl=ja

> channelId	string
> channelId パラメータは、チャンネルによって作成されたリソースのみが API レスポンスに含まれるように指定します。


### パッケージの選択

flutterには、以下のようなパッケージがすでに色々存在存在していた。
ただ、どのパッケージも、**channelIdをYouTubeDataAPIに渡すことはできない**っぽかった。

仕方がないので、一番汎用性が高そうだった以下のパッケージのファイルをまるまるlibディレクトリにコピペして、ファイルの一部をchannelIdを追加できるように変更することとする。
(ほんとはうまいことoverrideとか使った方がいいのだろうが、技術力不足ゆえご容赦。)

https://pub.dev/packages/youtube_api

### コードの修正

```dart:src/util/_api.dart
class ApiHelper {

  // 略
  
  // 以下の関数を修正
  Uri searchUri(
    String query, {
    String? type,
    String? regionCode,
    String? channelId, // <- 追加!!
    required String videoDuration,
    required String order,
  }) {
    this.query = query;
    this.type = type ?? this.type;
    this.channelId = channelId ?? this.channelId;  // <- 追加!!
    final options = {
      "q": "${this.query}",
      "part": "snippet",
      "maxResults": "${this.maxResults}",
      "key": "${this.key}",
      "type": "${this.type}",
      "order": order,
      "videoDuration": videoDuration,
      "channelId": "${this.channelId}", // <- 追加!!
    };
    if (regionCode != null) options['regionCode'] = regionCode;
    print(options);
    Uri url = new Uri.https(baseURL, "youtube/v3/search", options);
    return url;
  }
  
  // 略

}

```


```dart:youtube_api.dart

// 前略

class YoutubeAPI {
  
  // 略
  
  // 以下の関数を修正
  Future<List<YouTubeVideo>> search(
    String query, {
    String type =  'video,channel,playlist',
    String order = 'relevance',
    String videoDuration = 'any',
    String? regionCode,
    String? channelId // <- 追加!!
  }) async {
    this.getTrending = false;
    this.query = query;
    final url = api!.searchUri(
      query,
      type: type,
      videoDuration: videoDuration,
      order: order,
      regionCode: regionCode,
      channelId: channelId, // <- 追加!!
    );

    // 略

  }
  
  // 略

}

```

### PRの作成

せっかくなので、上記の変更でPR作ってみた。

https://github.com/nstack-in/youtube_api/pull/41

さらに、上がってるIssueみて、自分も困っている部分があったので、それも解決するようなPRを作ってみた。

https://github.com/nstack-in/youtube_api/pull/42

あとはPRがmergeされるのを待って、これらがmergeされたversionがリリースされたら、そのバージョンを使って自分のコードもまた修正すれば良い。