YouTubeにはプレイリスト(再生リスト)のインポート機能がないので、YouTube Data API v3を利用して簡単なものを自作した。
プレイリストのインポート機能を実装するには、APIで挿入 (insert) 操作をリクエストする必要がある。
このAPIリクエストを実行するには、OAuth 2.0認証を行い、アプリケーション(今回の場合は自作インポート機能プログラム)によるユーザーアカウントへのアクセスが許可されなければならない。
また、このアクセス許可は、ユーザーのリソース操作全てを許可するわけではなく、スコープという仕組みを導入して許可する範囲を限定している。
プレイリストのインポート機能に必要な挿入 (insert) 操作を行う場合は、スコープ https://www.googleapis.com/auth/youtube
が許可される必要がある。
OAuth 2.0認証のやり取りを行い、承認されたクライアントオブジェクトをセットアップするためのコードが下記になる。
require_once '/path/to/google-api-php-client/vendor/autoload.php';
require_once 'OAuthClient.php';
$CLIENT_ID = '_CLIENT_ID_';
$CLIENT_SECRET = '_CLIENT_SECRET_';
$REDIRECT_URI = 'urn:ietf:wg:oauth:2.0:oob';
$TOKEN_FILENAME = "token.json";
$CODE = '_CODE_';
try
{
$gclient = new Google_Client();
$oauth = new OAuthClient($gclient, $CLIENT_ID, $CLIENT_SECRET, $REDIRECT_URI, $TOKEN_FILENAME, $CODE);
$oauth->setScopes('https://www.googleapis.com/auth/youtube');
$client = $oauth->getAuthorizedClient();
}
catch(Exception $e)
{
switch($e->getCode())
{
case OAuthClient::EMPTY_CODE:
case OAuthClient::INVALID_CODE:
echo $e->getMessage() . "\n";
echo $oauth->getAuthUrl() . "\n";
exit;
case OAuthClient::INVALID_TOKEN_FILE:
echo $e->getMessage() . "\n";
exit;
default:
throw $e;
}
}
$youtube = new Google_Service_YouTube($client);
OAuth 2.0認証の一連の処理は OAuthClient
クラスにまとめてある。このクラスの getAuthorizedClient()
を呼べば、承認されたクライアントオブジェクトが返ってくる。詳細は前の記事で説明したので、それを参照のこと。
OAuth 2.0 認証で YouTube Data API v3 を利用する
ここからは本題のインポート機能について説明する。
インポート機能は次の3つの処理から成る。
- インポートファイルの読み込み
- プレイリスト作成
- プレイリストに動画を追加
まず、下記はインポートファイルの読み込みとプレイリストの作成を行う部分。
$importFileName = "import.tsv";
$videoIds = extractVideoIds($importFileName);
$playlistName = preg_replace('/^(.+)\.tsv$/', '$1', $importFileName);
echo "creating a playlist \"$playlistName\"...\n";
$playlistSnippet = new Google_Service_YouTube_PlaylistSnippet();
$playlistSnippet->setTitle($playlistName);
$playlistSnippet->setDescription("created with the YouTube Data API v3 [" . date('Y-m-d H:i:s') . "]");
$playlistStatus = new Google_Service_YouTube_PlaylistStatus();
$playlistStatus->setPrivacyStatus('private');
$youTubePlaylist = new Google_Service_YouTube_Playlist();
$youTubePlaylist->setSnippet($playlistSnippet);
$youTubePlaylist->setStatus($playlistStatus);
$playlistResponse = $youtube->playlists->insert('snippet,status', $youTubePlaylist, []);
$playlistId = $playlistResponse['id'];
echo "done.\n\n";
function extractVideoIds($filename)
{
$videoIds = [];
$file = file_get_contents($filename);
if (!$file)
exit("Error: Can't open file: $filename\n");
echo "reading \"$filename\"...\n";
foreach (str_getcsv($file, "\n") as $row)
{
if (empty($row))
continue;
$cols = str_getcsv($row, "\t");
$videoId = preg_replace('|^https://www.youtube.com/watch\?v=(.+)$|', '$1', $cols[0]);
$videoIds[] = $videoId;
}
echo "done.\n\n";
return $videoIds;
}
インポートできるファイルは、下記のようなYouTubeの動画URLとタイトルが TSV(タブ区切り)形式で保存されたファイルを想定している。
YouTube動画URL1 動画タイトル1
YouTube動画URL2 動画タイトル2
YouTube動画URL3 動画タイトル3
...
このファイルを読み込んで動画IDだけ抽出する。
続いてプレイリストの作成では、まず、snippet
プロパティと status
プロパティの値を保持する PlaylistSnippet
と PlaylistStatus
オブジェクトをそれぞれ作成する。
PlaylistSnippet
オブジェクトの作成では、snippet
プロパティ内の snippet.title
プロパティと snippet.description
(プレイリストの説明)の値を setTitle()
と setDescription()
でそれぞれセットする。上記のコードの例では、title
にはインポートファイルのファイル名、description
には文字列 created with the YouTube Data API v3
とそれにタイムスタンプを付加したものをセットしている。
PlaylistStatus
オブジェクトの作成では、status
プロパティ内の status.privacyStatus
プロパティの値をセットする。有効な値は、public
、private
、unlisted
の3つで、デフォルトは public
となる。上記のコードの例では、private
をセットし、作成するプレイリストは非公開のものとして設定している。
PlaylistSnippet
と PlaylistStatus
オブジェクトを作成したら、それらを Playlist
オブジェクト $youTubePlaylist
に setSnippet()
と setStatus()
でそれぞれセットする。そして、$youtube->playlists->insert('snippet,status', $youTubePlaylist, [])
でAPIリクエストを行い、プレイリストの作成が完了する。insert()
の引数 'snippet,status'
は、書き込み操作対象となるプロパティを特定するものである。
APIレスポンスに作成されたプレイリストIDが含まれているのでそれを取得する。
次に、このIDを使って、プレイリストに動画をインポートしてプレイリストを完成させていく。
foreach ($videoIds as $i => $videoId)
{
echo "$i: videoId: $videoId ";
$resourceId = new Google_Service_YouTube_ResourceId();
$resourceId->setVideoId($videoId);
$resourceId->setKind('youtube#video');
$playlistItemSnippet = new Google_Service_YouTube_PlaylistItemSnippet();
$playlistItemSnippet->setPlaylistId($playlistId);
$playlistItemSnippet->setResourceId($resourceId);
$playlistItem = new Google_Service_YouTube_PlaylistItem();
$playlistItem->setSnippet($playlistItemSnippet);
$playlistItemResponse = $youtube->playlistItems->insert('snippet', $playlistItem, []);
echo "inserted.\n";
}
echo "\ndone.\n";
プレイリストはプレイリストアイテムから構成され、インポートする動画一つ一つに対応するプレイリストアイテムを作成して、それらをプレイリストに挿入していくのが主な処理となる。
プレイリストアイテムの作成手順は前述のプレイリスト作成と同様で、プレイリストアイテムの snippet
プロパティの値を保持する PlaylistItemSnippet
オブジェクトを作成し、それを PlaylistItem
オブジェクトの setSnippet()
に渡してセットし、PlaylistItem
オブジェクト $playlistItem
をセットアップする。そして、$youtube->playlistItems->insert('snippet', $playlistItem, [])
でAPIリクエストを行い、プレイリストにプレイリストアイテムを挿入し、動画一つのインポートが完了する。
違う点は、プレイリストアイテムとプレイリストの紐付け、また、プレイリストアイテムと動画IDを紐付けるために ResourceId
オブジェクトを作成する必要があるというところ。
プレイリストアイテムとプレイリストの紐付けは、PlaylistItemSnippet
オブジェクトの setPlaylistId()
にプレイリストIDを渡して行う。
プレイリストアイテムと動画IDの紐付けは、ResourceId
オブジェクトを作成し、setVideoId()
で動画IDをセット、setKind()
でリソースタイプをセットする。リソースタイプは動画の場合、youtube#video
となる。そして、ResourceId
オブジェクトを PlaylistItemSnippet
オブジェクトの setResourceId()
に渡し、プレイリストアイテムと動画IDが紐付けられる。