制作自己的YouTube视频下载程序的所有当前教程都已过时。视频信息中的整个令牌插入不起作用,也没有使用javascript方法。有没有人知道如何做到这一点,而不只是下载别人的程序?我只是想知道这个方法,所以我可以自己编程(为了好玩:D)
提前致谢!
答案 0 :(得分:41)
截至2014年1月1日,下面描述的旧技术似乎无法可靠地运行。 Youtube的页内变量结构似乎已经改变了,我还没有能够找出更新版本。
这是一个更新的(2017年6月)版本,可直接在任何浏览器中提供的开发工具控制台中运行。目前应该适用于任何Youtube媒体类型,包括最多4k(如果可用)。
https://gist.github.com/geuis/8b1b2ea57d7f9a9ae22f80d4fbf5b97f
// ES6 version
const videoUrls = ytplayer.config.args.adaptive_fmts
.split(',')
.map(item => item
.split('&')
.reduce((prev, curr) => (curr = curr.split('='),
Object.assign(prev, {[curr[0]]: decodeURIComponent(curr[1])})
), {})
)
.reduce((prev, curr) => Object.assign(prev, {
[curr.quality_label || curr.type]: curr
}), {});
console.log(videoUrls);
// ES5 version
var videoUrls = ytplayer.config.args.adaptive_fmts
.split(',')
.map(function (item) {
return item
.split('&')
.reduce(function (prev, curr) {
curr = curr.split('=');
return Object.assign(prev, {[curr[0]]: decodeURIComponent(curr[1])})
}, {});
})
.reduce(function (prev, curr) {
return Object.assign(prev, {
[curr.quality_label || curr.type]: curr
});
}, {});
console.log(videoUrls);
https://www.youtube.com/watch?v=9bZkp7q19f0
的示例输出{
"1080p": {
"itag": "248",
"xtags": "",
"lmt": "1440215955569849",
"url": "https://r16---sn-n4v7kn7r.c.youtube.com/videoplayback?itag=248&keepalive=ye…2Cmm%2Cmn%2Cms%2Cmv%2Cpl%2Crequiressl%2Csc%2Csource%2Cexpire&mt=1498245944",
"type": "video/webm;+codecs=\"vp9\"",
"bitrate": "1733724",
"index": "243-1977",
"size": "1920x1080",
"projection_type": "1",
"fps": "30",
"clen": "31192903",
"init": "0-242",
"quality_label": "1080p"
},
"720p": {
"itag": "247",
"xtags": "",
"lmt": "1440215905109639",
"url": "https://r16---sn-n4v7kn7r.c.youtube.com/videoplayback?itag=247&keepalive=ye…2Cmm%2Cmn%2Cms%2Cmv%2Cpl%2Crequiressl%2Csc%2Csource%2Cexpire&mt=1498245944",
"type": "video/webm;+codecs=\"vp9\"",
"bitrate": "726076",
"index": "243-1933",
"size": "1280x720",
"projection_type": "1",
"fps": "30",
"clen": "15801933",
"init": "0-242",
"quality_label": "720p"
},
"480p": {
"itag": "244",
"xtags": "",
"lmt": "1440215890236689",
"url": "https://r16---sn-n4v7kn7r.c.youtube.com/videoplayback?itag=244&keepalive=ye…2Cmm%2Cmn%2Cms%2Cmv%2Cpl%2Crequiressl%2Csc%2Csource%2Cexpire&mt=1498245944",
"type": "video/webm;+codecs=\"vp9\"",
"bitrate": "396541",
"index": "243-1933",
"size": "854x480",
"projection_type": "1",
"fps": "30",
"clen": "7928237",
"init": "0-242",
"quality_label": "480p"
},
"360p": {
"itag": "243",
"xtags": "",
"lmt": "1440215888783441",
"url": "https://r16---sn-n4v7kn7r.c.youtube.com/videoplayback?itag=243&keepalive=ye…2Cmm%2Cmn%2Cms%2Cmv%2Cpl%2Crequiressl%2Csc%2Csource%2Cexpire&mt=1498245944",
"type": "video/webm;+codecs=\"vp9\"",
"bitrate": "223695",
"index": "243-1933",
"size": "640x360",
"projection_type": "1",
"fps": "30",
"clen": "5127362",
"init": "0-242",
"quality_label": "360p"
},
"240p": {
"itag": "242",
"xtags": "",
"lmt": "1440215900971640",
"url": "https://r16---sn-n4v7kn7r.c.youtube.com/videoplayback?itag=242&keepalive=ye…2Cmm%2Cmn%2Cms%2Cmv%2Cpl%2Crequiressl%2Csc%2Csource%2Cexpire&mt=1498245944",
"type": "video/webm;+codecs=\"vp9\"",
"bitrate": "113952",
"index": "242-1931",
"size": "426x240",
"projection_type": "1",
"fps": "30",
"clen": "2597162",
"init": "0-241",
"quality_label": "240p"
},
"144p": {
"itag": "278",
"xtags": "",
"lmt": "1440215900119192",
"url": "https://r16---sn-n4v7kn7r.c.youtube.com/videoplayback?itag=278&keepalive=ye…2Cmm%2Cmn%2Cms%2Cmv%2Cpl%2Crequiressl%2Csc%2Csource%2Cexpire&mt=1498245944",
"type": "video/webm;+codecs=\"vp9\"",
"bitrate": "60303",
"index": "242-1930",
"size": "256x144",
"projection_type": "1",
"fps": "15",
"clen": "1798744",
"init": "0-241",
"quality_label": "144p"
},
"audio/mp4;+codecs=\"mp4a.40.2\"": {
"bitrate": "128266",
"itag": "140",
"xtags": "",
"lmt": "1440578358539132",
"index": "592-1271",
"clen": "8482615",
"projection_type": "1",
"url": "https://r16---sn-n4v7kn7r.c.youtube.com/videoplayback?itag=140&keepalive=ye…2Cmm%2Cmn%2Cms%2Cmv%2Cpl%2Crequiressl%2Csc%2Csource%2Cexpire&mt=1498245944",
"type": "audio/mp4;+codecs=\"mp4a.40.2\"",
"init": "0-591"
},
"audio/webm;+codecs=\"vorbis\"": {
"bitrate": "118499",
"itag": "171",
"xtags": "",
"lmt": "1440215938192462",
"index": "4452-5366",
"clen": "6383456",
"projection_type": "1",
"url": "https://r16---sn-n4v7kn7r.c.youtube.com/videoplayback?itag=171&keepalive=ye…2Cmm%2Cmn%2Cms%2Cmv%2Cpl%2Crequiressl%2Csc%2Csource%2Cexpire&mt=1498245944",
"type": "audio/webm;+codecs=\"vorbis\"",
"init": "0-4451"
},
"audio/webm;+codecs=\"opus\"": {
"bitrate": "154966",
"itag": "251",
"xtags": "",
"lmt": "1440215889283443",
"index": "272-1186",
"clen": "9526605",
"projection_type": "1",
"url": "https://r16---sn-n4v7kn7r.c.youtube.com/videoplayback?itag=251&keepalive=ye…2Cmm%2Cmn%2Cms%2Cmv%2Cpl%2Crequiressl%2Csc%2Csource%2Cexpire&mt=1498245944",
"type": "audio/webm;+codecs=\"opus\"",
"init": "0-271"
}
}
答案 1 :(得分:17)
截至今天15/06/2012非常简单;但是你必须注意未来的变化。 这是(在Javascript中)
try{
var urls = document.body.innerHTML.match(/"url_encoded_fmt_stream_map": "url=([^"]+)/)[1]
urls = decodeURIComponent(urls).replace(/\\u0026/g,'&')
urls = urls.replace(/&quality.+?(?=,url)/g,'');;
urls = urls.split(',url=')
// urls is an array of all the possible qualities
// To download one you could use something like:
// document.location = urls[0]
// The first one is usually in the highest quality available
} catch(e){
console.error("Youtube may have changed its API")
}
答案 2 :(得分:1)
你为什么要重新发明轮子?使用Rapidleech脚本!
顺便说一下,如果你还需要重新发明轮子,这里是Rapidleech的Youtube插件的源代码(它的可读性很高:
class youtube_com extends DownloadClass {
/*
Some blah blah about the age verification and erroneous URLs
$fmt is quality/format number and is an integer
*/
public function Download($link) {
$this->fmts = array(38,37,22,45,35,44,34,43,18,5,17);
$yt_fmt = empty($_REQUEST['yt_fmt']) ? '' : $_REQUEST['yt_fmt'];
$this->fmturlmaps = $this->GetVideosArr($fmt_url_maps);
if (empty($yt_fmt) && !isset($_GET["audl"])) return $this->QSelector($link);
elseif (isset($_REQUEST['ytube_mp4']) && $_REQUEST['ytube_mp4'] == 'on' && !empty($yt_fmt)) {
//look for and download the highest quality we can find?
if ($yt_fmt == 'highest') {
foreach ($this->fmts as $fmt) {
if (array_key_exists($fmt, $this->fmturlmaps)) {
$furl = $this->fmturlmaps[$fmt];
break;
}
}
} else { //get the format the user specified (making sure it actually exists)
if (!$furl = $this->fmturlmaps[$yt_fmt]) html_error ('Specified video format not found');
$fmt = $yt_fmt;
}
} else { //just get the one Youtube plays by default (in some cases it could also be the highest quality format)
$fmt = key($this->fmturlmaps);
$furl = $this->fmturlmaps[$fmt];
}
if (preg_match ('%^5|34|35$%', $fmt)) $ext = '.flv';
elseif (preg_match ('%^17$%', $fmt)) $ext = '.3gp';
elseif (preg_match ('%^18|22|37|38$%', $fmt)) $ext = '.mp4';
elseif (preg_match ('%^43|44|45$%', $fmt)) $ext = '.webm';
else $ext = '.flv';
if (!preg_match('#<title>(.*)\s+-\sYouTube[\r|\n|\t|\s]*</title>#Us', $this->page, $title)) html_error('No video title found! Download halted.');
if (!preg_match ('/video_id=(.+?)(\\\|"|&|(\\\u0026))/', $this->page, $video_id)) html_error('Video id not found.');
$FileName = str_replace (Array ("\\", "/", ":", "*", "?", "\"", "<", ">", "|"), "_", html_entity_decode(trim($title[1]), ENT_QUOTES)) . "-[{$video_id[1]}][f$fmt]$ext";
if (stristr($furl, '|')) {
$u_arr = explode('|', $furl);
$furl = preg_replace('#://([^/]+)#', "://".$u_arr[2], $u_arr[0]);
}
if (isset($_REQUEST['ytdirect']) && $_REQUEST['ytdirect'] == 'on')
{
echo "<br /><br /><h4><a style='color:yellow' href='" . urldecode($furl) . "'>Click here or copy the link to your download manager to download</a></h4>";
echo "<input name='dlurl' style='width: 1000px; border: 1px solid #55AAFF; background-color: #FFFFFF; padding:3px' value='" . urldecode($furl) . "' onclick='javascript:this.select();' readonly></input>";
}
else
{
$this->RedirectDownload (urldecode($furl), $FileName, $this->cookie, 0, 0, $FileName);
}
}