【YouTube Data API】Youtubeの動画の諸データを取得する

公式にも使用方法が纏まっていたが、一応纏めた。

前準備

以下のサイトの「作業を始める前に」に従って準備をする。
Youtube Data API の概要

情報の取得方法

動画の情報を取得する際は、

https://www.googleapis.com/youtube/v3/videos?id={videoID}&key={apiKey}&part={parts}&fields={fields}

のURLを叩けば良い。(fieldsは任意)

idパラメータはビデオID(動画のURL末尾の11桁の英数記号)、keyパラメータはAPIキーを指定する。

partパラメータ(必須)

このパラメータは、取得する情報の大まかな種類を決める。「大まかな」と書いたのは、最上位のカテゴリしか指定できないからだ。

より細かい項目ごとの指定は、この後解説する"fields"パラメータで行う。

よく使うところとしては、

  • snippet 動画の基本的な情報(タイトル、説明、カテゴリなど)が格納される。
  • contentDetails 動画の長さとアスペクト比を含む、動画コンテンツに関する情報が格納される。
  • status 動画のアップロード、処理、プライバシーのステータスに関する情報が格納される。
  • statistics 動画に関する統計情報が格納される。

具体的な取得できる値については公式サイトに乗っている。

fieldsパラメータ(任意)

詳しく所得する情報を指定できるこのパラメータは、階層構造にそって指定していく。説明するより具体例を見たほうが良いと思うので、具体例を紹介する。(パラメータのところのみ掲載。)

- snippet内のデータのみ取得 : fields=items(snippet(title))
- 動画名のみ取得 : fields=items(snippet(title))
- 動画IDと公開日時、動画名を取得 : fields=items(id,snippet(publishedAt,title))

もちろん、上記の例では part=snippet は必須になる。

ソースコード

以上を踏まえて、動画名を取得するコードをC#で記述してみる。

string youtubeID = "jNQXAC9IVRw";

string apiKey = "*****";//自分の取得したAPIキー

//YoutubeビデオIDが有効か
if(Regex.IsMatch(youtubeID, @"[0-9a-zA-Z-_]{11}"))
{
    //APIを叩く
    string youtubeDataJson = Encoding.UTF8.GetString(wc.DownloadData($"https://www.googleapis.com/youtube/v3/videos?id={youtubeID}&key={apiKey}&part=snippet&fields=items(snippet(title))"));

    //最後の"までを削除
    youtubeDataJson = youtubeDataJson.Remove(youtubeDataJson.LastIndexOf("\""));

    //最後の"から後だけ残す(これで動画名の取得)
    youtubeDataJson = youtubeDataJson.Substring(youtubeDataJson.LastIndexOf("\"") + 1);
    
}

ゴリゴリと削って動画名を取得しているが、Json.NETというJson形式のファイルをキレイにデコードしてくれるNuGetパッケージもあるので、そちらもおすすめだ。

【C#】Youtubeから音源だけダウンロードする

自分で実装しようか迷ったけど既存サービスを使うことにした。

使おうと思っていたアルゴリズムは下に纏めておく。

ファイル名に動画名を使いたい場合は、以下の記事を参照して欲しい。

cnth1a.hatenablog.com

また、音声のみ分離してダウンロードすることはYoutube規約違反である。使用する場合は自己責任で。

ソースコード

//動画のURLにくっついている11桁のID
string youtubeID = "jNQXAC9IVRw";

string savePath = @"D:\hoge.mp3";

string url = $"http://www.youtubeinmp3.com/fetch/?video=https://www.youtube.com/watch?v={youtubeID}";

wc.DownloadFile(url,savePath);

たまにyoutubeinmp3の直リンクアドレスがMP3を返さないことがある。まだ変換されたことが無いものはそうなるようだ。現在、他のAPIを探している。

http://www.youtubeinmp3.comというサービスを使用した。ソースにもある通り、このサービスはhttp://www.youtubeinmp3.com/fetch/?video={youtubeID}というURLにアクセスすることでMP3を取得できる。

そのままWAVデータに変換する場合は、以下の記事が役に立つと思う。

cnth1a.hatenablog.com

Youtubeの動画の音源のみのダウンロードのアルゴリズム

YoutubeからMP4をダウンロードすることは比較的容易に可能で、少し調べれば出てくる。(ここでは詳述しないが、仕様変更が何度かされているので古い情報には注意。)

その後、MP4のファイルを途中までダウンロードし、動画ファイル部分をを表すBox(MP4では一つ一つのデータがBoxと呼ばれる塊になっている)を読み飛ばし、音声データだけをダウンロードする。

その後、それをデコードする。これで音声ファイルにできる、はず。

途中で諦めたので本当にこれで出来るかどうかも分からない。

【C# 】バイト列で受け取ったMP3をファイルに書き出さずにWAVに変換する【NAudio】

Webからダウンロードした音源データをファイルにせずに変換したい時に躓いたのでメモ。

ググっても一旦MP3で保存してその後WAVで書き出して~とかしか出てこなくて困った。

コード

このコードではNAudioを使う。NAudioとは何か、導入手順等は以下の記事を参照して欲しい。

//MP3のバイト列
byte[] mp3Byte = hogehoge();
byte[] wavByte;

using (Stream stream = new MemoryStream())
{
    stream.Write(mp3Byte, 0, wavByte);

    stream.Position = 0;
                
    using (WaveStream pcm = new Mp3FileReader(stream))
    {
        wavByte = new byte[Convert.ToInt32(pcm.Length)];
        //wavByteに読み込み
        pcm.Read(wavByte,0, Convert.ToInt32(pcm.Length));
    }
}

streamをMemoryStreamで初期化している。これは、ファイルの読み取り先にメモリを使用するストリームである。

つまり、Byte配列等の生データから読み込めるということだ。

そのStreamに書き込んだ後、Positionを0に戻す

後のMp3FileReaderがPositionからデコードするのか、これが無いとエラーを吐く。

Mp3FileReaderでデコードして、そのデータをwavByteに読み込む。このデータは生のPCMデータ、つまり波形のデータだ。

また、wavFileを保存する場合はwavByteに書き込むところを

WaveFileWriter.CreateWaveFile(savePath, pcm);

とすれば良いし、そのまま再生する場合はWaveStreamを再利用できる。