2013年5月23日星期四

拆解 Youtube 影片下載位置

坊間有不少下載 Youtube 影片的網頁
究竟他們是如何操作?

要尋找 Youtube 影片的來源連結,除了之前提及使用 Chrome
還可以使用 http://www.youtube.com/get_video_info

http://www.youtube.com/get_video_info 屬於 Youtube API 的一部分
加插 video_id 參數便可以讀指定 Youtube 影片的資訊

例如要讀取 http://www.youtube.com/watch?v=fEcnrA6RIzo 的資訊
將 v 的參數加插至 http://www.youtube.com/get_video_info?video_id=fEcnrA6RIzo

會得到一串 query string 資料
拆解資料可獲得影片
hl 為預設語言
author 為影片上載者
iurlsd 為封面圖片
thumbnail_url 為封面縮圖
length_seconds 為影片長度,以秒計算
title 為影片標題
url_encoded_fmt_stream_map 為另一串 query string 保存著影片的來源資訊,而來源資訊以 , 分類

再將 url_encoded_fmt_stream_map 拆解
quality 為影片品質,分別有:
smail 為 240p
medium 為 360p
large 為 480p
hd720 為 720p
hd1080 為 1080p
sig 為用作許可影片播放的「簽名」
type 為影片類型,分別有:
video/3gpp 為 3gp 格式
video/mp4 為 mp4 格式
video/webm 為 webm 格式
video/x-flv 為 flv 格式
url 為影片來源,都是一種 query string

要下載一個 Youtube 影片,需要將 url 及 sig 以 signature 連接才能夠下載
即 <url>&signature=<sig> 的超連結

以下是以 PHP 拆解 http://www.youtube.com/get_video_info
@set_time_limit(0); // 將載入時間設定為 0 即不限操作時間,避免操作逾時
//$video_id = $_GET['video_id']; // 讓 video_id 可以透過 query string 代入,這樣可以動態拆解不同的 Youtube 影片
$video_id = 'fEcnrA6RIzo';

$params = array(); // 宣告 $params 為 array
// 讀取 Youtube API 的 query 
$query_string = file_get_contents('http://www.youtube.com/get_video_info?video_id=' . $video_id);
parse_str($query_string, $params); // 拆解 query string 載入至 $params

$streams = explode(',', $params['url_encoded_fmt_stream_map']); // 以 , 將 $params['url_encoded_fmt_stream_map'] 分拆
foreach ($streams as $stream){
    $s = array();
    parse_str($stream, $s);
    if (($index = strpos($s['type'], ';')) !== false){
        $s['mime'] = substr($s['type'], 0, $index); // 選取 mimetype 部分
    }
//  是因為 br 在 blog 中會變成換行,不能顯示,閣下是不需要將 br 分開
    printf('<a href="%s&signature=%s">%s-%s(%s-%s)</a><b' . 'r/>'
        , urldecode($s['url'])
        , $s['sig']
        , $params['author']
        , $params['title']
        , $s['mime']
        , $s['quality']
    );
}
以上程序,會顯示類似以下格式,來源資料數量,根據影品質與類型而不同
其他程式語法都可以進行類似操作
由於 PHP 提供了 parse_str 拆解 query string 及 urldecode 轉換 url encoded string
PHP 不需要自編 parse_str 及 urldecode
例如 Java 本身沒有能拆解 query string 的功能,便需要自行編 query string parser

如果經常下載 Youtube 影片,有些網站還可以將影片轉換成 mp3 格式
技術上,其實是該網頁先將影片下載至它們的伺服器,利用 FFmpeg 等能與 PHP 等網頁語言整合的程序處理
所以會發現操作速度非常慢,因為在下不建議讓對方伺服器處理
比起由對方處理,其實自行下載至本機,再自行轉換格式比由對方操作快得多

3 則留言 :