-
-
Save xissy/3812653 to your computer and use it in GitHub Desktop.
request = require 'request' | |
youTubeMovieInfo = | |
youTubeMovieId: 'videoId' | |
url = "http://www.youtube.com/get_video_info?video_id=#{youTubeMovieInfo.youTubeMovieId}" | |
request.get url, (err, res, body) -> | |
return callback(false) if err | |
return callback(false) if res.statusCode isnt 200 | |
formats = parseYoutubeInfoStringToFormats(body) | |
return callback(false) if formats is null | |
mp4StreamUrl = getMp4StreamUrlFromFormats(formats) | |
youTubeMovieInfo.mp4StreamUrl = mp4StreamUrl | |
# parse youtube api json response. | |
parseYoutubeInfoStringToFormats = (youtubeInfoString) -> | |
youtubeInfoArray = youtubeInfoString.split '&' | |
return null if youtubeInfoArray[0] is 'status=fail' | |
formatStreamArrayString = (element for element in youtubeInfoArray when element.split('=')[0] is 'url_encoded_fmt_stream_map')[0].split('=')[1] | |
formatStreamArray = decodeURIComponent(formatStreamArrayString).split(',') | |
formats = [] | |
for formatStreamString in formatStreamArray | |
formatInfoArray = formatStreamString.split '&' | |
formatInfoMap = {} | |
for formatInfoElement in formatInfoArray | |
formatInfoElementPair = formatInfoElement.split '=' | |
formatInfoMap[formatInfoElementPair[0]] = decodeURIComponent(formatInfoElementPair[1]) | |
formats.push formatInfoMap | |
return formats | |
# find mp4 stream url from parsed data. | |
getMp4StreamUrlFromFormats = (formats) -> | |
return format.url for format in formats when format.itag is '18' |
Thanks for the answer, but unfortunately getVideoInfo () not from anymore the results that you manage with your code, particularly the index "url_encoded_fmt_stream_map" it doesn't exist anymore, but it is necessary to intercept the index "player_response."
I attach you a code what works alone if is present the index 'url' , but unfortunately in the most greater part of the video Youtube the url is now drowned in the index "cipher", that I don't know whether to decipher.
for example the id: "QGV14x_8-eQ" directly returns an url downloadable, while the id "7cGWMlcAWq4" not!
Do You succeed there even?
This is the code
`<?PHP
//$id = "QGV14x_8-eQ";
$id = "7cGWMlcAWq4";
$data = youtube_info($id);
foreach($data[0] as $h => $v) echo ($h.":".$v."
");
function youtube_info($id)
{
$vformat = "video/mp4"; // The MIME type of the video. e.g. video/mp4, video/webm, etc.
$url = "http://youtube.com/get_video_info?video_id=".$id;
parse_str(file_get_contents($url),$info);
if (!array_key_exists('player_response',$info))
$div[0] = 'not found';
else
{ $videos = $info["player_response"];
$i = 0;
while ($i != 99)
{ $da = strpos($videos,'{"itag"')+1;
$per = strpos($videos,'}',$da) - $da;
$data = substr($videos,$da,$per);
if (strpos($data,$vformat) && strpos($data,'"quality"')) $itags [$i++] = $data;
$videos = substr($videos,$da + $per);
if ( !strpos($videos,'{"itag"') ) $i = 99;
}
$y = 0;
$c = count($itags); $i = 0;
while ($c--)
{ $itags[$i] = str_replace ('":' , ':' , $itags[$i] );
$itags[$i] = str_replace ('"itag' , 'itag' , $itags[$i] );
$array = explode(',"',$itags[$i++]);
$base = array();
foreach($array as $h => $v)
{ $d = strpos($array[$h],":");
$ch = substr($array[$h],0,$d);
$dt = substr($array[$h],$d+1);
if (substr($dt,0,1) == '"')
$dt = substr($dt,1,strlen($dt)-2);
$base[$ch] = str_replace("\\u0026","&",$dt);
}
if (!array_key_exists('url',$base))
{ parse_str($base["cipher"],$dturl);
foreach($dturl as $h => $v) echo ($h.":".$v."<br>");
$url = $dturl['url'].'&sig='.$dturl['s'];
}
$elem = array();
if (array_key_exists('url',$base))
{ $elem['url'] = $base['url']; $elem['dec'] = urldecode($base['url']); }
else
{ $elem['cipher'] = $base['cipher']; $elem['dec'] = urldecode($base['cipher']); }
$elem['itag'] = $base['itag'];
$elem['formato'] = 'mp4';
$elem['quality'] = $base['quality'];
$elem['dim'] = $base['qualityLabel'];
$div [$y++] = $elem;
}
}
return $div;
}
?>`
Thanks for the answer, but unfortunately getVideoInfo () not from anymore the results that you manage with your code, particularly the index "url_encoded_fmt_stream_map" it doesn't exist anymore, but it is necessary to intercept the index "player_response."
I attach you a code what works alone if is present the index 'url' , but unfortunately in the most greater part of the video Youtube the url is now drowned in the index "cipher", that I don't know whether to decipher.
for example the id: "QGV14x_8-eQ" directly returns an url downloadable, while the id "7cGWMlcAWq4" not!
Do You succeed there even?
This is the code
`<?PHP
//$id = "QGV14x_8-eQ";
$id = "7cGWMlcAWq4";
$data = youtube_info($id);
foreach($data[0] as $h => $v) echo ($h.":".$v."
");function youtube_info($id) { $vformat = "video/mp4"; // The MIME type of the video. e.g. video/mp4, video/webm, etc. $url = "http://youtube.com/get_video_info?video_id=".$id; parse_str(file_get_contents($url),$info); if (!array_key_exists('player_response',$info)) $div[0] = 'not found'; else { $videos = $info["player_response"]; $i = 0; while ($i != 99) { $da = strpos($videos,'{"itag"')+1; $per = strpos($videos,'}',$da) - $da; $data = substr($videos,$da,$per); if (strpos($data,$vformat) && strpos($data,'"quality"')) $itags [$i++] = $data; $videos = substr($videos,$da + $per); if ( !strpos($videos,'{"itag"') ) $i = 99; } $y = 0; $c = count($itags); $i = 0; while ($c--) { $itags[$i] = str_replace ('":' , ':' , $itags[$i] ); $itags[$i] = str_replace ('"itag' , 'itag' , $itags[$i] ); $array = explode(',"',$itags[$i++]); $base = array(); foreach($array as $h => $v) { $d = strpos($array[$h],":"); $ch = substr($array[$h],0,$d); $dt = substr($array[$h],$d+1); if (substr($dt,0,1) == '"') $dt = substr($dt,1,strlen($dt)-2); $base[$ch] = str_replace("\\u0026","&",$dt); } if (!array_key_exists('url',$base)) { parse_str($base["cipher"],$dturl); foreach($dturl as $h => $v) echo ($h.":".$v."<br>"); $url = $dturl['url'].'&sig='.$dturl['s']; } $elem = array(); if (array_key_exists('url',$base)) { $elem['url'] = $base['url']; $elem['dec'] = urldecode($base['url']); } else { $elem['cipher'] = $base['cipher']; $elem['dec'] = urldecode($base['cipher']); } $elem['itag'] = $base['itag']; $elem['formato'] = 'mp4'; $elem['quality'] = $base['quality']; $elem['dim'] = $base['qualityLabel']; $div [$y++] = $elem; } } return $div; }
?>`
@
Hello @JeanPaul3
Your PHP code works for me , but why for some YouTube videos, it is not returning MP4 URL ?
can you please help me with this ? Do you have any alternative solution for this ?
I need direct MP4 URL of YouTube video
New Method
change {videoid}
there are two of them.
New Method
change {videoid}
there are two of them.
Seems like as of this morning this method is no longer working
New Method
https://www.youtube.com/get_video_info?video_id={videoId}&eurl=https://youtube.googleapis.com/v/{videoId}&html5=1&c=TVHTML5&cver=6.20180913
change {videoid}
there are two of them.Seems like as of this morning this method is no longer working
Yes, It return 404 now. Unfortunately.
New Method not working. Sad.
I am facing same issue. anyone can help please.
try this one is working for me
echo getVideoInfo("op4B9sNGi0k");
`>function getVideoInfo($video_id){
$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://www.youtube.com/youtubei/v1/player?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, '{ "context": { "client": { "hl": "en", "clientName": "WEB", "clientVersion": "2.20210721.00.00", "clientFormFactor": "UNKNOWN_FORM_FACTOR", "clientScreen": "WATCH", "mainAppWebInfo": { "graftUrl": "/watch?v='.$video_id.'", } }, "user": { "lockedSafetyMode": false }, "request": { "useSsl": true, "internalExperimentFlags": [], "consistencyTokenJars": [] } }, "videoId": "'.$video_id.'", "playbackContext": { "contentPlaybackContext": { "vis": 0, "splay": false, "autoCaptionsDefaultOn": false, "autonavState": "STATE_NONE", "html5Preference": "HTML5_PREF_WANTS", "lactMilliseconds": "-1" } }, "racyCheckOk": false, "contentCheckOk": false}'); curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate'); $headers = array(); $headers[] = 'Content-Type: application/json'; curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $result = curl_exec($ch); if (curl_errno($ch)) { echo 'Error:' . curl_error($ch); } curl_close($ch); return $result;
}
`
try this one is working for me
echo getVideoInfo("op4B9sNGi0k");
`>function getVideoInfo($video_id){
$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://www.youtube.com/youtubei/v1/player?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, '{ "context": { "client": { "hl": "en", "clientName": "WEB", "clientVersion": "2.20210721.00.00", "clientFormFactor": "UNKNOWN_FORM_FACTOR", "clientScreen": "WATCH", "mainAppWebInfo": { "graftUrl": "/watch?v='.$video_id.'", } }, "user": { "lockedSafetyMode": false }, "request": { "useSsl": true, "internalExperimentFlags": [], "consistencyTokenJars": [] } }, "videoId": "'.$video_id.'", "playbackContext": { "contentPlaybackContext": { "vis": 0, "splay": false, "autoCaptionsDefaultOn": false, "autonavState": "STATE_NONE", "html5Preference": "HTML5_PREF_WANTS", "lactMilliseconds": "-1" } }, "racyCheckOk": false, "contentCheckOk": false}'); curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate'); $headers = array(); $headers[] = 'Content-Type: application/json'; curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $result = curl_exec($ch); if (curl_errno($ch)) { echo 'Error:' . curl_error($ch); } curl_close($ch); return $result;
}
`
how can i use this code in nodejs
Simplified
Method: POST
URL:
https://www.youtube.com/youtubei/v1/player?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8
Content Type:
JSON (application/json)
Content:
{
"context":{
"client":{
"hl":"en",
"clientName":"WEB",
"clientVersion":"2.20210721.00.00",
"clientFormFactor":"UNKNOWN_FORM_FACTOR",
"clientScreen":"WATCH",
"mainAppWebInfo":{
"graftUrl": "/watch?v={Video ID}"🛑
}
},
"user":{
"lockedSafetyMode":false
},
"request":{
"useSsl":true,
"internalExperimentFlags":[
],
"consistencyTokenJars":[
]
}
},
"videoId":"{Video ID}",🛑
"playbackContext":{
"contentPlaybackContext":{
"vis":0,
"splay":false,
"autoCaptionsDefaultOn":false,
"autonavState":"STATE_NONE",
"html5Preference":"HTML5_PREF_WANTS",
"lactMilliseconds":"-1"
}
},
"racyCheckOk":false,
"contentCheckOk":false
}
Change {Video ID}
Live Demo
how can i use this code in nodejs
I think it's better to use youtube-dl
on NodeJS.
Examples
const { getInfo } = require('ytdl-getinfo')
const youtube_video_id = "XxEhuSJF780"; // you can use full url too, https://www.youtube.com/watch?v=XxEhuSJF780
Method 1
getInfo( youtube_video_id ).then(info => {
// info.items[0] should contain the output of youtube-dl --dump-json
console.log( info.items[0] )
});
Method 2
getInfo( youtube_video_id, ['--dump-json'] ).then(info => {
console.log( info.items[0] )
});
References:
old ytInfoUrl += "www.youtube.com/get_video_info?video_id=" + videoID + "&eurl="
+ URLEncoder.encode("https://youtube.googleapis.com/v/" + videoID, "UTF-8")
+"&html5=1&c=TVHTML5&cver=6.20180913";
and i update new ytInfoUrl
ytInfoUrl += "www.youtube.com/get_video_info?video_id=" + videoID + "&eurl="
+ URLEncoder.encode("https://www.youtube.com/youtubei/v1/player?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8/" + videoID, "UTF-8")
+"&html5=1&c=TVHTML5&cver=6.20180913";
but still video not playing and showing the W/System.err: java.io.FileNotFoundException Error
@surajpendhare @thenandkishorkumawat
Your solution is working for me.
But, How can i parse response in node js.
const request = require('request');
const youtube_video_id = 'XxEhuSJF780'; // https://www.youtube.com/watch?v=XxEhuSJF780
var options = {
method: 'POST',
url: 'https://www.youtube.com/youtubei/v1/player?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8',
'headers': {
'Content-Type': 'application/json'
},
body: JSON.stringify({
"context": {
"client": {
"hl": "en",
"clientName": "WEB",
"clientVersion": "2.20210721.00.00",
"clientFormFactor": "UNKNOWN_FORM_FACTOR",
"clientScreen": "WATCH",
"mainAppWebInfo": {
"graftUrl": "/watch?v=" + youtube_video_id
}
},
"user": {
"lockedSafetyMode": false
},
"request": {
"useSsl": true,
"internalExperimentFlags": [
],
"consistencyTokenJars": [
]
}
},
"videoId": youtube_video_id,
"playbackContext": {
"contentPlaybackContext": {
"vis": 0,
"splay": false,
"autoCaptionsDefaultOn": false,
"autonavState": "STATE_NONE",
"html5Preference": "HTML5_PREF_WANTS",
"lactMilliseconds": "-1"
}
},
"racyCheckOk": false,
"contentCheckOk": false
})
};
request(options, function(error, response, body) {
if (error) throw new Error(error);
console.log(JSON.parse(body));
});
Simplified
Method:
POST
URL:
https://www.youtube.com/youtubei/v1/player?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8
Content Type:
JSON (application/json)
Content:
{ "context":{ "client":{ "hl":"en", "clientName":"WEB", "clientVersion":"2.20210721.00.00", "clientFormFactor":"UNKNOWN_FORM_FACTOR", "clientScreen":"WATCH", "mainAppWebInfo":{ "graftUrl": "/watch?v={Video ID}"🛑 } }, "user":{ "lockedSafetyMode":false }, "request":{ "useSsl":true, "internalExperimentFlags":[ ], "consistencyTokenJars":[ ] } }, "videoId":"{Video ID}",🛑 "playbackContext":{ "contentPlaybackContext":{ "vis":0, "splay":false, "autoCaptionsDefaultOn":false, "autonavState":"STATE_NONE", "html5Preference":"HTML5_PREF_WANTS", "lactMilliseconds":"-1" } }, "racyCheckOk":false, "contentCheckOk":false }Change
{Video ID}
Live Demo
from where is the key, what is thatclient, goodsolution, thanks
🙌 I used this method
URL :
Content Type :
JSON (application/json)
Content :
{
"context":{
"client":{
"hl":"en",
"clientName":"WEB",
"clientVersion":"2.20210721.00.00",
"clientFormFactor":"UNKNOWN_FORM_FACTOR",
"clientScreen":"WATCH",
"mainAppWebInfo":{
"graftUrl": "/watch?v={Video ID}" // <- Change here (Delete this comment)
}
},
"user":{
"lockedSafetyMode":false
},
"request":{
"useSsl":true,
"internalExperimentFlags":[
],
"consistencyTokenJars":[
]
}
},
"videoId":"{Video ID}", // <- Change here (Delete this comment)
"playbackContext":{
"contentPlaybackContext":{
"vis":0,
"splay":false,
"autoCaptionsDefaultOn":false,
"autonavState":"STATE_NONE",
"html5Preference":"HTML5_PREF_WANTS",
"lactMilliseconds":"-1"
}
},
"racyCheckOk":false,
"contentCheckOk":false
}
How do I return the MP4 URL for download using PHP? My function is below:
`function getVideoInfo($video_id){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://www.youtube.com/youtubei/v1/player?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{ "context": { "client": { "hl": "en", "clientName": "WEB", "clientVersion": "2.20210721.00.00", "clientFormFactor": "UNKNOWN_FORM_FACTOR", "clientScreen": "WATCH", "mainAppWebInfo": { "graftUrl": "/watch?v='.$video_id.'", } }, "user": { "lockedSafetyMode": false }, "request": { "useSsl": true, "internalExperimentFlags": [], "consistencyTokenJars": [] } }, "videoId": "'.$video_id.'", "playbackContext": { "contentPlaybackContext": { "vis": 0, "splay": false, "autoCaptionsDefaultOn": false, "autonavState": "STATE_NONE", "html5Preference": "HTML5_PREF_WANTS", "lactMilliseconds": "-1" } }, "racyCheckOk": false, "contentCheckOk": false}');
curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate');
$headers = array();
$headers[] = 'Content-Type: application/json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);
return $result;
}
$video_link = 'https://www.youtube.com/watch?v='.$vid;
preg_match('%(?:youtube(?:-nocookie)?.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu.be/)([^"&?/ ]{11})%i', $video_link, $match);
$video_id = $vid;
$video = json_decode(getVideoInfo($video_id));
$formats = $video->streamingData->formats;
$adaptiveFormats = $video->streamingData->adaptiveFormats;
$thumbnails = $video->videoDetails->thumbnail->thumbnails;
$title = $video->videoDetails->title;
$short_description = $video->videoDetails->shortDescription;
$thumbnail = end($thumbnails)->url;`
Hi
Do you know a similar code in php?
thanks