当我想通过 PHP 从 YouTube 获取直接 URL 时的签名问题
Posted
技术标签:
【中文标题】当我想通过 PHP 从 YouTube 获取直接 URL 时的签名问题【英文标题】:signature issue when I want to get a direct URL from YouTube via PHP 【发布时间】:2019-07-31 08:38:45 【问题描述】:在研究了我如何从 YouTube 视频中获取直接 URL 后,询问:How to get direct URL of video from YouTube URL? [closed]
我终于制作了一个简单的脚本,用 php 从 YouTube 视频生成直接 URL 它工作得很好,但不适用于所有视频
它不适用于“签名”视频,
这是我的代码:
if(isset($_GET['url']) && $_GET['url'] != "")
parse_str( parse_url( $_GET['url'], PHP_URL_QUERY ), $vars );
$id=$vars['v'];
$dt=file_get_contents("https://www.youtube.com/get_video_info?video_id=$id&el=embedded&ps=default&eurl=&gl=US&hl=en");
//var_dump(explode("&",$dt));
if (strpos($dt, 'status=fail') !== false)
$x=explode("&",$dt);
$t=array(); $g=array(); $h=array();
foreach($x as $r)
$c=explode("=",$r);
$n=$c[0]; $v=$c[1];
$y=urldecode($v);
$t[$n]=$v;
$x=explode("&",$dt);
foreach($x as $r)
$c=explode("=",$r);
$n=$c[0]; $v=$c[1];
$h[$n]=urldecode($v);
$g[]=$h;
$g[0]['error'] = true;
$g[0]['instagram'] = "egy.js";
$g[0]['apiMadeBy'] = 'El-zahaby';
echo json_encode($g,JSON_PRETTY_PRINT);
else
$x=explode("&",$dt);
$t=array(); $g=array(); $h=array();
foreach($x as $r)
$c=explode("=",$r);
$n=$c[0]; $v=$c[1];
$y=urldecode($v);
$t[$n]=$v;
$streams = explode(',',urldecode($t['url_encoded_fmt_stream_map']));
foreach($streams as $dt)
$x=explode("&",$dt);
foreach($x as $r)
$c=explode("=",$r);
$n=$c[0]; $v=$c[1];
$h[$n]=urldecode($v);
$g[]=$h;
echo json_encode($g,JSON_PRETTY_PRINT);
// var_dump( $g[1]["quality"],true);
else
@$myObj->error = true;
$myObj->msg = "there is no youtube link";
$myObj->madeBy = "El-zahaby";
$myObj->instagram = "egy.js";
$myJSON = json_encode($myObj,JSON_PRETTY_PRINT);
echo $myJSON;
问题示例:https://you-link.herokuapp.com/?url=yt.com?v=csy7cF1T2vk
更新:
代码在:gist.github
任何解决方案?非常感谢
【问题讨论】:
嗨@a-el-zahaby 你是怎么解决这个问题的?我想要来自 YouTube 网址的 MP4 网址,有什么建议吗? 【参考方案1】:这是从 youtube get_video_info
获取每个视频质量的另一个代码<?php
function YT_IN_DX($url)
$cookie_file_path = "cookies.txt";
$agent = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:43.0) Gecko/20100101 Firefox/46.0";
$ch = curl_init();
$headers[] = "Connection: Keep-Alive";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_USERAGENT, $agent);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file_path);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file_path);
curl_setopt($ch, CURLOPT_URL, $url);
$res = curl_exec($ch);
curl_close($ch);
return $res;
function YT_V_INFO($v)
$url = "https://www.youtube.com/get_video_info?video_id=$v";
$html = urldecode(YT_IN_DX($url));
$video_links = Explode_Content('playabilityStatus', 'adSafetyReason', $html);
$json = str_replace("\u0026", "&", $video_links);
$json = '"playabilityStatus' . $json . 'adSafetyReason":"isEmbed":true';
$array = json_decode($json, true);
if (isset($array["playabilityStatus"]["status"]) && $array["playabilityStatus"]["status"] == "UNPLAYABLE")
$data = array("error" => $array["playabilityStatus"]["status"]);
else
$formats = $array["streamingData"]["formats"];
for ($a = 0; $a <= (count($formats) - 1); $a++)
$data[] = array(
"url" => $array["streamingData"]["formats"][$a]["url"],
"mimeType" => $array["streamingData"]["formats"][$a]["mimeType"],
"quality" => $array["streamingData"]["formats"][$a]["quality"],
"qualityLabel" => $array["streamingData"]["formats"][$a]["qualityLabel"],
"width" => $array["streamingData"]["formats"][$a]["width"],
"height" => $array["streamingData"]["formats"][$a]["height"],
"audioQuality" => $array["streamingData"]["formats"][$a]["audioQuality"],
"approxDurationMs" => $array["streamingData"]["formats"][0]["approxDurationMs"]
);
return $data;
function Explode_Content($first, $last, $string)
$exp = explode($first, $string);
$exp = explode($last, $exp[1]);
return $exp[0];
$videoinfo = YT_V_INFO("6chhghoMGVQ");
// $videoinfo=YT_V_INFO("sJsoyuQAepQ");
print_r($videoinfo);
?>
如果所有者不允许,使用此方法您无法获取某些视频 ID 数据。 这是两个例子:
$videoinfo = YT_V_INFO("6chhghoMGVQ");
输出:
Array
(
[0] => Array
(
[url] => https://r4---sn-p5h-gc5d.googlevideo.com/videoplayback?id=e9c861821a0c1954&itag=18&source=youtube&requiressl=yes&mm=31,26&mn=sn-p5h-gc5d,sn-hpa7znsd&ms=au,onr&mv=m&pl=21&ei=fmWRXLGxLIKZ1wb61YyIBQ&susc=yt&initcwndbps=232500&mime=video/mp4&gir=yes&clen=13861924&ratebypass=yes&dur=276.271&lmt=1448537568788216&mt=1553032481&fvip=4&c=WEB&ip=196.64.208.187&ipbits=0&expire=1553054174&sparams=ip,ipbits,expire,id,itag,source,requiressl,mm,mn,ms,mv,pl,ei,susc,initcwndbps,mime,gir,clen,ratebypass,dur,lmt&signature=E2DEC9FF027D3810BF4309AD81E1C22E51BDA8F8.DCA10F844A294D5D267F518DBF0951B757855D2B&key=yt8
[mimeType] => video/mp4; codecs="avc1.42001E, mp4a.40.2"
[quality] => medium
[qualityLabel] => 360p
[width] => 640
[height] => 360
[audioQuality] => AUDIO_QUALITY_LOW
[approxDurationMs] => 276271
)
[1] => Array
(
[url] => https://r4---sn-p5h-gc5d.googlevideo.com/videoplayback?id=e9c861821a0c1954&itag=22&source=youtube&requiressl=yes&mm=31,26&mn=sn-p5h-gc5d,sn-hpa7znsd&ms=au,onr&mv=m&pl=21&ei=fmWRXLGxLIKZ1wb61YyIBQ&susc=yt&initcwndbps=232500&mime=video/mp4&ratebypass=yes&dur=276.271&lmt=1470942139723144&mt=1553032481&fvip=4&c=WEB&ip=196.64.208.187&ipbits=0&expire=1553054174&sparams=ip,ipbits,expire,id,itag,source,requiressl,mm,mn,ms,mv,pl,ei,susc,initcwndbps,mime,ratebypass,dur,lmt&signature=B99844F18562D76976B29A1E6358A3C6D6A0DA78.CD747441B3C6883D3639B584BDACC4023C0A9082&key=yt8
[mimeType] => video/mp4; codecs="avc1.64001F, mp4a.40.2"
[quality] => hd720
[qualityLabel] => 720p
[width] => 1280
[height] => 720
[audioQuality] => AUDIO_QUALITY_MEDIUM
[approxDurationMs] => 276271
)
[2] => Array
(
[url] => https://r4---sn-p5h-gc5d.googlevideo.com/videoplayback?id=e9c861821a0c1954&itag=43&source=youtube&requiressl=yes&mm=31,26&mn=sn-p5h-gc5d,sn-hpa7znsd&ms=au,onr&mv=m&pl=21&ei=fmWRXLGxLIKZ1wb61YyIBQ&susc=yt&initcwndbps=232500&mime=video/webm&gir=yes&clen=16923548&ratebypass=yes&dur=0.000&lmt=1448363037942780&mt=1553032481&fvip=4&c=WEB&ip=196.64.208.187&ipbits=0&expire=1553054174&sparams=ip,ipbits,expire,id,itag,source,requiressl,mm,mn,ms,mv,pl,ei,susc,initcwndbps,mime,gir,clen,ratebypass,dur,lmt&signature=B477F9D1D7A34ECFAF8C7CDBC94A46B365633A26.DEC0E30537E6DE02FD960E515CC5DDB4CFEFC65C&key=yt8
[mimeType] => video/webm; codecs="vp8.0, vorbis"
[quality] => medium
[qualityLabel] => 360p
[width] => 640
[height] => 360
[audioQuality] => AUDIO_QUALITY_MEDIUM
[approxDurationMs] => 276271
)
)
这是他的所有者不允许的另一个视频 ID。
$videoinfo=YT_V_INFO("sJsoyuQAepQ");
输出:
数组 ( [错误] => 无法播放)
【讨论】:
如果这正是您想要的,请接受答案 (A. El-zahaby)。 当我尝试访问该 URL 时收到 403。 不工作了 :( ,,但是我的旧代码还在工作【参考方案2】:这是我基于最新的 Youtube 网站更新 (2019) 的解决方案。
<?php
function YT_IN_DX($url)
$cookie_file_path = "cookies.txt";
$agent = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:43.0) Gecko/20100101 Firefox/46.0";
$ch = curl_init();
$headers[] = "Connection: Keep-Alive";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_USERAGENT, $agent);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file_path);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file_path);
curl_setopt($ch, CURLOPT_URL, $url);
$res = curl_exec($ch);
curl_close($ch);
return $res;
function YT_V_INFO($v)
$url="https://www.youtube.com/watch?v=$v";
$html=YT_IN_DX($url);
$video_links=Explode_Content('ytplayer.config = ', ';ytplayer.load', $html);
$jsondownload1=json_decode($video_links, true);
$json_str=$jsondownload1["args"]["player_response"];
$jsn_str=str_replace("\u0026","&",$json_str);
$streamin_data_json=json_decode($jsn_str, true);
$videolink=$streamin_data_json["streamingData"]["formats"][0]["url"];
return $videolink;
function Explode_Content($first, $last, $string)
$exp=explode($first,$string);
$exp=explode($last,$exp[1]);
return $exp[0];
// Include these functions at the top.
// Get direct url from Youtube with two lines
$videolink = YT_V_INFO("6chhghoMGVQ"); // Add Youtube Video ID
echo $videolink; // Your download link
?>
对于视频质量,您只能获得低质量,对于中等或高清质量,您可以获得分离的视频AUDIO-LINK / VIDEO-LINK。 p>
【讨论】:
能否请您通过添加// comment on the lines
来解释此代码
您好,请先告诉我代码是否适合您?
是的,它有效,但我希望获得所有品质
你可以得到其他品质但分开的AUDIO-LINK / VIDEO-LINK,所以如果你愿意,我为你完成代码
@AnassElFakir 嗨,我正在尝试本地设置中的 php 函数,但 $videolink 返回为空?它还应该工作吗??以上是关于当我想通过 PHP 从 YouTube 获取直接 URL 时的签名问题的主要内容,如果未能解决你的问题,请参考以下文章
截至 2012 年 11 月,通过 json 和 php 获取 youtube 数据的正确语法是啥?
我需要一些帮助来纠正我在 php 中的代码 - 如何从 YouTube URL 获取视频 ID [重复]