加了好幾首 "最美的歌" 到喜歡的影片
於是就想試看看如何用程式來下載影片
網路上其實有很多線上服務可以做到
不過 RD 就是要捲起袖子自己來才有 fu
網路上查了一下
大概是利用 get_video_info 這個 api 配合影片 id
先取得影片 url ,接著就可以 download
舊的作法會再取得 'sig' 並串到 url 裡面(&singature=XXX)
但根據我 2018/03/14 的測試
url 裡面其實就有 'signature'
如果沒有,用 get_video_info 也會沒有
此時這個影片可能也不用下載了
因為一定會失敗
(但是線上服務是可以的)
不過這個 api 並不是官方 release 的
故以後還能不能用並不知道
再來也不是每個影片都能下載
步驟大概如下
1. 手動在 Youtube 喜歡的影片頁面,下載該頁面原始檔
2. 程式 parse 原始檔,找到影片的 id 及 title
3. 使用 get_video_info 取得 mp4 的下載 url
4. 使用 curl 下載檔案
github 連結
<?php
function downloadVideo($id, $title, $url, $video)
{
$fp = fopen($video, "w");
if (!$fp) {
echo "$id $title can't create video file \n";
return;
}
$ch = curl_init();
if ($ch === false) {
echo "$id $title curl_init error \n";
fclose($fp);
return;
}
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST , false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER , false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 600);
curl_setopt($ch, CURLOPT_HEADER , false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION , true);
curl_setopt($ch, CURLOPT_AUTOREFERER , true);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36');
curl_setopt($ch, CURLOPT_FILE, $fp);
$con = curl_exec($ch);
curl_close($ch);
if ($con === false) {
echo "$id $title download video error \n";
fclose($fp);
return;
}
fclose($fp);
}
function processVideo($id, $title, $video)
{
$api = sprintf("http://www.youtube.com/get_video_info?video_id=%s", $id);
$res = file_get_contents($api);
if ($res === '') {
echo "$id $title res is null \n";
return;
}
$params = [];
parse_str($res, $params);
if (!isset($params['url_encoded_fmt_stream_map'])) {
echo "$id $title url_encoded_fmt_stream_map error \n";
return;
}
$s = $params['url_encoded_fmt_stream_map'];
$streams = explode(',', $s);
$realURL = '';
for ($i = 0; $i < sizeof($streams); $i++) {
$params = [];
parse_str($streams[$i], $params);
if (!isset($params['url']) || !isset($params['type']) || !isset($params['quality'])) {
echo "$id $title params error \n";
return;
}
$url = urldecode($params['url']);
$type = urldecode($params['type']);
$quality = urldecode($params['quality']);
if (strpos($type, 'video/mp4') == 0) {
$realURL = $url;
if ($quality === 'medium') {
break;
}
}
}
if ($realURL === '') {
echo "$id $title has no mp4 type \n";
return;
}
//echo "$title, $realURL\n";
downloadVideo($id, $title, $realURL, $video);
}
// "youtube.txt" is the file that you use browser to save the page of your favorite videos.
$html = file_get_contents('youtube.txt');
$pattern = '/window\[\"ytInitialData\"\] = ({.*});/';
if (!preg_match($pattern, $html, $matchs)) {
echo "can't find favorites \n";
return;
}
$s = $matchs[1];
$json = json_decode($s, true);
$songs = $json['contents']['twoColumnBrowseResultsRenderer']['tabs'][0]
['tabRenderer']['content']['sectionListRenderer']['contents'][0]
['itemSectionRenderer']['contents'][0]
['playlistVideoListRenderer']['contents'];
for ($i = 0; $i < sizeof($songs); $i++) {
$title = $songs[$i]['playlistVideoRenderer']['title']['simpleText'];
$title = mb_convert_encoding($title, "big5", "utf-8");
$title = str_replace([' ', '?'], ['', ''], $title);
$id = $songs[$i]['playlistVideoRenderer']['videoId'];
//echo "$id $title \n";
$video = sprintf("%s\\%s.mp4", __DIR__, $title);
processVideo($id, $title, $video);
sleep(10);
}
2 則留言:
你好,請問現在還可以用嗎?
執行後出現 Undefined index: twoColumnBrowseResultsRenderer in /var/www/html/youtube/favorite-youtube-to-video.php
或者您可以提供youtube.txt嗎?
謝謝喔
Hi Claire's
https://raw.githubusercontent.com/tylpk1216/favorite-youtube-to-video/master/youtube.txt
因為工作地方網路的關係,沒辦法試下載
但我看歌名的解析都還是正常的
也許您可以試看看
張貼留言