常常覺的Youtube上的影片有些還真有趣,
就會想要下載下來,以後無聊可以看看。
所以就研究了一下怎麼寫。
其實程式不難,短短的就可以搞定了。
下面就貼上我亂寫的一些Code。
第一種方式,是使用 get_video_info 來取得影片資訊,進而拿到token ,取得影片路徑。
function doHttpRequest($url) { $ch = curl_init(); $header[] = "Cache-Control: no-cache"; $header[] = "Pragma: no-cache"; curl_setopt($ch, CURLOPT_HTTPHEADER, $header); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 4); curl_setopt($ch, CURLOPT_TIMEOUT, 4); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_FAILONERROR, 1); $result = curl_exec($ch); curl_close($ch); return $result; } $url = 'http://www.youtube.com/watch?v=q_gfD3nvh-8'; // video_id $key = explode("v=",$url); $key = $key[1]; $content = doHttpRequest("http://youtube.com/get_video_info?video_id=".$key); $a = explode('&', $content); $info = array(); foreach($a as $item){ $tmp = explode('=', $item); $info[$tmp[0]] = urldecode($tmp[1]); } $token = $info['token']; $url= 'http://www.youtube.com/get_video?fmt=18\&video_id='.$key.'\&t='.$token; $cmd = '/usr/bin/wget '.$url. ' -O /tmp/'.$key; system($cmd, $ret_val); echo $ret_val; // 回0表正常抓到檔案。
但第一種方式會有一個缺點,就是當影片有限制時,會有錯誤,例如回傳下列錯誤訊息。
array(3) { ["status"]=> string(4) "fail" ["errorcode"]=> string(3) "150" ["reason"]=> string(90) "這部影片含有 SM Entertainment 所擁有的內容,禁止在特定網站上播放。" }
所以這時候,可以改成用下列這種方式來抓影片,這個方式是直接把Youtube的播放頁Html全部抓回來,
然後取得所要的token及相關資訊,程式如下:
$url = 'http://www.youtube.com/watch?v=q_gfD3nvh-8'; // 取得 video id, 必要 $key = explode("v=",$url); $key = $key[1]; $txt = urldecode(file_get_contents($url)); // 取得 title, 非必要 preg_match('/ $title = substr($title[0], 28, -2); // 取得 keywords, 非必要 preg_match('/ $keywords = substr($keywords[0], 31, -2); // 取得 token, 必要 preg_match('/&t=[\w-=_]+/',$txt,$t_temp); $t = substr($t_temp[0], 3); $url= 'http://www.youtube.com/get_video?fmt=18\&video_id='.$key.'\&t='.$t; $cmd = '/usr/bin/wget '.$file. ' -O /tmp/'.$key; system($cmd, $ret_val); echo $ret_val; // 回0表正常抓到檔案。
所以基本上只要用第二種方式,就可以了抓到影片了。
不過我不太會regExp,所以寫的有點…暴力……
以上~~
附上 fmt 資訊 ( 來源:一次搞懂十種YouTube格式 )
※影片格式與&fmt參數對應
- MP4格式:&fmt=18、22、37
- 3GP格式:&fmt=13、17
- FLV格 式:其他皆是
※&fmt參數與影片規格對照
參數 | 檔案格式 | 影片大小 | 聲音格式 | 備註 |
&fmt=0 | FLV | 320 x 240 | 單聲道 22KHz MP3 | 與&fmt=5相同 |
&fmt=5 | FLV | 320 x 240 | 單聲道 44KHz MP3 | |
&fmt=6 | FLV | 480 x 360 | 單聲道 44KHz MP3 | |
&fmt=34 | FLV | 320 x 240 | 雙聲道 44KHz MP3 | YouTube預設影片格式 |
&fmt=35 | FLV | 640 x 380 | 雙聲道 44KHz MP3 | |
&fmt=13 | 3GP | 176 x 144 | 雙聲道 8KHz | 適合小螢幕手機 |
&fmt=17 | 3GP | 176 x 144 | 單聲道 22KHz | 適合小螢幕手機 |
&fmt=18 | MP4 | 480 x 360 | 雙聲道 44KHz AAC | H.264編碼 |
&fmt=22 | MP4 | 1280 x 720 | 雙聲道 44KHz AAC | H.264編碼 |
&fmt=37 | MP4 | 1920 x 1080 | 雙聲道 44KHz AAC | H.264編碼 |
2010-08-05 更新:
不久前發現 http://www.youtube.com/get_video 這隻不能用了~
真的很麻煩,現在改成用 get_video_info 取得影片資訊,
然後 Parsing 裡面的 fmt_url_map ,取得各種格式的網址去下載。
Parser url_encoded_fmt_stream_map的資訊,在local端可以正常出現正確url, 但是部署到外部Server所取到的url不正確。 好像只能在local端使用?
回覆刪除