我想通过PHP从YouTube获得直接URL时出现签名问题

时间:2019-03-09 13:51:15

标签: php youtube youtube-api youtube-data-api

经过研究,我如何从类似这样的YouTube视频中获取直接网址: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("http://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 signature error YouTube API

更新:

gist.github

上的代码

任何解决方案?非常感谢

3 个答案:

答案 0 :(得分: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
?>

对于视频质量,您只能获得较低的质量,对于中等或HD质量,您可以分离出视频 AUDIO-LINK / VIDEO-LINK

答案 1 :(得分: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");

输出:

  

数组(       [错误] =>无法播放)

答案 2 :(得分:0)

Anass El Fakir's答案几乎被钉住了,只需要更改字符串即可爆炸。 如果我们使用原始帖子playabilityStatusadSafetyReason中的字符串。效果会更好(原始帖子)

<?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('playabilityStatus', 'adSafetyReason', $html);

    $json        = str_replace("\u0026", "&", $video_links);
    $json        = stripslashes('{"playabilityStatus' . $json . 'adSafetyReason":{"isEmbed":true}}');
    return $json;
}

function Explode_Content($first, $last, $string){
    $exp=explode($first,$string);
    $exp=explode($last,$exp[1]);
    return $exp[0];
}

// get video info in JSON format
$video_info = YT_V_INFO($_GET['id']); // Add Youtube Video ID
echo $video_info;

?>