YouTubeから動画をダウンロード
YouTubeではHTML内に動画FLVのURLが隠されているので、これを抜き出して動画をダウンロードします。
YouTubeの使い方を説明している動画のURL「http://www.youtube.com/watch?v=xoZV-BtJjXw」にブラウザからアクセスして、ソースを参照してください。
上記画面のJavaScriptの「fmt_url_map=・・・」内に「http://xxxx.c.youtube.com/~&id=xxxxx」という記述があり、この部分が動画ファイルにアクセスできるURLとなっています。
本項ではZend_Http_Clientを使って「http://www.youtube.com/watch?v=xoZV-BtJjXw」のURLにアクセスし、HTMLソースを取得後、動画ファイルのURLを抽出してダウンロードする方法を説明します。
HTTPリクエストを扱うライブラリZend_Http_Clientを利用すると、GETやPOSTメソッドでURLにアクセスしてコンテンツを取得したり、認証を行ったりといった通常のブラウザと同じような使い方ができます。さらにURLにアクセスする際にUserAgentを設定できるため、YouTubeのようにアクセスしてきた端末によって表示を変える画面でも、希望する端末向けのコンテンツを正確に取得できます。
Zend_Http_Clientの主なメソッドは以下の通りです。
メソッド名 | 概要 |
setConfig(配列) | アクセスする際の状態を配列で設定する(後述) |
setUri(URL) | アクセスするURLを設定する |
setHeaders(ヘッダ名, 値) | アクセスする際のヘッダを設定する |
setParameterPost(配列) | リクエスト送信の際のパラメーターを連想配列で設定する |
request(メソッド) | リクエストを送信し、レスポンスオブジェクト(Zend_Http_Response、後述)を返却するメソッドは「GET」「POST」で指定する |
setCookie(名前, 値) | アクセスする際のクッキーの名前と値を設定する |
setConfigメソッドで指定できる主なパラメータは以下の通りです。
名前 | 意味 |
maxredirects | リダイレクトする際の最大数 |
useragent | ユーザーエージェント |
timeout | 接続時のタイムアウト時間(秒) |
keepalive | keep-alive接続を有効にするか? |
requestメソッドの戻り値であるレスポンスオブジェクトZend_Http_Responseの主なメソッドには、以下のものがあります。
メソッド名 | 概要 |
isSuccessful() | リクエストが成功したか否かを返却する |
getStatus() | HTTPレスポンスステータスコード(200や404など)を取得する |
getHeaders() | HTTPレスポンスヘッダを連想配列形式で取得する |
getBody() | HTTPレスポンス本文を取得する |
Zend_Http_Clientを利用してHTMLソースを取得して解析する部分は以下のようになります。
require_once 'Zend/Http/Client.php'; // YouTube紹介動画のURL $url = "http://www.youtube.com/watch?v=xoZV-BtJjXw"; // Zend_Http_Clientをコール $client = new Zend_Http_Client(); // URLをセット $client->setUri($url); // アクセス条件をセット $client->setConfig(array( 'useragent' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)', 'timeout' => 10, 'keepalive' => true )); // リクエストを送信、レスポンスを取得 $response = $client->request('GET'); // HTMLを取得 $content = $response->getBody();
PC向けブラウザからのアクセスであることを明示的にするために、IEのUserAgentを設定しています。$response->getBody()でYouTube紹介動画の画面のHTMLが取得できます。
取得したHTMLの解析には正規表現を使います。
// fmt_url_map=~ の部分を取得する $pattern = "fmt_url_map=(.*?)\""; preg_match("/".$pattern."/i", $content, $match); // 該当する部分 $_match_str = urldecode($match[1]); // 動画のURLを取得する $pattern = "http(.*?)&id=(.*?)&"; preg_match_all("/".$pattern."/i", $_match_str, $match); // flv動画のURL $_flv_url = end($match[0]);
HTMLソース内に動画のURLは複数存在する場合があります。いくつものソースで試してみた結果、最後に出てくる動画のURLがもっとも確実にダウンロードできたため、サンプルでも最後に見つかったURLで動画をダウンロードしています。
動画のダウンロードでもZend_Http_Clientを利用します。前項と同様に「$response->getBody()」でアクセス先のコンテンツが取得できます。
// URLをセット $client->setUri($_flv_url); // 通信開始 $response = $client->request('GET'); // 動画にアクセスしてダウンロード $content = $response->getBody(); // ダウンロードした動画をファイルに書き出す $_output = "youtube.flv"; $_outputResourse = fopen( $_output ,"w"); flock($_outputResourse ,LOCK_EX); fwrite($_outputResourse,$content);
上記コード内では$response->getBody()に動画ファイルの実体が入るので、これをfwrite関数でファイルに書き出しています。
ここまでで動画のダウンロード部分は完成しました。