Вход Регистрация
Файл: _system/class/YoutubeDownloader.php
Строк: 276
<?
###################################################
#     BY MAKSAMKA (Mr.MAX) ICQ 154-26-36          #
#       Поиск видео > API v3 Youtube              #
#      Версия сборки V.2.0                        #
###################################################


class YoutubeDownloader
{
    protected 
$url;
    protected 
$fullInfo;

    public function 
__construct($url)
    {
        
$this->url $url;
    }

    public function 
getFullInfo()
    {
        if (
is_null($this->fullInfo)) {
            
preg_match("/^.*((youtu.be/)|(v/)|(/u/w/)|(embed/)|(watch?))??v?=?([^#&?]*).*/i"$this->url$matches);
            
$videoId $matches[7];
            
$clearContent file_get_contents("https://www.youtube.com/watch?v=$videoId");
            
preg_match('/ytplayer.config = ({.+});ytplayer/'$clearContent$mathes);
            
$configData json_decode($mathes[1], true);
            
$streamList explode(','$configData['args']['url_encoded_fmt_stream_map']);
            
$configData['args']['url_encoded_fmt_stream_map'] = array();
            foreach (
$streamList AS $stream) {
                
parse_str($stream$res);
                
$configData['args']['url_encoded_fmt_stream_map'][] = $res;
            }
            
$streamList explode(','$configData['args']['adaptive_fmts']);
            
$configData['args']['adaptive_fmts'] = array();
            foreach (
$streamList AS $stream) {
                
parse_str($stream$res);
                
$configData['args']['adaptive_fmts'][] = $res;
            }

            
$this->fullInfo $configData['args'];
            
$this->fullInfo['html'] = $clearContent;
            
$this->fullInfo['video_id'] = $videoId;
            
$jsPath $configData['assets']['js'];
            
$jsPlayerClear file_get_contents('https://www.youtube.com' $jsPath);
            
preg_match('/set("signature",s*(?:([^(]*).*))/'$jsPlayerClear$mathes);
            
$signParserFnName $mathes[1];
            
preg_match("/$signParserFnName=(function(.+;)/"$jsPlayerClear$mathes);
            
$signFnBody $mathes[1];
            
preg_match("/(w+).w+([wd,]+)/"$signFnBody$mathes);
            
$helperObjName $mathes[1];
            
preg_match_all("/$helperObjName.(w+)(w+,(d+));/"$signFnBody$matches);
            
$startPos strpos($jsPlayerClear"$helperObjName={");
            
$calcRule = array();
            foreach (
$matches[1] AS $i => $fnName) {
                
$calcRule[] = array(
                    
'function' => $fnName,
                    
'param' => $matches[2][$i],
                );
            }
            
$endPos $startPos strlen($helperObjName) + 2;
            
$startPos += strlen($helperObjName) + 1;
            
$countOpenBraces 1;
            while (
$countOpenBraces 0) {
                
$char substr($jsPlayerClear$endPos1);
                
$endPos++;
                if (
$char == '{') {
                    
$countOpenBraces++;
                } elseif (
$char == '}') {
                    
$countOpenBraces--;
                }
            }
            
$helperObjBody substr($jsPlayerClear$startPos$endPos $startPos);
            
preg_match_all('/(w+):function([w,]+){([^}]+)}/'$helperObjBody$matches);
            
$calcFunctions = array();
            foreach (
$matches[1] AS $i => $fnName) {
                
$fnBody $matches[2][$i];
                if (
strpos($fnBody'reverse') !== false) {
                    
$calcFunctions[$fnName] = 'reverse';
                    continue;
                }
                if (
strpos($fnBody'splice') !== false) {
                    
$calcFunctions[$fnName] = 'splice';
                    continue;
                }
                
$calcFunctions[$fnName] = 'swap';
            }
            foreach (
$calcRule AS &$calcItem) {
                
$calcItem['function'] = $calcFunctions[$calcItem['function']];
            }
            
$this->fullInfo['calcSignatureSteps'] = $calcRule;
            
$calcSignExpression = <<<JS
    function calculateSignature(sign){
        var __HELPER_OBJ_NAME = __HELPER_OBJ_BODY__;
        var calcSign = __SIGN_FN_BODY__;
        return calcSign(sign);
    }
JS;
            
$calcSignExpression str_replace('__HELPER_OBJ_NAME'$helperObjName$calcSignExpression);
            
$calcSignExpression str_replace('__HELPER_OBJ_BODY__'$helperObjBody$calcSignExpression);
            
$calcSignExpression str_replace('__SIGN_FN_BODY__'$signFnBody$calcSignExpression);

            
$this->fullInfo['jsSignatureGen'] = $calcSignExpression;

        }
        return 
$this->fullInfo;
    }

    public function 
getBaseInfo()
    {
        
$fullInfo $this->getFullInfo();
        
$baseInfo = array();
        
$baseInfo['name'] = $fullInfo['title'];
        
$videoId $fullInfo['video_id'];
        
$baseInfo['previewUrl'] = "https://img.youtube.com/vi/$videoId/hqdefault.jpg";
        
$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;
    }

    public static function 
getItagInfo()
    {
        return array(
            
=> array('format' => 'flv''withVideo' => true'withAudio' => true),
            
=> array('format' => 'flv''withVideo' => true'withAudio' => true),
            
13 => array('format' => '3gp''withVideo' => true'withAudio' => true),
            
17 => array('format' => '3gp''withVideo' => true'withAudio' => true),
            
18 => array('format' => 'mp4''withVideo' => true'withAudio' => true),
            
22 => array('format' => 'mp4''withVideo' => true'withAudio' => true),
            
34 => array('format' => 'flv''withVideo' => true'withAudio' => true),
            
35 => array('format' => 'flv''withVideo' => true'withAudio' => true),
            
36 => array('format' => '3gp''withVideo' => true'withAudio' => true),
            
37 => array('format' => 'mp4''withVideo' => true'withAudio' => true),
            
38 => array('format' => 'mp4''withVideo' => true'withAudio' => true),
            
43 => array('format' => 'webm''withVideo' => true'withAudio' => true),
            
44 => array('format' => 'webm''withVideo' => true'withAudio' => true),
            
45 => array('format' => 'webm''withVideo' => true'withAudio' => true),
            
46 => array('format' => 'webm''withVideo' => true'withAudio' => true),
            
82 => array('format' => 'mp4''withVideo' => true'withAudio' => true),
            
83 => array('format' => 'mp4''withVideo' => true'withAudio' => true),
            
84 => array('format' => 'mp4''withVideo' => true'withAudio' => true),
            
85 => array('format' => 'mp4''withVideo' => true'withAudio' => true),
            
100 => array('format' => 'webm''withVideo' => true'withAudio' => true),
            
101 => array('format' => 'webm''withVideo' => true'withAudio' => true),
            
102 => array('format' => 'webm''withVideo' => true'withAudio' => true),
            
92 => array('format' => 'mp4''withVideo' => true'withAudio' => true),
            
93 => array('format' => 'mp4''withVideo' => true'withAudio' => true),
            
94 => array('format' => 'mp4''withVideo' => true'withAudio' => true),
            
95 => array('format' => 'mp4''withVideo' => true'withAudio' => true),
            
96 => array('format' => 'mp4''withVideo' => true'withAudio' => true),
            
132 => array('format' => 'mp4''withVideo' => true'withAudio' => true),
            
151 => array('format' => 'mp4''withVideo' => true'withAudio' => true),
            
133 => array('format' => 'mp4''withVideo' => true'withAudio' => false),
            
134 => array('format' => 'mp4''withVideo' => true'withAudio' => false),
            
135 => array('format' => 'mp4''withVideo' => true'withAudio' => false),
            
136 => array('format' => 'mp4''withVideo' => true'withAudio' => false),
            
137 => array('format' => 'mp4''withVideo' => true'withAudio' => false),
            
138 => array('format' => 'mp4''withVideo' => true'withAudio' => false),
            
160 => array('format' => 'mp4''withVideo' => true'withAudio' => false),
            
264 => array('format' => 'mp4''withVideo' => true'withAudio' => false),
            
298 => array('format' => 'mp4''withVideo' => true'withAudio' => false),
            
299 => array('format' => 'mp4''withVideo' => true'withAudio' => false),
            
266 => array('format' => 'mp4''withVideo' => true'withAudio' => false),
            
139 => array('format' => 'm4a''withVideo' => false'withAudio' => true),
            
140 => array('format' => 'm4a''withVideo' => false'withAudio' => true),
            
141 => array('format' => 'm4a''withVideo' => false'withAudio' => true),
            
167 => array('format' => 'webm''withVideo' => true'withAudio' => false),
            
168 => array('format' => 'webm''withVideo' => true'withAudio' => false),
            
169 => array('format' => 'webm''withVideo' => true'withAudio' => false),
            
170 => array('format' => 'webm''withVideo' => true'withAudio' => false),
            
218 => array('format' => 'webm''withVideo' => true'withAudio' => false),
            
219 => array('format' => 'webm''withVideo' => true'withAudio' => false),
            
242 => array('format' => 'webm''withVideo' => true'withAudio' => false),
            
243 => array('format' => 'webm''withVideo' => true'withAudio' => false),
            
244 => array('format' => 'webm''withVideo' => true'withAudio' => false),
            
245 => array('format' => 'webm''withVideo' => true'withAudio' => false),
            
246 => array('format' => 'webm''withVideo' => true'withAudio' => false),
            
247 => array('format' => 'webm''withVideo' => true'withAudio' => false),
            
248 => array('format' => 'webm''withVideo' => true'withAudio' => false),
            
271 => array('format' => 'webm''withVideo' => true'withAudio' => false),
            
272 => array('format' => 'webm''withVideo' => true'withAudio' => false),
            
302 => array('format' => 'webm''withVideo' => true'withAudio' => false),
            
303 => array('format' => 'webm''withVideo' => true'withAudio' => false),
            
308 => array('format' => 'webm''withVideo' => true'withAudio' => false),
            
313 => array('format' => 'webm''withVideo' => true'withAudio' => false),
            
315 => array('format' => 'webm''withVideo' => true'withAudio' => false),
            
171 => array('format' => 'webm''withVideo' => false'withAudio' => true),
            
172 => array('format' => 'webm''withVideo' => false'withAudio' => true),
        );
    }

    static protected function 
calcSignature($signatureEncoded$steps)
    {
        
$sign str_split($signatureEncoded);
        foreach (
$steps AS $step) {
            
$fn $step['function'];
            
$param = (int)$step['param'];

            switch (
$fn) {
                case 
'reverse':
                    
$sign array_reverse($sign);
                    break;
                case 
'splice':
                    
$sign array_slice($sign$param);
                    break;
                case 
'swap':
                    
$c $sign[0];
                    
$sign[0] = $sign[$param count($sign)];
                    
$sign[$param] = $c;
                    break;
            }
        }
        return 
implode(''$sign);
    }

    public static function 
getResponseHeaders($url)
    {
        
$clearHeaders get_headers($url);
        
$headers = array();
        foreach (
$clearHeaders AS $header) {
            
$header explode(':'$header);
            if (
count($header) === 2) {
                
$headers[$header[0]] = trim($header[1]);
            }
        }
        return 
$headers;
    }


    public function 
getDownloadInfoOne($fmtsItem)
    {
        
$fullInfo $this->getFullInfo();
        
$title $fullInfo['title'];
        
$url $fmtsItem['url'] . '&title=' $_SERVER['HTTP_HOST'] .'_' urlencode($title);
        
$signature false;
        if (isset(
$fmtsItem['signature'])) {
            
$signature $fmtsItem['signature'];
        }

        if (isset(
$fmtsItem['sig'])) {
            
$signature self::calcSignature($fmtsItem['sig'], $fullInfo['calcSignatureSteps']);
        }

        if (isset(
$fmtsItem['s'])) {
            
$signature self::calcSignature($fmtsItem['s'], $fullInfo['calcSignatureSteps']);
        }

        if (
$signature) {
            
$url .= '&signature=' $signature;
        }

        
$headers self::getResponseHeaders($url);
        
$downloadInfo = array();
          
$downloadInfo['url'] = $url;
        
$downloadInfo['youtubeItag'] = $fmtsItem['itag'];
        
$downloadInfo['fileType'] = explode(';'$fmtsItem['type']);
        
$downloadInfo['fileType'] = $downloadInfo['fileType'][0];
        
$ext explode('/'$downloadInfo['fileType']);
        
$ext $ext[1];
        
$downloadInfo['name'] = $title '.' $ext;
        
$downloadInfo['itagInfo'] = self::getItagInfo();
        if (isset(
$downloadInfo['itagInfo'][$fmtsItem['itag']])) {
            
$downloadInfo['itagInfo'] = $downloadInfo['itagInfo'][$fmtsItem['itag']];
        } else {
            
$downloadInfo['itagInfo'] = null;
        }
        
$downloadInfo[] = $downloadInfo;
        return 
$downloadInfo;
    }

    
/**
     * Return array of download information for video
     *
     * @return VideoDownloadInfo[]
     * @throws VideoDownloaderDownloadException
     */
    
public function getDownloadsInfo()
    {
        
$fullInfo $this->getFullInfo();
        
$fmts $fullInfo['url_encoded_fmt_stream_map'];
        
$fmts array_merge($fmts$fullInfo['adaptive_fmts']);
        
$downloadsInfo = array();
        foreach (
$fmts AS $item) {
            
$downloadsInfo[] = $this->getDownloadInfoOne($item);
        }
        return 
$downloadsInfo;
    }

}
Онлайн: 0
Реклама