4

I'm from bangladesh. i have an youtube downloader php script but its not work some videos to download. when i click download button, its download videoplayback and showing me text Failed - Forbidden.

I can't download same as below videos. Most of video not downloaded.

Download website is: http://mcv12.masudtools.xyz/

Such as this video:

https://www.youtube.com/watch?v=DL5-XssXkxo

Also i have error log:

[13-Jul-2017 12:51:44 UTC] PHP Notice: Undefined index: adaptive_fmts in /home/masudtoo/public_html/mcv12/VideoYoutubeProvider.php on line 126 [13-Jul-2017 12:51:45 UTC] PHP Notice: Undefined index: type in /home/masudtoo/public_html/mcv12/VideoYoutubeProvider.php on line 85 [13-Jul-2017 12:51:45 UTC] PHP Notice: Undefined offset: 1 in /home/masudtoo/public_html/mcv12/VideoYoutubeProvider.php on line 88

126 line is:

$adaptive_fmts = $this->fullInfo['adaptive_fmts'];

85 line is:

$type = explode(';', $item['type']);

88 line is:

$ext = $baseType[1];

full VideoYoutubeProvider.php code:

class VideoYoutubeProvider extends VideoAbstractProvider
{

public $fullInfo = null;

/**
 * Get provider name
 * @return string
 */
public function getProviderName()
{
    return "Youtube video";
}

/**
 * Checks video url for belonging to this provider
 *
 * @param string $url video url for check
 * @return boolean returning true if service available this video url
 */
static public function checkUrl($url)
{
    return !!preg_match("/^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/i", $url);
}

/**
 * Return base video information
 *
 * @return BaseVideoInfo
 * @throws VideoDownloaderBaseInfoException
 */
public function getBaseInfo()
{
    $fullInfo = $this->getFullInfo();
    $baseInfo = new BaseVideoInfo();
    $baseInfo->name = $fullInfo['title'];
    $videoId = $fullInfo['video_id'];
    $preview = new VideoPreviewUrl();
    $preview->width = 1280;
    $preview->height = 720;
    $preview->name = 'maxresdefault';
    $preview->url = "https://img.youtube.com/vi/$videoId/hqdefault.jpg";
    $baseInfo->previewUrls = [$preview];
    $baseInfo->mainPreviewUrl = $preview;
    $html = $fullInfo['html'];
    if (preg_match('/<p id="eow-description"[^>]+>(.+)<\/p>/', $html, $matches)) {
        $baseInfo->description = strip_tags(str_replace('<br />', "\n", $matches[1]));
    }
    return $baseInfo;
}

/**
 * Return array of download information for video
 *
 * @return VideoDownloadInfo[]
 * @throws VideoDownloaderDownloadException
 */
public function getDownloadsInfo()
{
    $fullInfo = $this->getFullInfo();
    $fmts = $fullInfo['url_encoded_fmt_stream_map'];
    $downloadsInfo = [];
    $title = $fullInfo['title'];
    foreach ($fmts AS $item) {
        $url = $item['url'] . '&title=' . urlencode($title);
        $headers = RequestHelper::getResponseHeaders($url);
        $downloadInfo = new VideoDownloadInfo();
        $downloadInfo->fileSize = (int)$headers['Content-Length'];
        $downloadInfo->url = $url;
        $downloadInfo->fileType = $headers['Content-Type'];
        $ext = explode('/', $downloadInfo->fileType);
        $ext = $ext[1];
        $downloadInfo->name = $title . '.' . $ext;
        $downloadsInfo[] = $downloadInfo;
    }
    $fmts = $fullInfo['adaptive_fmts'];
    foreach ($fmts AS $item) {
        $type = explode(';', $item['type']);
        $type = $type[0];
        $baseType = explode('/', $type);
        $ext = $baseType[1];
        $baseType = $baseType[0];
        if ($baseType === 'audio') {
            $downloadInfo = new VideoDownloadInfo();
            $downloadInfo->fileSize = (int)$item['clen'];
            $downloadInfo->name = $title . '.' . $ext;
            $url = $item['url'] . '&title=' . urlencode($title);
            $downloadInfo->url = $url;
            $downloadInfo->fileType = $type;
            $downloadsInfo[] = $downloadInfo;
            break;
        }
    }
    return $downloadsInfo;
}


private function getFullInfo()
{
    if (is_null($this->fullInfo)) { 
        preg_match("/^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/i", $this->url, $matches);
        $videoId = $matches[7];
        $fullInfoSource = file_get_contents("http://www.youtube.com/get_video_info?&video_id=$videoId&asv=3&el=detailpage&hl=en_US");
        $fullInfoSource = explode('&', $fullInfoSource);
        $this->fullInfo = [];
        foreach ($fullInfoSource AS $item) {
            $item = explode('=', $item);
            $this->fullInfo[$item[0]] = urldecode($item[1]);
        }
        $url_encoded_fmt_stream_map = $this->fullInfo['url_encoded_fmt_stream_map'];
        $url_encoded_fmt_stream_map = explode(',', $url_encoded_fmt_stream_map);
        $this->fullInfo['url_encoded_fmt_stream_map'] = [];
        foreach ($url_encoded_fmt_stream_map AS $downloadItem) {
            $downloadInfo = [];
            parse_str($downloadItem, $downloadInfo);
            $this->fullInfo['url_encoded_fmt_stream_map'][] = $downloadInfo;
        }

        $adaptive_fmts = $this->fullInfo['adaptive_fmts'];
        $adaptive_fmts = explode(',', $adaptive_fmts);
        $this->fullInfo['adaptive_fmts'] = [];
        foreach ($adaptive_fmts AS $item) {
            $itemInfo = [];
            parse_str($item, $itemInfo);
            $this->fullInfo['adaptive_fmts'][] = $itemInfo;
        }

        $this->fullInfo['html'] = file_get_contents("https://www.youtube.com/watch?v=$videoId");
        $this->fullInfo['video_id'] = $videoId;
    }
    return $this->fullInfo;
}
}

Please help me to solve it. thanks

Masud Rana
  • 51
  • 8
  • Possible duplicate of [How can I write a PHP script to download YouTube videos?](https://stackoverflow.com/questions/1620806/how-can-i-write-a-php-script-to-download-youtube-videos) – Bestter Jul 13 '17 at 14:42
  • My problem is download Failed - Forbidden – Masud Rana Jul 13 '17 at 15:22
  • i edited/added website url on post, try your self please – Masud Rana Jul 13 '17 at 15:32
  • Hi and welcome to Stack Overflow, please read how to create a [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve) and also check [How to Ask Good Questions](https://stackoverflow.com/help/how-to-ask) so you increase your chances to get feedback and useful answers. – DarkCygnus Jul 13 '17 at 17:08

2 Answers2

2

Try this to get Youtube Video source from only youtube video id

    // Get Youtube Source
function getYoutubeVideoSource1($id = 'jNQXAC9IVRw'){
    parse_str(file_get_contents("http://youtube.com/get_video_info?video_id=".$id),$info);
    $streams = $info['url_encoded_fmt_stream_map'];
    $streams = explode(',',$streams);
    //dd($streams);
    // store value in array
    $video_stream = array();
    foreach ($streams as $stream){
        parse_str($stream,$data);
        $data = array(
            'type' => $data['type'],
            'quality' => $data['quality'],
            'url' => $data['url'],
        );
        $video_stream[] = (object) $data;
    }
    print_r($video_stream);

    //return $video_stream;
}

Here you will get an array of video steam.

   array:4 [▼
  0 => {#216 ▼
    +"type": "video/webm; codecs="vp8.0, vorbis""
    +"quality": "medium"
    +"url": "https://r3---sn-ugp5obax-q5je.googlevideo.com/videoplayback?ipbits=0&ei=qC_9Wa3HD9rcogOXgZuAAw&lmt=1380226535526270&expire=1509786632&sparams=clen%2Cdur%2Cei%2C ▶"
  }
  1 => {#211 ▶}
  2 => {#212 ▶}
  3 => {#218 ▶}
]

Now you can get video link like this

// Get Youtube Batch Download link
function youtubeBatchDownloadLink($videoId, $format){
    $video_source = getYoutubeVideoSource ($videoId);
    $url = $video_source[$format]->url;
    print_r($url);
    //return $url;
}

Hope this will help you

Shapon Pal
  • 1,098
  • 3
  • 16
  • 27
1

Since the latest response is out of date with the current results from youtube, I'd like to post an update. For anyone using the above code url_encoded_fmt_stream_map throws errors because YouTube changed the value of that parameter to player_response.

The code below will output a JSON object containing the YouTube video source urls.

<?php
/*
YouTubeLinkSourcer
by digitallysavvy
based on code by [egy.js](https://www.instagram.com/egy.js/);
v0.1
*/
header('Access-Control-Allow-Origin: *');
header('Content-Type: application/json');


function get_error($ErrorExaction){
    $myObj = new stdClass();
    $myObj->error = true;
    $myObj->msg = $ErrorExaction;

    $myJSON = json_encode($myObj,JSON_PRETTY_PRINT);
    echo $myJSON;
    exit;
}

// pass youtube url via param
if(isset($_GET['ytURL']) && $_GET['ytURL'] != "") {
    // parse the url param to split the string
    parse_str( parse_url( $_GET['ytURL'], PHP_URL_QUERY ), $vars );
    $id = $vars['v']; // get the video id from the v query param 
    $dt = file_get_contents("https://www.youtube.com/get_video_info?video_id=$id&el=embedded&ps=default&eurl=&gl=US&hl=en");
    
    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;
        echo json_encode($g,JSON_PRETTY_PRINT);

    } else {
        // decode the response
        $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;
        }
        // get the "player_response" field and parse it as JSON
        $player_response = json_decode(urldecode($t['player_response']), true);
        
        // if response is missing streaming data - show an error and exit
        if(!array_key_exists("streamingData",$player_response)){ 
          get_error('ops! this video has something wrong! :( '); 
        }
        // get reference to the streaming data object
        $streams = $player_response["streamingData"]; 
        // loop through the list and print out all formats
        echo "{ \"formats\": [";
        foreach ($streams["formats"] as $formats) {
          echo "{ \"". $formats["qualityLabel"] ."\": \"". $formats["url"] ."\" },";
        }
        echo "], \"adaptiveFormats\": [";
        foreach ($streams["adaptiveFormats"] as $adaptiveFormats) {
            if(array_key_exists("qualityLabel",$adaptiveFormats)){ 
                echo "{ \"". $adaptiveFormats["qualityLabel"] ."\": \"". $adaptiveFormats["url"] ."\" },";
            } else {
                break; // end the loop
            }
        }
        echo "]}";
    }
} else {
     get_error("Ops, there is no youtube link!");
}

call this script using:

/YouTubeSourcer.php?ytURL=https://www.youtube.com/watch?v=nMAzchVWTis
Hermes
  • 2,828
  • 2
  • 14
  • 34
  • According to Youtube's [DTOS](https://developers.google.com/youtube/terms/developer-policies), scrapping Youtube's site is forbidden: **Scraping:** *You and your API Clients must not, and must not encourage, enable, or require others to, directly or indirectly, scrape YouTube Applications or Google Applications, or obtain scraped YouTube data or content. Public search engines may scrape data only in accordance with YouTube's robots.txt file or with YouTube's prior written permission.* Thus, I deem your solution unfitted for this forum. Please be kind to reconsider your post. – stvar Jun 25 '20 at 11:44