Search the Community
Showing results for tags 'undefined'.
-
Hello all, I have a video converting script fetch / remote download and then convert using FFMPEG. Recently i had issue with one of the extractor "plugin" when i try to convert i get error in the browser in Virtualmin error log i get [Wed Jul 06 20:30:12.758777 2022] [proxy_fcgi:error] [pid 842:tid 139961936357120] [client 2.xx.xxx.9:56176] AH01071: Got error 'PHP message: PHP Notice: Undefined offset: 2 in /home/testdomain/public_html/lib/extractors/Extractor.php on line 205PHP message: PHP Notice: Undefined offset: 2 in /home/testdomain/public_html/lib/extractors/Extractor.php on line 205PHP message: PHP Notice: Undefined offset: 2 in /home/testdomain/public_html/lib/extractors/Extractor.php on line 205PHP message: PHP Notice: Undefined offset: 2 in /home/testdomain/public_html/lib/extractors/Extractor.php on line 205PHP message: PHP Notice: Undefined offset: 2 in /home/testdomain/public_html/lib/extractors/Extractor.php on line 205PHP message: PHP Notice: Undefined offset: 2 in /home/testdomain/public_html/lib/extractors/Extractor.php on line 205PHP message: PHP Notice: Undefined offset: 2 in /home/testdomain/public_html/lib/extractors/Extractor.php on line 205PHP message: PHP Notice: Undefined offset: 2 in /home/testdomain/public_html/lib/extractors/Extractor.php on line 205PHP message: PHP Notice: Undefined offset: 2 in /home/testdomain/public_html/lib/extractors/Extractor.php on line 205PHP message: PHP Notice: Undefined offset: 2 in /home/testdomain/public_html/lib/extractors/Extractor.php on line 205PHP message: PHP Notice: Undefined offset: 2 in /home/testdomain/public_html/lib/extractors/Extractor.php on line 205PHP message: PHP Notice: Undefined offset: 2 in /home/testdomain/public_html/lib/extractors/Extractor.php on line 205PHP message: PHP Warning: A non-numeric value encountered in /home/testdomain/public_html/lib/extractors/yt.php on line 202PHP message: PHP Fatal error: Uncaught Error: Unsupported operand types in /home/testdomain/public_html/lib/extractors/yt.php:202\nStack trace:\n#0 /home/testdomain/public_html/lib/VideoConverter.php(258): YouTubeMp3Converter\\lib\\extractors\\yt->RetrieveVidInfo()\n#1 /home/testdomain/public_html/inc/index_header.php(175): YouTubeMp3Converter\\lib\\VideoConverter->ValidateConversionForm()\n#2 /home/testdomain/public_html/index.php(4): include('/home/testdomai...')\n#3 {main}\n thrown in /home/testdomain/public_html/lib/extractors/yt.php on line 202', referer: http://91.xxx.xxx.xxx/?config=complete [Wed Jul 06 20:36:49.899796 2022] [proxy_fcgi:error] [pid 842:tid 139961886000896] [client 2.xx.xxx.9:56487] AH01071: Got error 'PHP message: PHP Notice: Undefined offset: 1 in /home/testdomain/public_html/lib/extractors/Extractor.php on line 205PHP message: PHP Notice: Undefined offset: 1 in /home/testdomain/public_html/lib/extractors/Extractor.php on line 205PHP message: PHP Notice: Undefined offset: 1 in /home/testdomain/public_html/lib/extractors/Extractor.php on line 205PHP message: PHP Notice: Undefined offset: 1 in /home/testdomain/public_html/lib/extractors/Extractor.php on line 205PHP message: PHP Notice: Undefined offset: 1 in /home/testdomain/public_html/lib/extractors/Extractor.php on line 205PHP message: PHP Notice: Undefined offset: 1 in /home/testdomain/public_html/lib/extractors/Extractor.php on line 205PHP message: PHP Notice: Undefined offset: 1 in /home/testdomain/public_html/lib/extractors/Extractor.php on line 205PHP message: PHP Notice: Undefined offset: 1 in /home/testdomain/public_html/lib/extractors/Extractor.php on line 205PHP message: PHP Notice: Undefined offset: 1 in /home/testdomain/public_html/lib/extractors/Extractor.php on line 205PHP message: PHP Notice: Undefined offset: 1 in /home/testdomain/public_html/lib/extractors/Extractor.php on line 205PHP message: PHP Notice: Undefined offset: 1 in /home/testdomain/public_html/lib/extractors/Extractor.php on line 205PHP message: PHP Notice: Undefined offset: 1 in /home/testdomain/public_html/lib/extractors/Extractor.php on line 205PHP message: PHP Warning: A non-numeric value encountered in /home/testdomain/public_html/lib/extractors/yt.php on line 202PHP message: PHP Fatal error: Uncaught Error: Unsupported operand types in /home/testdomain/public_html/lib/extractors/yt.php:202\nStack trace:\n#0 /home/testdomain/public_html/lib/VideoConverter.php(258): YouTubeMp3Converter\\lib\\extractors\\yt->RetrieveVidInfo()\n#1 /home/testdomain/public_html/inc/index_header.php(175): YouTubeMp3Converter\\lib\\VideoConverter->ValidateConversionForm()\n#2 /home/testdomain/public_html/index.php(4): include('/home/testdomai...')\n#3 {main}\n thrown in /home/testdomain/public_html/lib/extractors/yt.php on line 202', referer: http://91.xxx.xxx.xxx/index.php Previously i got it fixed with a help of a developer and everything worked perfectly without any issue on aaPanel but when i test this in Virtualmin i get this error. I will post 4 codes and related to the extractor which is having issue below is the (01) yt.php <?php namespace YouTubeMp3Converter\lib\extractors; use \YouTubeMp3Converter\lib\Config; // hub Extractor Class class yt extends Extractor { // Fields public $_reqHeaders = array( //'Accept-Encoding: gzip, deflate', 'Accept-Language: en-us,en;q=0.5', 'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7', 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Cookie: age_verified=1; platform=pc' ); protected $_mainUserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.131 Safari/537.36'; private $_platforms = array('pc'/*, 'tv'*/); #region Public Methods function RetrieveVidInfo($vidUrl) { $converter = $this->GetConverter(); $videoInfo = array(); $vidPage = ''; $srcUrl = ''; $vidTitle = 'Unknown'; $vidImage = 'https://img.youtube.com/vi/oops/1.jpg'; $vidDuration = array(); foreach ($this->_platforms as $platform) { $vidPage = $this->FileGetContents($vidUrl, "", $this->_reqHeaders); if (!empty($vidPage)) { $reqCookies = $this->ExtractCookies(); if (empty($srcUrl) && preg_match('/<video[^>]+src="(.+?)"[^>]*><\/video>/is', $vidPage, $matches) == 1) { $srcUrl = preg_replace('/^(\/{2})/', "http://", trim($matches[1])); } if (empty($srcUrl)) { $srcUrls = array(); if (preg_match('/var player_mp4_seek = "[^"]*";\s*(\/\/[^\/]+?\n)*(.+?)\n/is', $vidPage, $matches) == 1) { //die(trim($matches[2])); if (preg_match('/var qualityItems_[a-zA-Z0-9]+\s*=\s*(\[\{.+?\}\]);/is', $matches[2], $qitems) == 1) { $items = json_decode($qitems[1], true); if (json_last_error() == JSON_ERROR_NONE) { //die(print_r($items)); $itemUrls = array(); foreach ($items as $item) { if (isset($item['url']) && !empty($item['url'])) { $srcUrls[] = $item['url']; } } arsort($srcUrls); } } if (empty($srcUrls)) { if (preg_match('/(var\s+(?:(media|quality))_.+)/', $vidPage, $assignments) == 1) { //die(print_r($assignments)); $assignmentsArr = explode(";", $assignments[0]); //die(print_r($assignmentsArr)); $media = array(); array_walk($assignmentsArr, function($val) use(&$media) { if (preg_match('/^(var\s+(media|quality(?!Items))_\d=)/', $val) == 1) $media[] = preg_replace('/\/\*[^\*]*\*\//', "", preg_replace('/^(var\s+(media|quality(?!Items))_\d=)/', "", $val)); }); //die(print_r($media)); $surl = ""; foreach ($media as $medium) { $jsKeys = preg_split('/\s*\+\s*/', $medium, -1, PREG_SPLIT_NO_EMPTY); //die(print_r($jsKeys)); foreach ($jsKeys as $jsKey) { if (preg_match('/var\s+' . preg_quote($jsKey, "/") . '=([^;]+)/', $vidPage, $jsKeyMatch) == 1) { $surl .= preg_replace('/("|\+|\s)/', "", $jsKeyMatch[1]); } } if (!empty($surl)) { //echo $surl . "<br>"; if (preg_match('/get_media/', $surl) == 1) { $this->_reqHeaders[count($this->_reqHeaders) - 1] .= ';' . $reqCookies; //die(print_r($this->_reqHeaders)); $reqTries = 0; do { $mp4Json = $this->FileGetContents($surl, "", $this->_reqHeaders); $mp4Data = json_decode($mp4Json, true); $reqTries++; } while ($reqTries < Config::_MAX_CURL_TRIES && (json_last_error() != JSON_ERROR_NONE || empty($mp4Data))); $mp4Data_pre = array() ; foreach($mp4Data as $k => $v){ if($v['quality'] > 1080) unset($mp4Data[$k]); else if($v['format'] == 'hls') { $mp4Data_pre['ff_pre'] = ' -protocol_whitelist file,tls,tcp,https,crypto -allowed_extensions ALL '; $mp4Data_pre['ff_for'] = true ; } } //die(print_r($mp4Data)); if (isset($mp4Data[count($mp4Data) - 1]['videoUrl'])) { $srcUrls[0] = $mp4Data[count($mp4Data) - 1]['videoUrl']; } } if (empty($srcUrls) && preg_match('/1080P.*?720P.*?480P.*?\.m3u8\?/', $surl) == 1) { $m3u8 = $this->FileGetContents($surl, "", $this->_reqHeaders); if (!empty($m3u8)) { $m3u8Lines = preg_split('/\n|\r/', $m3u8, -1, PREG_SPLIT_NO_EMPTY); $m3u8Lines = preg_grep('/^(#)/', $m3u8Lines, PREG_GREP_INVERT); //die(print_r($m3u8Lines)); if (!empty($m3u8Lines)) { $surl = preg_replace('/(' . preg_quote(strrchr($surl, "/"), "/") . ')$/', "", $surl); $surl = $surl . "/" . current($m3u8Lines); $srcUrls[] = $surl; } } } //if (preg_match('/\.m3u8\?/', $surl) != 1) $srcUrls[] = $surl; } $surl = ""; } //die(print_r($srcUrls)); } } if (empty($srcUrls)) { preg_match_all('/var ([^=]+)="([^"]*)"(\s*\+\s*"([^"]*)")?;/is', trim($matches[2]), $matches2); if (!empty($matches2)) { //die(print_r($matches2)); $urlParts = array(); foreach ($matches2[0] as $k => $m) { $urlParts[$matches2[1][$k]] = $matches2[2][$k] . $matches2[4][$k]; } //die(print_r($urlParts)); if (!empty($urlParts)) { preg_match_all('/var quality_(\d+)p=(.+?);/is', trim($matches[2]), $matches3); if (!empty($matches3)) { //die(print_r($matches3)); foreach ($matches3[0] as $k => $m) { $urlVars = preg_replace('/\/\*[^\*]*\*\//', "", $matches3[2][$k]); $urlVars = preg_split('/\+/', $urlVars, -1, PREG_SPLIT_NO_EMPTY); foreach ($urlVars as $uvar) { $uvar = trim($uvar); $srcUrls[$matches3[1][$k]] .= (isset($urlParts[$uvar])) ? $urlParts[$uvar] : ''; } } arsort($srcUrls); } } } } } //die(print_r($srcUrls)); $srcUrl = (!empty($srcUrls)) ? current($srcUrls) : $srcUrl; } if ($vidTitle == 'Unknown' && preg_match("/('flashvars'\s*:\s*\{(.+?)\},)|(var flashvars\w* = \{(.+?)\};)/is", $vidPage, $matched) == 1) { //die(print_r($matched)); $rawJson = (!empty($matched[2])) ? $matched[2] : $matched[4]; $json = json_decode('{' . $rawJson . '}', true); if (json_last_error() == JSON_ERROR_NONE) { //die(print_r($json)); if (!isset($json['video_title'])) { $json = json_decode('{' . $matched[4] . '}', true); } $vidTitle = (isset($json['video_title'])) ? urldecode($json['video_title']) : $vidTitle; $vidImage = (isset($json['image_url'])) ? urldecode($json['image_url']) : $vidImage; $vidDuration = (isset($json['video_duration'])) ? array('duration' => (int)$json['video_duration']) : $vidDuration; } } } } parse_str(parse_url($vidUrl, PHP_URL_QUERY), $urlVars); if (isset($urlVars['viewkey'])) { $videoInfo = array('id' => $urlVars['viewkey'], 'title' => $vidTitle, 'thumb_preview' => $vidImage, 'src_sd' => $srcUrl, 'src_hd' => $srcUrl, 'cookies' => preg_replace('/^(Cookie: )/', "", $this->_reqHeaders[count($this->_reqHeaders) - 1])) + $vidDuration + $mp4Data_pre; } //die(print_r($videoInfo)); //print_r($videoInfo); return $videoInfo; } function ExtractVidSourceUrls() { // Populate vars required for extraction $converter = $this->GetConverter(); $vidUrls = array(); $ftype = $converter->GetConvertedFileType(); $fcategory = $converter->GetConvertedFileCategory(); $vidHost = $converter->GetCurrentVidHost(); $vidInfo = $converter->GetVidInfo(); $vidHosts = $converter->GetVideoHosts(); $vidQualities = array(); array_walk($vidHosts, function($vh, $key) use(&$vidQualities, $vidHost) {if ($vh['name'] == $vidHost) $vidQualities = $vh['video_qualities'];}); // Start extraction $playUrls = array(); foreach ($vidQualities as $key => $fq) { if (!empty($vidInfo[$fq]) && !in_array($vidInfo[$fq], $playUrls)) { $vidUrls[] = array('mp4', $key, $vidInfo[$fq]); $playUrls[] = $vidInfo[$fq]; } } //die(print_r($vidUrls)); return ($fcategory == 'audio' || $ftype == '3gp') ? array_reverse($vidUrls) : $vidUrls; } #endregion } ?> (02) remote.php <?php namespace YouTubeMp3Converter\lib; use YouTubeMp3Converter\lib\extractors\Extractor; // Remote Download Class class Remote { // Private Fields private static $_converter; private static $_curlResource; private static $_percentVidDownloaded = 0; private static $_fsize; private static $_downloaded; private static $_chunkCount = 0; private static $_prevChunkCount = 0; private static $_isChunkedDload; #region Public Methods public static function Init(VideoConverter $converter) { self::$_converter = $converter; } public static function ChunkedDownload(array $vars) { extract($vars); self::$_isChunkedDload = true; $converter = self::$_converter; $vHost = $converter->GetCurrentVidHost(); $dloadUrls = end($urls[$vidCount]); $dloadUrls = (!is_array($dloadUrls)) ? array($dloadUrls) : $dloadUrls; foreach ($dloadUrls as $urlKey => $dloadUrl) { self::$_downloaded = self::$_percentVidDownloaded = 0; $dloadUrlInfo = self::CheckDownloadUrl($dloadUrl, $extractor, $vidInfo, $vHost); $dloadUrl = (!empty($dloadUrlInfo['redirectUrl'])) ? $dloadUrlInfo['redirectUrl'] : $dloadUrl; if ($dloadUrlInfo['isValid']) { self::$_fsize = $dloadUrlInfo['filesize']; $chunkEnd = $chunkSize = 1000000; // 1 MB in bytes $numTries = $count = $chunkStart = 0; if (is_file($filename[$urlKey])) unlink($filename[$urlKey]); $file = fopen($filename[$urlKey], 'a'); self::$_curlResource = $ch = curl_init(); while (self::$_fsize >= $chunkStart) { //curl_setopt($ch, CURLOPT_FILE, $file); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_URL, $dloadUrl); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); if (Config::_ENABLE_IP_ROTATION && !Config::_DISABLE_IP_FOR_DOWNLOAD && $vHost == "YouTube" && $converter->GetOutgoingIP() != array()) { $currentIP = $converter->GetOutgoingIP(); $isProxy = !empty($currentIP['port']) || !empty($currentIP['proxy_user']) || !empty($currentIP['proxy_pass']); curl_setopt($ch, CURLOPT_REFERER, ''); if ($isProxy) { curl_setopt($ch, CURLOPT_PROXY, $currentIP['ip'] . ":" . $currentIP['port']); if (!empty($currentIP['proxy_user']) && !empty($currentIP['proxy_pass'])) { curl_setopt($ch, CURLOPT_PROXYUSERPWD, $currentIP['proxy_user'] . ":" . $currentIP['proxy_pass']); } if (Config::_ENABLE_TOR_PROXY) { curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); } curl_setopt($ch, CURLOPT_TIMEOUT, (int)ceil(3 * (round($chunkSize / 1048576, 2) / (1 / 8)))); } else { curl_setopt($ch, CURLOPT_INTERFACE, $currentIP['ip']); curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); } curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); } curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); curl_setopt($ch, CURLOPT_NOPROGRESS, false); curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, array('self', self::ProgressFuncName())); curl_setopt($ch, CURLOPT_BUFFERSIZE, $chunkSize); curl_setopt($ch, CURLOPT_RANGE, $chunkStart.'-'.$chunkEnd); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_USERAGENT, $extractor->GetMainUserAgent()); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); if (isset($vidInfo['cookies'])) { curl_setopt($ch, CURLOPT_COOKIE, $vidInfo['cookies']); } $output = curl_exec($ch); $curlInfo = curl_getinfo($ch); if ((curl_errno($ch) != 0 || $curlInfo['http_code'] != "206") && $numTries < 10) { $numTries++; continue; } $numTries = 0; fwrite($file, $output); $chunkStart += $chunkSize; $chunkStart += ($count == 0) ? 1 : 0; $chunkEnd += $chunkSize; self::$_chunkCount = ++$count; } curl_close($ch); fclose($file); self::$_prevChunkCount = self::$_chunkCount = 0; } /*if (is_file($filename[$urlKey])) echo "is file: " . $filename[$urlKey] . "<br>";*/ } } public static function Download(array $vars) { extract($vars); self::$_isChunkedDload = false; $converter = self::$_converter; $vHost = $converter->GetCurrentVidHost(); $dloadUrls = end($urls[$vidCount]); $dloadUrls = (!is_array($dloadUrls)) ? array($dloadUrls) : $dloadUrls; $resumeKey = 0; foreach ($dloadUrls as $urlKey => $dloadUrl) { self::$_curlResource = $ch = curl_init(); while ($urlKey == $resumeKey) { self::$_percentVidDownloaded = 0; $file = fopen($filename[$urlKey], 'w'); curl_setopt($ch, CURLOPT_FILE, $file); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_URL, $dloadUrl); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); if (Config::_ENABLE_IP_ROTATION && !Config::_DISABLE_IP_FOR_DOWNLOAD && $vHost == "YouTube" && $converter->GetOutgoingIP() != array()) { $currentIP = $converter->GetOutgoingIP(); $isProxy = !empty($currentIP['port']) || !empty($currentIP['proxy_user']) || !empty($currentIP['proxy_pass']); curl_setopt($ch, CURLOPT_REFERER, ''); if ($isProxy) { curl_setopt($ch, CURLOPT_PROXY, $currentIP['ip'] . ":" . $currentIP['port']); if (!empty($currentIP['proxy_user']) && !empty($currentIP['proxy_pass'])) { curl_setopt($ch, CURLOPT_PROXYUSERPWD, $currentIP['proxy_user'] . ":" . $currentIP['proxy_pass']); } if (Config::_ENABLE_TOR_PROXY) { curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); } } else { curl_setopt($ch, CURLOPT_INTERFACE, $currentIP['ip']); curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); } curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); } curl_setopt($ch, CURLOPT_NOPROGRESS, false); curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, array('self', self::ProgressFuncName())); curl_setopt($ch, CURLOPT_BUFFERSIZE, 4096000); curl_setopt($ch, CURLOPT_USERAGENT, $extractor->GetMainUserAgent()); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); if (isset($vidInfo['cookies'])) { curl_setopt($ch, CURLOPT_COOKIE, $vidInfo['cookies']); } curl_exec($ch); if (curl_errno($ch) == 0) { $curlInfo = curl_getinfo($ch); if (($vHost == "Dailymotion" || $vHost == "SoundCloud" || $vHost == "YouTube" || $vHost == "Pornhub") && $curlInfo['http_code'] == '302' && isset($curlInfo['redirect_url']) && !empty($curlInfo['redirect_url'])) { $dloadUrl = $curlInfo['redirect_url']; continue; } if (method_exists($extractor, 'GetCypherUsed') && $extractor->GetCypherUsed() && $curlInfo['http_code'] == '403') { $itag = $extractor->ExtractItagFromUrl($dloadUrl); if (!empty($itag)) { $extractor->FixDecryption($extractor->GetSignature($itag)); } } } fclose($file); $resumeKey++; } curl_close($ch); } } public static function DownloadPlaylist(array $vars) { extract($vars); $converter = self::$_converter; $vHost = $converter->GetCurrentVidHost(); $reqHeaders = (!empty($extractor->_reqHeaders)) ? $extractor->_reqHeaders : ""; $cmd = Config::_FFMPEG . (isset($pre_ffmpeg) ? $pre_ffmpeg : '') . ((!empty($reqHeaders)) ? ' -headers ' . escapeshellarg(implode('\r\n', $reqHeaders) . '\r\n') : '') . ' -i \'' . end($urls[$vidCount]) . '\' -bsf:a ' . ((strrchr($filename[0], ".") == ".mp3" || $vHost == "SoundCloud") ? 'mp3decomp' : 'aac_adtstoasc') . ' -c copy -y ' . $filename[0] . ' 2>&1'; //die($cmd); if (Config::_ENABLE_PLAYLIST_DOWNLOAD_PROGRESS && isset($vidInfo['duration'])) { $descriptorspec = array( 0 => array("pipe", "r"), 1 => array("pipe", "w"), 2 => array("pipe", "a") ); $pipes = array(); $process = proc_open($cmd, $descriptorspec, $pipes, null, null); if (is_resource($process)) { $processInfo = false; do { $cmdOutputLine = trim(fgets($pipes[1])); if (preg_match('/(time=)(.+?)(\s)/i', $cmdOutputLine, $times) == 1) { if (preg_match('/(\d\d):(\d\d):(\d\d\.\d\d)/', $times[2], $lastTime) == 1) { $lastTime = ((int)$lastTime[1] * 60 * 60) + ((int)$lastTime[2] * 60) + (float)$lastTime[3]; $progress = round(($lastTime / (float)$vidInfo['duration']) * 100); $progress = ($progress > 100) ? 100 : $progress; self::OutputDownloadProgress($progress, true); } } //echo $cmdOutputLine . "<br>"; if (!empty($cmdOutputLine)) $ffmpegOutput[] = $cmdOutputLine; $processInfo = proc_get_status($process); } while ($processInfo !== false && $processInfo['running']); } fclose($pipes[0]); fclose($pipes[1]); fclose($pipes[2]); proc_close($process); } else { self::OutputDownloadProgress(100, false); exec($cmd, $ffmpegOutput); } return $ffmpegOutput; } public static function DownloadPlaylistNative(array $vars) { extract($vars); $converter = self::$_converter; $vHost = $converter->GetCurrentVidHost(); $reqHeaders = (!empty($extractor->_reqHeaders)) ? $extractor->_reqHeaders : ""; self::OutputDownloadProgress(100, false); $context = stream_context_create(array( 'http' => array( 'method' => "GET", 'header' => $reqHeaders ) )); $m3u8Url = end($urls[$vidCount]); $m3u8file = file_get_contents($m3u8Url, false, $context); if ($m3u8file !== false && !empty($m3u8file)) { $m3u8Lines = preg_split('/\n|\r/', $m3u8file, -1, PREG_SPLIT_NO_EMPTY); $m3u8Lines = preg_grep('/^(#)/', $m3u8Lines, PREG_GREP_INVERT); //die(print_r($m3u8Lines)); if (!empty($m3u8Lines)) { ini_set('memory_limit', '-1'); $videoContent = ''; foreach ($m3u8Lines as $m3u8Line) { //die($m3u8Line); $urlPrefix = preg_replace('/(' . preg_quote(strrchr($m3u8Url, "/"), "/") . ')$/', "", $m3u8Url); $m3u8Line = $urlPrefix . "/" . $m3u8Line; //die($m3u8Line); $tsFileContent = file_get_contents($m3u8Line, false, $context); if ($tsFileContent === false || empty($tsFileContent)) { $videoContent = ''; break; } $videoContent .= $tsFileContent; } if (!empty($videoContent)) { $tmpfname = tempnam(dirname(__DIR__) . "/store", "m3u8"); if ($tmpfname !== false) { $bytes = file_put_contents($tmpfname, $videoContent); if ($bytes !== false && $bytes > 0) { $cmd = Config::_FFMPEG . (isset($pre_ffmpeg) ? $pre_ffmpeg : '') . ' -i ' . escapeshellarg($tmpfname) . ' -c copy -y -f mp4 -bsf:a aac_adtstoasc ' . escapeshellarg($filename[0]) . ' 2>&1'; exec($cmd, $ffmpegOutput); } unlink($tmpfname); } } } } return $ffmpegOutput; } public static function OutputDownloadProgress($percent, $isRealTime) { echo '<script type="text/javascript">updateVideoDownloadProgress("'. $percent .'", ' . (($isRealTime) ? 'true' : 'false') . ');</script>'; $converter = self::$_converter; $converter->FlushBuffer(); } #endregion #region Private "Helper" Methods private static function CheckDownloadUrl($url, Extractor $extractor, array $vidInfo, $vHost) { $retVal = array('isValid' => false, 'filesize' => 0, 'redirectUrl' => ''); $converter = self::$_converter; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_NOBODY, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_USERAGENT, $extractor->GetMainUserAgent()); if (Config::_ENABLE_IP_ROTATION && !Config::_DISABLE_IP_FOR_DOWNLOAD && $converter->GetCurrentVidHost() == "YouTube" && $converter->GetOutgoingIP() != array()) { $currentIP = $converter->GetOutgoingIP(); $isProxy = !empty($currentIP['port']) || !empty($currentIP['proxy_user']) || !empty($currentIP['proxy_pass']); curl_setopt($ch, CURLOPT_REFERER, ''); if ($isProxy) { curl_setopt($ch, CURLOPT_PROXY, $currentIP['ip'] . ":" . $currentIP['port']); if (!empty($currentIP['proxy_user']) && !empty($currentIP['proxy_pass'])) { curl_setopt($ch, CURLOPT_PROXYUSERPWD, $currentIP['proxy_user'] . ":" . $currentIP['proxy_pass']); } if (Config::_ENABLE_TOR_PROXY) { curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); } } else { curl_setopt($ch, CURLOPT_INTERFACE, $currentIP['ip']); curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); } curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); } curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); if (isset($vidInfo['cookies'])) { curl_setopt($ch, CURLOPT_COOKIE, $vidInfo['cookies']); } $headers = curl_exec($ch); if (curl_errno($ch) == 0) { $info = curl_getinfo($ch); //die(print_r($info)); $retVal['filesize'] = (int)$info['download_content_length']; if (($vHost == "Dailymotion" || $vHost == "SoundCloud" || $vHost == "YouTube" || $vHost == "Pornhub") && $info['http_code'] == '302' && isset($info['redirect_url']) && !empty($info['redirect_url'])) { $retVal['redirectUrl'] = $info['redirect_url']; } if (method_exists($extractor, 'GetCypherUsed') && $extractor->GetCypherUsed() && $info['http_code'] == '403') { $itag = $extractor->ExtractItagFromUrl($url); if (!empty($itag)) { $extractor->FixDecryption($extractor->GetSignature($itag)); } } else { $retVal['isValid'] = $info['http_code'] != '404' && $info['http_code'] != '403'; } } curl_close($ch); return $retVal; } private static function ProgressFuncName() { return (Config::_PHP_VERSION >= 5.5) ? ((self::$_isChunkedDload) ? 'UpdateVideoChunkDownloadProgress' : 'UpdateVideoDownloadProgress') : 'LegacyUpdateVideoDownloadProgress'; } private static function UpdateVideoDownloadProgress($curlResource, $downloadSize, $downloaded, $uploadSize, $uploaded) { $httpCode = curl_getinfo($curlResource, CURLINFO_HTTP_CODE); if ($httpCode == "200" && $downloadSize > 0) { $percent = round($downloaded / $downloadSize, 2) * 100; if ($percent > self::$_percentVidDownloaded) { self::$_percentVidDownloaded++; self::OutputDownloadProgress($percent, true); } } } private static function UpdateVideoChunkDownloadProgress($curlResource, $downloadSize, $downloaded, $uploadSize, $uploaded) { $httpCode = curl_getinfo($curlResource, CURLINFO_HTTP_CODE); if ($httpCode == "206" && $downloadSize > 0 && self::$_chunkCount != self::$_prevChunkCount) { self::$_prevChunkCount++; self::$_downloaded += $downloadSize; $percent = round(self::$_downloaded / self::$_fsize, 2) * 100; if ($percent > self::$_percentVidDownloaded) { self::$_percentVidDownloaded++; self::OutputDownloadProgress($percent, true); } } } // Deprecated - May be removed in future versions! private static function LegacyUpdateVideoDownloadProgress($downloadSize, $downloaded, $uploadSize, $uploaded) { if (self::$_isChunkedDload) { self::UpdateVideoChunkDownloadProgress(self::$_curlResource, $downloadSize, $downloaded, $uploadSize, $uploaded); } else { self::UpdateVideoDownloadProgress(self::$_curlResource, $downloadSize, $downloaded, $uploadSize, $uploaded); } } #endregion } ?> (03) VideoConverter.php <?php namespace YouTubeMp3Converter\lib; // Conversion Class class VideoConverter extends Config { // Private Fields private $_convertedFileName = ''; private $_convertedFileType = ''; private $_convertedFileCategory = ''; private $_convertedFileQuality = Config::_DEFAULT_AUDIO_QUALITY; private $_convertedFileVolume = Config::_VOLUME; private $_vidSourceUrls = array(); private $_tempVidFileName = array(); private $_uniqueID; private $_currentVidHost = ''; private $_vidInfo = array(); private $_validationError = ''; private $_skipConversion = false; private $_ffmpegCommand = ''; private $_extractor; private $_outgoingIP = array(); private $_doFFmpegCopy = false; private $_pluginInfo = array(); // Constants const _FILENAME_DELIMITER = "~~"; const _MAX_FILENAME_LENGTH = 255; const _URL_WILDCARD_PATTERN = '[^\\\\/\?]+'; #region Public Methods function __construct() { if (isset($_SESSION)) { $this->_uniqueID = (!isset($_SESSION[Config::_SITENAME])) ? time() . "_" . uniqid('', true) : $_SESSION[Config::_SITENAME]; $_SESSION[Config::_SITENAME] = (!isset($_SESSION[Config::_SITENAME])) ? $this->_uniqueID : $_SESSION[Config::_SITENAME]; $_SESSION['execFFmpegToken'] = (!isset($_SESSION['execFFmpegToken'])) ? uniqid($this->_uniqueID, true) : $_SESSION['execFFmpegToken']; $_SESSION['execFFmpegToken2'] = (!isset($_SESSION['execFFmpegToken2'])) ? uniqid($this->_uniqueID, true) : $_SESSION['execFFmpegToken2']; if (Config::_ENABLE_IP_ROTATION && !Config::_ENABLE_TOR_PROXY) Database::Connect(Config::_SERVER, Config::_DB_USER, Config::_DB_PASSWORD, Config::_DATABASE); $this->_pluginInfo = Plugin::Init(); // Load any plugin data } else { die('Error!: Session must be started in the calling file to use this class.'); } } function __destruct() { if (Config::_ENABLE_IP_ROTATION && !Config::_ENABLE_TOR_PROXY && class_exists('Database')) Database::Close(); } function DownloadVideo($vidUrl) { $videoInfo = $this->GetVidInfo(); if (!empty($videoInfo)) { $this->SetConvertedFileName(); $this->SetVidSourceUrls(); if ($this->GetConvertedFileName() != '' && count($this->GetVidSourceUrls()) > 0) { $urls = $this->GetVidSourceUrls(); if ((Config::_CACHING_ENABLED && !Config::_ENABLE_DIRECT_DOWNLOAD) || (Config::_ENABLE_DIRECT_DOWNLOAD && $this->GetConvertedFileCategory() != 'audio' && $this->GetConvertedFileVolume() == Config::_VOLUME)) { $urls = $this->FilterUrls($urls); //die(print_r($urls)); } return $this->SaveVideo($urls); } } return false; } function DoConversion() { $extractor = $this->GetExtractor(); $vidHost = $this->GetCurrentVidHost(); $fileType = $this->GetConvertedFileType(); $fileCategory = $this->GetConvertedFileCategory(); $fileQuality = $this->GetConvertedFileQuality(); $fileVolume = $this->GetConvertedFileVolume(); $newFile = $this->GetConvertedFileName(); $tempFile = $this->GetTempVidFileName(); $tmpNewFile = preg_replace('/^((.+)(' . preg_quote(strrchr($newFile, "."), '/') . '))$/', "$2.tmp$3", $newFile); if (!empty($fileType) && !empty($newFile) && !empty($tempFile)) { $exec_string = ''; $ftypes = $this->GetConvertedFileTypes(); foreach ($ftypes as $ftype) { if ($fileType == $ftype['fileExt']) { $videoBitrate = Config::_DEFAULT_VIDEO_QUALITY; if ($fileCategory == 'video') { exec(Config::_FFMPEG . ' -i ' . $tempFile[0] . ' 2>&1 | grep "Video:\|bitrate:"', $output); if (count($output) > 0) { foreach ($output as $line) { if (preg_match('/(\d+)( kb\/s)/i', $line, $matches) == 1) { $videoBitrate = $matches[1]; break; } } } } $ftypeFFmpeg = (isset($ftype['ffmpegCopy']) && $fileVolume == Config::_VOLUME && $fileQuality == Config::_DEFAULT_AUDIO_QUALITY && (($fileType == "aac" && $vidHost == "YouTube" && $extractor->AudioAvailable()) || $this->_doFFmpegCopy)) ? $ftype['ffmpegCopy'] : $ftype['ffmpeg']; $tempFile2 = ''; if (isset($ftype['ffmpegMerge'], $ftype['ffmpegMergeAndVol']) && count($tempFile) > 1) { $ftypeFFmpeg = ($fileVolume == Config::_VOLUME) ? $ftype['ffmpegMerge'] : $ftype['ffmpegMergeAndVol']; $tempFile2 = $tempFile[1]; } $this->_ffmpegCommand = $exec_string = preg_replace( array('/%ffmpeg%/', '/%tempFile%/', '/%tempFile2%/', '/%volume%/', '/%quality%/', '/%vquality%/', '/%newFile%/', '/%logsDir%/', '/%id%/'), array(Config::_FFMPEG, $tempFile[0], $tempFile2, $fileVolume, $fileQuality, $videoBitrate, $tmpNewFile, Config::_LOGSDIR, $this->_uniqueID), $ftypeFFmpeg ); break; } } //die($exec_string); if (!is_dir(realpath(Config::_LOGSDIR))) mkdir(Config::_LOGSDIR, 0777); if (is_file(realpath(Config::_LOGSDIR . $this->_uniqueID . ".txt"))) unlink(realpath(Config::_LOGSDIR . $this->_uniqueID . ".txt")); // If previous conversion was abandoned, remove corresponding log file with same file name, if it exists, to prevent subsequent conversion failure! $isHttps = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') || $_SERVER['SERVER_PORT'] == 443; if (!$isHttps && isset($_SERVER['HTTP_CF_VISITOR'])) { $cfJson = json_decode($_SERVER['HTTP_CF_VISITOR'], true); if (json_last_error() == JSON_ERROR_NONE) { $isHttps = !empty($cfJson) && current($cfJson) == 'https'; } } $protocol = ($isHttps) ? "https://" : "http://"; $ffmpegExecUrl = preg_replace('/(([^\/]+?)(\.php))$/', "exec_ffmpeg.php", $protocol.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']); $postData = "cmd=".urlencode($exec_string)."&token=".urlencode($_SESSION['execFFmpegToken'])."&fname=".urlencode($tmpNewFile); $strCookie = 'PHPSESSID=' . session_id() . '; path=/'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $ffmpegExecUrl); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_COOKIE, $strCookie); curl_exec($ch); curl_close($ch); } } function DownloadConvertedFile($file, $directory) { $ftypes = $this->GetConvertedFileTypes(); $filepath = $directory . urldecode($file); $ftype = trim(strrchr($filepath, '.'), '.'); $vidHostAbbr = current(explode('/', urldecode($file))); $mimeTypes = array(); array_walk($ftypes, function($ftype) use(&$mimeTypes) {$mimeTypes[$ftype['fileExt']] = $ftype['mimeType'];}); //print_r($mimeTypes); //die("\n\nftype: " . $ftype . ", vidHostAbbr: " . $vidHostAbbr); if ($this->ValidateDownloadFileName($filepath, $directory, array_keys($mimeTypes))) { $filename = $this->PrepareConvertedFileNameForDownload($file); $filepath = realpath($filepath); if (Config::_DELAY_POPULAR_FILE_DELETION && Config::_CACHING_ENABLED && (!Config::_ENABLE_DIRECT_DOWNLOAD || (Config::_ENABLE_DIRECT_DOWNLOAD && $vidHostAbbr != "sc" && ($ftype == "mp3" || $ftype == "aac")))) { $attr = array(); exec(Config::_ATTR . ' -q -g time.created ' . escapeshellarg($filepath) . ' 2>&1', $attr); if (count($attr) > 1) { $attr = array(); exec(Config::_ATTR . ' -s time.created -V ' . time() . ' ' . escapeshellarg($filepath)); exec(Config::_ATTR . ' -q -g time.created ' . escapeshellarg($filepath) . ' 2>&1', $attr); } if (count($attr) == 1 && preg_match('/^(\d+)$/', $attr[0]) == 1) { if (time() - (int)$attr[0] < Config::_MAX_DELETION_DELAY && time() - filemtime($filepath) < Config::_MAX_POPULAR_FILE_INCREMENT) { touch($filepath); } } } //if (filesize($filepath) > 10000) touch($filepath); $contentType = ($ftype == 'm4a') ? $mimeTypes['mp3'] : $mimeTypes[$ftype]; header('Content-Type: ' . $contentType); header('Content-Length: ' . filesize($filepath)); header('Content-Disposition: attachment; filename="'.$filename.'"'); ob_clean(); flush(); readfile($filepath); die(); } else { $redirect = explode("?", $_SERVER['REQUEST_URI']); header('Location: ' . $redirect[0]); } } function ValidateConversionForm($vidUrl, $ftype, $getVidInfo=false, $moreOptions=array()) { $vidHostName = $convertedFtype = ''; $vidHosts = $this->GetVideoHosts(); $urlRoots = array(); $urlSuffix = ''; foreach ($vidHosts as $host) { foreach ($host['url_root'] as $urlRoot) { //$urlRoot = preg_replace('/^(([^\?]+?)(\?{1})(.+))$/', "$2$3", $urlRoot); $wildcardRegex = (Config::_PHP_VERSION >= 7.3) ? '/\\\#wildcard\\\#/' : '/#wildcard#/'; $rootUrlPattern = preg_replace($wildcardRegex, self::_URL_WILDCARD_PATTERN, preg_quote($urlRoot, '/')); $rootUrlPattern = ($host['allow_https_urls']) ? preg_replace('/^(http)/', "https?", $rootUrlPattern) : $rootUrlPattern; if (preg_match('/^(('.$rootUrlPattern.')(.+))/i', $vidUrl, $matches) == 1 && preg_match('/'.$rootUrlPattern.'/', $matches[3]) != 1) { $vidHostName = $host['name']; $urlRoots = $host['url_root']; $urlSuffix = $matches[3]; break 2; } } } $ftypes = $this->GetConvertedFileTypes(); $convertedFtype = (in_array($ftype, array_keys($ftypes))) ? $ftypes[$ftype]['fileExt'] : ''; $convertedFcategory = (in_array($ftype, array_keys($ftypes))) ? current(explode("/", $ftypes[$ftype]['mimeType'])) : ''; $convertedFquality = (in_array($ftype, array_keys($ftypes)) && isset($ftypes[$ftype]['quality'])) ? $ftypes[$ftype]['quality'] : Config::_DEFAULT_AUDIO_QUALITY; $convertedFvolume = (isset($moreOptions['volume'])) ? $moreOptions['volume'] : Config::_VOLUME; if (!empty($vidHostName) && !empty($convertedFtype) && !empty($convertedFcategory)) { foreach ($urlRoots as $urlroot) { $urlroot = preg_replace('/^(https?)/', "", $urlroot); if (isset(Config::$_urlBlacklist["https" . $urlroot . $urlSuffix]) || isset(Config::$_urlBlacklist["http" . $urlroot . $urlSuffix])) { $this->_validationError = 'Validation_Error_Copyright'; return false; } } if ($vidHostName == 'SoundCloud' && $convertedFcategory == 'video') { $this->_validationError = 'Validation_Error_Audio_To_Video'; return false; } $this->SetCurrentVidHost($vidHostName); $this->SetConvertedFileType($convertedFtype); $this->SetConvertedFileCategory($convertedFcategory); $this->SetConvertedFileQuality($convertedFquality); $this->SetConvertedFileVolume($convertedFvolume); $this->SetExtractor($vidHostName); if ($getVidInfo) { $extractor = $this->GetExtractor(); $this->_vidInfo = $extractor->RetrieveVidInfo($vidUrl); //die(print_r($this->_vidInfo)); if (isset($this->_vidInfo['is_video_audio']) && !$this->_vidInfo['is_video_audio']) { $this->_validationError = 'Validation_Error_General'; return false; } $isOkDuration = true; if (isset($this->_vidInfo['duration'])) { foreach ($ftypes as $ftype) { if ($isOkDuration) { $quality = (isset($ftype['quality'])) ? $ftype['quality'] : Config::_DEFAULT_AUDIO_QUALITY; $isOkDuration = ($ftype['fileExt'] == $convertedFtype && $quality == $convertedFquality) ? (($ftype['maxDuration'] != -1) ? $ftype['maxDuration'] >= $this->_vidInfo['duration'] : true) : true; } } } if (!$isOkDuration) { $this->_validationError = 'Validation_Error_Vid_Length'; return false; } } return true; } $this->_validationError = 'Validation_Error_General'; return false; } function PrepareConvertedFileNameForDownload($file) { $filename = urldecode($file); $filename = current(array_reverse(explode(self::_FILENAME_DELIMITER, $filename))); $ftypesForRegex = $this->GetConvertedFileTypes(); if (Config::_ENABLE_CONCURRENCY_CONTROL) { array_walk($ftypesForRegex, function(&$ftype, $key) {$ftype = $ftype['fileExt'];}); $replacementStr = ((Config::_ENABLE_FILENAME_BRANDING) ? '[' . Config::_SITENAME . ']' : '') . "$4$5"; $filename = preg_replace('/((_uuid-)(\w{13})(\.)('.implode('|', $ftypesForRegex).'))$/', $replacementStr, $filename); } $fileBasename = pathinfo($filename, PATHINFO_FILENAME); $filename = (empty($fileBasename) || (!Config::_ENABLE_UNICODE_SUPPORT && preg_match('/^([^a-zA-Z0-9]+)$/', $fileBasename) == 1)) ? 'unknown' . strrchr($filename, '.') : $filename; return preg_replace('/_/', " ", $filename); } function ExtractVideoId($vidUrl) { $id = ''; $url = trim($vidUrl); $urlQueryStr = parse_url($url, PHP_URL_QUERY); if ($urlQueryStr !== false && !empty($urlQueryStr)) { parse_str($urlQueryStr, $params); if (isset($params['v']) && !empty($params['v'])) { $id = $params['v']; } else { $url = preg_replace('/(\?' . preg_quote($urlQueryStr, '/') . ')$/', "", $url); $id = trim(strrchr(trim($url, '/'), '/'), '/'); } } else { $id = trim(strrchr(trim($url, '/'), '/'), '/'); } return $id; } function RetrieveCachedFile() { $fileName = ''; $videoInfo = $this->GetVidInfo(); $ftype = $this->GetConvertedFileType(); $fquality = $this->GetConvertedFileQuality(); $fvolume = $this->GetConvertedFileVolume(); $extractor = $this->GetExtractor(); $vidHost = $this->GetCurrentVidHost(); $videoInfo['host_abbrev'] = $extractor->ReturnConfig('abbreviation'); if ((!Config::_ENABLE_DIRECT_DOWNLOAD || (Config::_ENABLE_DIRECT_DOWNLOAD && $vidHost != "SoundCloud" && ($ftype == "mp3" || $ftype == "aac"))) && !empty($videoInfo) && !empty($videoInfo['title']) && !empty($videoInfo['id']) && !is_null($videoInfo['host_abbrev'])) { $vTitle = html_entity_decode($videoInfo['title'], ENT_COMPAT | ENT_HTML401, 'UTF-8'); $fname = (!Config::_ENABLE_UNICODE_SUPPORT) ? preg_replace('/[^A-Za-z0-9 _-]/', '', $vTitle) : preg_replace('#/#', '', preg_replace('/\\\\|\/|\?|%|\*|:|\||"|<|>|\]|\[|\(|\)|\.|&|\^|\$|#|@|\!|`|~|=|\+|,|;|\'|\{|\}/', '', $vTitle)); $fname = preg_replace('/_{2,}/', '_', preg_replace('/ /', '_', $fname)); $dirName = Config::_CONVERTED_FILEDIR . $videoInfo['host_abbrev'] . '/' . $videoInfo['id'] . '/'; if (is_dir(realpath($dirName))) { $filesystemIterator = new \FilesystemIterator(realpath($dirName), \FilesystemIterator::KEY_AS_FILENAME); $regexIterator = new \RegexIterator($filesystemIterator, '/^(('.preg_quote($fquality . self::_FILENAME_DELIMITER . $fvolume . self::_FILENAME_DELIMITER . $fname, '/').')((_uuid-)(\w+))?(\.)('.preg_quote($ftype, '/').'))$/', \RegexIterator::MATCH, \RegexIterator::USE_KEY); $files = array_keys(iterator_to_array($regexIterator)); if (!empty($files)) { foreach ($files as $file) { if (is_file(realpath($dirName . $file))) { $fileName = $dirName . $file; break; } } } } } //die($fileName); return $fileName; } function FlushBuffer() { if (ob_get_length() > 0) ob_end_flush(); if (ob_get_length() > 0) ob_flush(); flush(); } function ValidateFile(array $filename, array $params) { extract($params); $error = true; foreach ($filename as $fname) { if (is_file($fname)) { $durationDiff = 0; $getID3 = new \getID3; $fileInfo = @$getID3->analyze($fname); //print_r($fileInfo); if (isset($duration)) { if (!isset($fileInfo['playtime_seconds'])) { // Use FFmpeg to detect duration as a backup!! exec(Config::_FFMPEG . ' -i ' . $fname . ' 2>&1', $ffOutput); //die(print_r($ffOutput)); if (count($ffOutput) > 0) { foreach ($ffOutput as $line) { if (preg_match('/Duration:\s*(\d{2}:\d{2}:\d{2})/', $line, $matches) == 1) { $fileInfo['playtime_seconds'] = strtotime("1970-01-01 " . $matches[1] . " UTC"); break; } } } } $durationDiff = (isset($fileInfo['playtime_seconds'])) ? abs((float)$fileInfo['playtime_seconds'] - (float)$duration) : $durationDiff; } $error = !filesize($fname) || filesize($fname) < 10000 || (isset($isPlaylist) && isset($ffmpegOutput) && $isPlaylist && (empty($ffmpegOutput) || preg_match('/muxing overhead/i', end($ffmpegOutput)) != 1)) || !isset($fileInfo['playtime_seconds']) || $durationDiff > Config::_MAX_ALLOWED_DURATION_DIFFERENCE; if ($error) break; } } return !$error; } #endregion #region Private "Helper" Methods private function ValidateDownloadFileName($filepath, $directory, array $fileExts) { $isValid = false; $fullFilepath = realpath($filepath); if ($fullFilepath !== false && $fullFilepath != $filepath && is_file($fullFilepath)) { $normalizedAppRoot = (Config::_APPROOT != "/") ? preg_replace('/\//', DIRECTORY_SEPARATOR, Config::_APPROOT) : DIRECTORY_SEPARATOR; $pathBase = realpath($_SERVER['DOCUMENT_ROOT']) . $normalizedAppRoot; $safePath = preg_replace('/^(' . preg_quote($pathBase, '/') . ')/', "", $fullFilepath); if ($safePath != $fullFilepath && preg_match('/^(' . preg_quote(preg_replace('/\//', DIRECTORY_SEPARATOR, $directory), '/') . ')/', $safePath) == 1) { $fileExt = pathinfo($fullFilepath, PATHINFO_EXTENSION); $isValid = in_array($fileExt, $fileExts); } } return $isValid; } private function FilterUrls(array $urls) { $filteredUrls = array(); $ftype = $this->GetConvertedFileType(); $vidHosts = array_values($this->GetVideoHosts()); $vidQualities = array_keys($vidHosts[0]['video_qualities']); $ftypes = $this->GetConvertedFileTypes(); $uniqueFtypes = array(); array_walk($ftypes, function($ft, $key) use(&$uniqueFtypes) {if (!isset($uniqueFtypes[$ft['fileExt']]) && isset($ft['qualityTolerance'])) $uniqueFtypes[$ft['fileExt']] = $ft['qualityTolerance'];}); if (Config::_ENABLE_DIRECT_DOWNLOAD && isset($uniqueFtypes[$ftype])) { $availableQualityIndexes = array(); array_walk($urls, function($url) use(&$availableQualityIndexes, $vidQualities) {if (in_array($url[1], $vidQualities)) $availableQualityIndexes[] = array_search($url[1], $vidQualities);}); $ftypeQualityIndex = array_search($uniqueFtypes[$ftype], $vidQualities); $reduceQualityToleranceFurther = false; do { $filteredAvailableQuals = array_filter($availableQualityIndexes, function($index) use($ftypeQualityIndex) {return $index <= $ftypeQualityIndex;}); if (empty($filteredAvailableQuals)) { $uniqueFtypes[$ftype] = $vidQualities[++$ftypeQualityIndex]; $reduceQualityToleranceFurther = $ftypeQualityIndex < count($vidQualities) - 1; } else { $reduceQualityToleranceFurther = false; } } while ($reduceQualityToleranceFurther); } foreach ($urls as $url) { $qualityToleranceCondition = (Config::_ENABLE_DIRECT_DOWNLOAD) ? array_search($url[1], $vidQualities) <= array_search($uniqueFtypes[$ftype], $vidQualities) : true; if ($ftype == $url[0] && in_array($url[1], $vidQualities) && $qualityToleranceCondition) { $filteredUrls[] = $url; } } return $filteredUrls; } private function SaveVideo(array $urls) { //die(print_r($urls)); //die(print_r($this->GetVidSourceUrls())); $vidInfo = $this->GetVidInfo(); $extractor = $this->GetExtractor(); $this->_skipConversion = $skipConversion = Config::_ENABLE_DIRECT_DOWNLOAD && (($this->GetConvertedFileCategory() != 'audio' && ($this->GetCurrentVidHost() != 'YouTube' || ($this->GetConvertedFileType() == '3gp' && $extractor->ThreegpAvailable()))) || ($this->GetCurrentVidHost() == 'SoundCloud' && !$vidInfo['downloadable'] && $this->GetConvertedFileType() == 'mp3' && $this->GetConvertedFileQuality() == '128') || ($this->GetCurrentVidHost() == 'YouTube' && $extractor->AudioAvailable() && $this->GetConvertedFileType() == 'm4a')) && $this->GetConvertedFileVolume() == Config::_VOLUME && !empty($urls); $this->_doFFmpegCopy = $doFFmpegCopy = ((Config::_CACHING_ENABLED && !Config::_ENABLE_DIRECT_DOWNLOAD) || (Config::_ENABLE_DIRECT_DOWNLOAD && $this->GetCurrentVidHost() == 'YouTube' && $this->GetConvertedFileCategory() != 'audio' && !$skipConversion)) && !empty($urls); if (!$skipConversion && !$doFFmpegCopy) $urls = $this->GetVidSourceUrls(); $success = false; $vidCount = -1; //die(print_r($urls)); $urls = array_values($urls); while (!$success && ++$vidCount < count($urls)) { if (isset($urls[$vidCount-1]) && $urls[$vidCount-1][1] == 'au' && $skipConversion && $this->GetCurrentVidHost() == 'YouTube' && $this->GetConvertedFileType() == 'm4a') { $this->_skipConversion = $skipConversion = false; } if (!$skipConversion) { $this->SetTempVidFileName(); if (is_array(end($urls[$vidCount]))) { $this->SetTempVidFileName(); } } $filename = (!$skipConversion) ? $this->GetTempVidFileName() : $this->GetConvertedFileName(); $filename = (!is_array($filename)) ? array($filename) : $filename; $tries = 0; $isPlaylist = preg_match('/^((\.m3u8)(.*))$/', (string)strrchr((string)parse_url(end($urls[$vidCount]), PHP_URL_PATH), ".")) == 1; $ffmpegOutput = array(); $pre_ffmpeg = isset($vidInfo['ff_pre']) ? $vidInfo['ff_pre'] : ''; do { $dloadVars = compact('extractor', 'vidInfo', 'urls', 'vidCount', 'filename', 'tries', 'ffmpegOutput', 'pre_ffmpeg'); $remote = (isset($this->_pluginInfo['AntiCaptcha']['Remote'][$this->GetCurrentVidHost()])) ? $this->_pluginInfo['AntiCaptcha']['Remote'][$this->GetCurrentVidHost()] : __NAMESPACE__ . '\\Remote'; $remote::Init($this); if ($isPlaylist) { $nativePlaylistDload = $extractor->ReturnConfig("enable_native_playlist_download"); if(isset($vidInfo['ff_for']) && $vidInfo['ff_for']) $ffmpegOutput = $remote::DownloadPlaylist($dloadVars); else $ffmpegOutput = (!is_null($nativePlaylistDload) && $nativePlaylistDload) ? $remote::DownloadPlaylistNative($dloadVars) : $remote::DownloadPlaylist($dloadVars); //die(print_r($ffmpegOutput)); } else { $isChunkedDload = $extractor->ReturnConfig('enable_chunked_download'); if (!is_null($isChunkedDload) && $isChunkedDload) { $remote::ChunkedDownload($dloadVars); } else { $remote::Download($dloadVars); } } $vidDurArr = (isset($vidInfo['duration'])) ? array('duration' => $vidInfo['duration']) : array(); $success = $this->ValidateFile($filename, $vidDurArr + compact('isPlaylist', 'ffmpegOutput')); if (!$success) { foreach ($filename as $fname) { if (is_file($fname)) unlink($fname); } $ffmpegOutput = array(); } $tries++; } while (!$success && Config::_ENABLE_IP_ROTATION && $tries < Config::_MAX_CURL_TRIES && $this->GetCurrentVidHost() == "YouTube"); } return $success; } #endregion #region Properties public function GetConvertedFileName() { return $this->_convertedFileName; } private function SetConvertedFileName() { $videoInfo = $this->GetVidInfo(); //die($videoInfo['title']); $ftype = $this->GetConvertedFileType(); $fquality = $this->GetConvertedFileQuality(); $fvolume = $this->GetConvertedFileVolume(); $extractor = $this->GetExtractor(); $videoInfo['host_abbrev'] = $extractor->ReturnConfig('abbreviation'); if (!empty($videoInfo) && !empty($videoInfo['title']) && !empty($videoInfo['id']) && !is_null($videoInfo['host_abbrev']) && !empty($ftype)) { $vTitle = html_entity_decode($videoInfo['title'], ENT_COMPAT | ENT_HTML401, 'UTF-8'); $fnameTitle = (!Config::_ENABLE_UNICODE_SUPPORT) ? preg_replace('/[^A-Za-z0-9 _-]/', '', $vTitle) : preg_replace('#/#', '', preg_replace('/\\\\|\/|\?|%|\*|:|\||"|<|>|\]|\[|\(|\)|\.|&|\^|\$|#|@|\!|`|~|=|\+|,|;|\'|\{|\}/', '', $vTitle)); $fnameTitle = preg_replace('/_{2,}/', '_', preg_replace('/ /', '_', $fnameTitle)); $fname = ''; $excessFilenameLength = -1; do { $fnameTitle = ($excessFilenameLength >= 0) ? substr($fnameTitle, 0, strlen($fnameTitle) - $excessFilenameLength - 1) : $fnameTitle; $fname = $fquality . self::_FILENAME_DELIMITER . $fvolume . self::_FILENAME_DELIMITER . $fnameTitle; $fname .= (Config::_ENABLE_CONCURRENCY_CONTROL) ? uniqid('_uuid-') : ''; $fname .= '.' . $ftype; $excessFilenameLength = strlen($fname) - self::_MAX_FILENAME_LENGTH; } while ($excessFilenameLength >= 0); // If file name length is greater than or equal to _MAX_FILENAME_LENGTH bytes, truncate X characters from end of title in file name until the full file name is less than _MAX_FILENAME_LENGTH bytes. $dirName = Config::_CONVERTED_FILEDIR . $videoInfo['host_abbrev'] . '/' . $videoInfo['id'] . '/'; if (!is_dir(realpath($dirName))) mkdir($dirName, 0777, true); $this->_convertedFileName = $dirName . $fname; } //die($this->_convertedFileName); } public function GetVidSourceUrls() { return $this->_vidSourceUrls; } private function SetVidSourceUrls() { $extractor = $this->GetExtractor(); $this->_vidSourceUrls = $extractor->ExtractVidSourceUrls(); } public function GetTempVidFileName() { return $this->_tempVidFileName; } private function SetTempVidFileName() { $extractor = $this->GetExtractor(); $srcVideoType = $extractor->ReturnConfig('src_video_type'); if (!is_null($srcVideoType)) { if (!is_dir(realpath(Config::_TEMPVIDDIR))) mkdir(Config::_TEMPVIDDIR, 0777); $tmpFnameCount = (!empty($this->_tempVidFileName)) ? count($this->_tempVidFileName) + 1 : 1; $tmpFileName = Config::_TEMPVIDDIR . $tmpFnameCount . '_' . $this->_uniqueID . '.' . $srcVideoType; $this->_tempVidFileName = (!empty($this->_tempVidFileName)) ? array_merge($this->_tempVidFileName, array($tmpFileName)) : array($tmpFileName); } //die($this->_tempVidFileName); } public function GetUniqueID() { return $this->_uniqueID; } public function GetConvertedFileTypes() { return $this->_convertedFileTypes; } public function GetVideoHosts() { return $this->_videoHosts; } public function GetCurrentVidHost() { return $this->_currentVidHost; } public function SetCurrentVidHost($hostName) { $this->_currentVidHost = $hostName; } public function GetVidInfo() { return $this->_vidInfo; } public function SetVidInfo($vidInfo) { $this->_vidInfo = $vidInfo; } public function GetConvertedFileType() { return $this->_convertedFileType; } private function SetConvertedFileType($ftype) { $this->_convertedFileType = $ftype; } public function GetConvertedFileCategory() { return $this->_convertedFileCategory; } private function SetConvertedFileCategory($fcat) { $this->_convertedFileCategory = $fcat; } public function GetConvertedFileQuality() { return $this->_convertedFileQuality; } private function SetConvertedFileQuality($quality) { $this->_convertedFileQuality = $quality; } public function GetConvertedFileVolume() { return $this->_convertedFileVolume; } private function SetConvertedFileVolume($volume) { $this->_convertedFileVolume = $volume; } public function GetExtractor() { return $this->_extractor; } public function SetExtractor($vidHostName) { //die(print_r($this->_pluginInfo)); $className = (isset($this->_pluginInfo['AntiCaptcha']['Extractors'][$vidHostName])) ? $this->_pluginInfo['AntiCaptcha']['Extractors'][$vidHostName] : __NAMESPACE__ . "\\extractors\\"; $className .= $vidHostName; try {$this->_extractor = new $className($this);} catch(\Exception $ex) {} } public function GetSkipConversion() { return $this->_skipConversion; } public function GetFFmpegCommand() { return $this->_ffmpegCommand; } public function GetValidationError() { return $this->_validationError; } public function GetOutgoingIP() { return $this->_outgoingIP; } public function SetOutgoingIP() { $noTor = !Config::_ENABLE_TOR_PROXY; $skipIP = false; $outgoingIP = (!$noTor) ? array('ip' => '127.0.0.1', 'port' => Config::_TOR_PROXY_PORT) : array(); $tries = 0; $resetBan = array(); do { if ($noTor) { $resetBan = array(); if (Config::_IP_ROTATION_METHOD == "round-robin") { $ips = Database::Find(Config::_DB_IPS_TABLE, array('order' => array('usage_count'))); $outgoingIP = (!empty($ips)) ? $ips[0] : array(); } else { $ips = Database::Find(Config::_DB_IPS_TABLE, array('order' => array('id'))); $allBanned = true; if (!empty($ips)) { foreach ($ips as $ip) { if ($ip['banned'] == 0) { $outgoingIP = $ip; $allBanned = false; break; } } if ($allBanned) { Database::UpdateAll(Config::_DB_IPS_TABLE, array('banned' => 0)); $ips = Database::Find(Config::_DB_IPS_TABLE, array('order' => array('id'))); $outgoingIP = (!empty($ips)) ? $ips[0] : array(); } } } } if (!empty($outgoingIP)) { if ($this->GetCurrentVidHost() == "YouTube") { $skipIP = ($noTor) ? $outgoingIP['banned'] != 0 && time() - $outgoingIP['banned'] < Config::_IP_BAN_PAUSE : false; if (!$skipIP) { $extractor = $this->GetExtractor(); $ipReqResult = $extractor->CheckIp($outgoingIP); $resetBan = ($noTor) ? (($ipReqResult['isBanned']) ? array('banned' => time()) : array('banned' => 0)) : $resetBan; $skipIP = $ipReqResult['isBanned'] || $ipReqResult['isCurlErr']; if (!$noTor && $skipIP) { $fp = fsockopen($outgoingIP['ip'], Config::_TOR_CONTROL_PORT, $error_number, $err_string, 10); if ($fp !== false) { fwrite($fp, "AUTHENTICATE \"" . Config::_TOR_PROXY_PASSWORD . "\"\n"); $received = fread($fp, 512); fwrite($fp, "signal NEWNYM\n"); $received = fread($fp, 512); fclose($fp); } } } if ($noTor) { Database::Save(Config::_DB_IPS_TABLE, array('id' => $outgoingIP['id'], 'usage_count' => ++$outgoingIP['usage_count']) + $resetBan); } } } $tries++; } while ((empty($outgoingIP) || $skipIP) && $tries < Config::_MAX_CURL_TRIES); $this->_outgoingIP = (empty($outgoingIP)) ? array('ip' => $_SERVER['SERVER_ADDR']) : $outgoingIP; } #endregion } ?> (04) Extractor.php <?php namespace YouTubeMp3Converter\lib\extractors; use YouTubeMp3Converter\lib\Config; use YouTubeMp3Converter\lib\VideoConverter; // Extraction Base Class abstract class Extractor { // Common Fields protected $_converter; protected $_isCurlError = false; protected $_headers = array(); protected $_mainUserAgent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.19 (KHTML, like Gecko) Ubuntu/12.04 Chromium/18.0.1025.168 Chrome/18.0.1025.168 Safari/535.19'; protected $_videoWebpageUrl = ''; protected $_videoWebpage = ''; public $_reqHeaders = array(); // Common Public Methods function __construct(VideoConverter $converter) { $this->_converter = $converter; } function ReturnConfig($setting) { $config = NULL; $converter = $this->GetConverter(); $vidHosts = $converter->GetVideoHosts(); foreach ($vidHosts as $host) { if ($host['name'] == $converter->GetCurrentVidHost() && isset($host[$setting])) { $config = $host[$setting]; break; } } return $config; } function CheckIp($ip) { $noWebpageUrl = empty($this->_videoWebpageUrl); $url = ($noWebpageUrl) ? current($this->ReturnConfig('url_root')) . $this->ReturnConfig('url_example_suffix') : $this->_videoWebpageUrl; $ipReqResult = array("isCurlErr" => false, "isBanned" => false); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); if ($noWebpageUrl) { curl_setopt($ch, CURLOPT_NOBODY, true); curl_setopt($ch, CURLOPT_HEADER, true); } else { curl_setopt($ch, CURLOPT_HEADER, 0); } curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_USERAGENT, $this->GetMainUserAgent()); // Set IP options $isProxy = !empty($ip['port']) || !empty($ip['proxy_user']) || !empty($ip['proxy_pass']); curl_setopt($ch, CURLOPT_REFERER, ''); if ($isProxy) { curl_setopt($ch, CURLOPT_PROXY, $ip['ip'] . ":" . $ip['port']); if (!empty($ip['proxy_user']) && !empty($ip['proxy_pass'])) { curl_setopt($ch, CURLOPT_PROXYUSERPWD, $ip['proxy_user'] . ":" . $ip['proxy_pass']); } if (Config::_ENABLE_TOR_PROXY) { curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); } curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, Config::_IP_CONNECT_TIMEOUT); curl_setopt($ch, CURLOPT_TIMEOUT, Config::_IP_REQUEST_TIMEOUT); } else { curl_setopt($ch, CURLOPT_INTERFACE, $ip['ip']); curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); } curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); $output = curl_exec($ch); $ipReqResult['isCurlErr'] = curl_errno($ch) != 0; if (curl_errno($ch) == 0) { $this->_videoWebpage = (!$noWebpageUrl) ? $output : $this->_videoWebpage; if (!$noWebpageUrl && !empty($output)) { $ipReqResult['isBanned'] = $this->ReturnConfig('name') == "YouTube" && preg_match(YouTube::_CAPTCHA_PATTERN, $output) == 1; } $info = curl_getinfo($ch); //die(print_r($info)); $ipReqResult['isBanned'] = (!$ipReqResult['isBanned']) ? $info['http_code'] == '429' : $ipReqResult['isBanned']; } curl_close($ch); return $ipReqResult; } // Common Protected Methods protected function FileGetContents($url, $postData='', $reqHeaders=array()) { $converter = $this->GetConverter(); if ($converter->GetCurrentVidHost() == "YouTube") { $urlRoot = $this->ReturnConfig('url_root'); $urlRoot = preg_replace('/^(https?)/', "https", $urlRoot[0]); $this->_videoWebpageUrl = (preg_match('/^(' . preg_quote($urlRoot, "/") . ')/', $url) == 1) ? $url : ''; } $file_contents = ''; $tries = 0; do { $this->_headers = array(); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_USERAGENT, $this->GetMainUserAgent()); if (Config::_ENABLE_IP_ROTATION && in_array($converter->GetCurrentVidHost(), array("YouTube", "GoogleDrive", "TikTok"))) { if ($converter->GetOutgoingIP() == array() || $tries > 0) $converter->SetOutgoingIP(); if (!empty($this->_videoWebpageUrl) && !empty($this->_videoWebpage)) { return $this->_videoWebpage; } $currentIP = $converter->GetOutgoingIP(); $isProxy = !empty($currentIP['port']) || !empty($currentIP['proxy_user']) || !empty($currentIP['proxy_pass']); curl_setopt($ch, CURLOPT_REFERER, ''); if ($isProxy) { curl_setopt($ch, CURLOPT_PROXY, $currentIP['ip'] . ":" . $currentIP['port']); if (!empty($currentIP['proxy_user']) && !empty($currentIP['proxy_pass'])) { curl_setopt($ch, CURLOPT_PROXYUSERPWD, $currentIP['proxy_user'] . ":" . $currentIP['proxy_pass']); } if (Config::_ENABLE_TOR_PROXY) { curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); } curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, Config::_IP_CONNECT_TIMEOUT); curl_setopt($ch, CURLOPT_TIMEOUT, Config::_IP_REQUEST_TIMEOUT); } else { curl_setopt($ch, CURLOPT_INTERFACE, $currentIP['ip']); curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); } curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); } if (!empty($postData)) { curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); } if (!empty($reqHeaders)) { curl_setopt($ch, CURLOPT_HTTPHEADER, $reqHeaders); } curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_HEADERFUNCTION, array($this, 'AppendHttpHeader')); $file_contents = curl_exec($ch); $this->_isCurlError = curl_errno($ch) != 0; $curlInfo = curl_getinfo($ch); //print_r($curlInfo); if (curl_errno($ch) == 0) { if ($converter->GetCurrentVidHost() == "YouTube" && ($curlInfo['http_code'] == '302' || $curlInfo['http_code'] == '301')) { if (isset($curlInfo['redirect_url']) && !empty($curlInfo['redirect_url'])) { $file_contents = $this->FileGetContents($curlInfo['redirect_url']); } } } curl_close($ch); $tries++; } while (Config::_ENABLE_IP_ROTATION && in_array($converter->GetCurrentVidHost(), array("YouTube", "GoogleDrive", "TikTok")) && $tries < Config::_MAX_CURL_TRIES && ($this->_isCurlError || $curlInfo['http_code'] == '403' || $curlInfo['http_code'] == '429' || empty($file_contents) || preg_match(YouTube::_CAPTCHA_PATTERN, $file_contents) == 1)); return $file_contents; } protected function AppendHttpHeader($ch, $headr) { $this->_headers[] = $headr; return strlen($headr); } protected function ExtractCookies() { $cookies = ''; $cookieNames = array(); $headers = array_reverse($this->_headers); foreach ($headers as $headr) { $cookies .= (preg_match('/^(Set-Cookie:\s*(\w+)=([^;]+))/i', $headr, $matches) == 1 && !in_array($matches[2], $cookieNames)) ? $matches[2] . "=" . $matches[3] . ";" : ''; $cookieNames[] = $matches[2]; } return trim($cookies, ";"); } // Force child classes to define these methods abstract public function RetrieveVidInfo($vidUrl); abstract public function ExtractVidSourceUrls(); // Common Properties protected function GetConverter() { return $this->_converter; } public function GetMainUserAgent() { return $this->_mainUserAgent; } public function GetVideoWebpage() { return $this->_videoWebpage; } protected function GetStoreDir() { return dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR . 'store' . DIRECTORY_SEPARATOR; } } ?> Hope i can get some help to solve this issue. Thank you kindly.
-
Hello all, I dont know why I'm getting this error with calculating the duration for the video, everything works fine with uploading, file is going in my database and folder, the duration of my video is ok. โhttp://prnt.sc/e59i4f here is my code: // video duration ob_start(); passthru("ffmpeg -i $tmp 2>&1"); $duration = ob_get_contents(); ob_end_clean(); $search='/Duration: (.*?)[.]/'; $duration=preg_match($search, $duration, $matches, PREG_OFFSET_CAPTURE); //error is on this line botom $duration = $matches[1][0]; โ//error is on this line botom list($hours, $mins, $secs) = split('[:]', $duration); //echo "Hours: ".$hours." Minutes: ".$mins." Seconds: ".$secs; $duration=$hours.':'.$mins.':'.$secs;
-
<form name=\"form1\" ACTION=\"$_SERVER[REQUEST_URI]\" METHOD=\"POST\">Your First Name<br><input name=\"first\" value = \"$first\" type=\"text\" id=\"first\" size=\"25\"><br><br>Last Name<br><input name=\"last\" value = \"$last\" type=\"text\" id=\"last\" size=\"25\"><br><br>Email<br><input name=\"email\" value = \"$email\" type=\"text\" id=\"email\" size=\"25\"><br><br>Telephone Number<br><input name=\"phone\" value = \"$phone\" type=\"text\" id=\"phone\" size=\"25\"><br><br><label for=\"comments\">Comments</label><textarea name=\"comments\" cols=\"18\" rows=\"4\" class=\"txt\" id=\"comments\"></textarea><div style=\"visibility:hidden\"><input name=\"email2\" type=\"text\" size=\"45\" id=\"email2\" > </div><input type=\"submit\" name=\"Submit\" value=\"Submit\" class=\"tpc4\"></form>\n"; Hi I am getting the error message Notice: Undefined Index on the following form before submission I would like to fix this rather than suppress errors Any help would be much appreciated
-
hi, can anyone tell me anything wrong with my coding as it keeps mentioned undefined index,id tambahitem.php
-
undefined variable errorString. what's wrong with this? Notice: Undefined variable: errorString in /Applications/XAMPP/xamppfiles/htdocs/finalproject/donate/thankyou.php on line 97 Notice: Undefined variable: messageString in /Applications/XAMPP/xamppfiles/htdocs/finalproject/donate/thankyou.php on line101 <?php require "config.php"; require "connect.php"; if(isset($_POST['submitform']) && isset($_POST['txn_id'])) { $_POST['nameField'] = esc($_POST['nameField']); $_POST['websiteField'] = esc($_POST['websiteField']); $_POST['messageField'] = esc($_POST['messageField']); $error = array(); if(mb_strlen($_POST['nameField'],"utf-8")<2) { $error[] = 'Please fill in a valid name.'; } if(mb_strlen($_POST['messageField'],"utf-8")<2) { $error[] = 'Please fill in a longer message.'; } if(!validateURL($_POST['websiteField'])) { $error[] = 'The URL you entered is invalid.'; } $errorString = ''; if(count($error)) { $errorString = join('<br />',$error); } else { mysql_query(" INSERT INTO dc_comments (transaction_id, name, url, message) VALUES ( '".esc($_POST['txn_id'])."', '".$_POST['nameField']."', '".$_POST['websiteField']."', '".$_POST['messageField']."' )"); if(mysql_affected_rows($link)==1) { $messageString = '<a href="donate.php">You were added to our donor list! ยป</a>'; } } } ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Thank you!</title> <link rel="stylesheet" type="text/css" href="styles.css" /> </head> <body class="thankyouPage"> <div id="main"> <h1>Thank you!</h1> <h2>Add Yourself to our Donor Section</h2> <div class="lightSection"> <form action="" method="post"> <div class="field"> <label for="nameField">Name</label> <input type="text" id="nameField" name="nameField" /> </div> <div class="field"> <label for="websiteField">Web Site</label> <input type="text" id="websiteField" name="websiteField" /> </div> <div class="field"> <label for="messageField">Message</label> <textarea name="messageField" id="messageField"></textarea> </div> <div class="button"> <input type="submit" value="Submit" /> <input type="hidden" name="submitform" value="1" /> <input type="hidden" name="txn_id" value="<?php echo $_POST['txn_id']?>" /> </div> </form> <?php if($errorString) { echo '<p class="error">'.$errorString.'</p>'; } else if($messageString) { echo '<p class="success">'.$messageString.'</p>'; } ?> </div> </body> </html> <?php function esc($str) { global $link; if(ini_get('magic_quotes_gpc')) $str = stripslashes($str); return mysql_real_escape_string(htmlspecialchars(strip_tags($str)),$link); } function validateURL($str) { return preg_match('/(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:\/~\+#]*[\w\-\@?^=%&\/~\+#])?/i',$str); } ?>
-
Hi guys, I have a CMS system which I've spent the last week fixing. It's built in PHP, and now I'm stuck on the most simplest of tasks. I can't figure out why I am receiving an "undefined variable" error within this block of code. Any help would be greatly appreciated. function track_app($app_id, $lang_code, $str, $instance) { $lang_id = get_lang_id($lang_code); if ($instance > 0) { if ($str == 'LOAD_APP' || $str == 'APP_LOADED') { $query = "INSERT INTO `tracking` ( `APPLICATION_ID`, `LANG_ID`, `INFO`, INSTANCE_ID ) VALUES ( $app_id, $lang_id, '$str', $instance )"; } mysql_query("INSERT INTO `tracking_backup` ( `APPLICATION_ID`, `LANG_ID`, `INFO`, INSTANCE_ID ) VALUES ( $app_id, $lang_id, '$str', $instance )"); mysql_query("UPDATE `instances` SET ACTIVE = 1 WHERE INSTANCE_ID = $instance"); } else { $query = "INSERT INTO `tracking` ( `APPLICATION_ID`, `LANG_ID`, `INFO` ) VALUES ( $app_id, $lang_id, '$str' )"; } mysql_query($query); }
-
Well I am having the worst weekend ever. I have been working on this code all day and google is not my friend today. So here is the problem, I am trying to write a form that is basically keeping records of people who have stayed as guest and what meals they ate (breakfast, lunch, dinner, midnight snack). So the html form is pretty simple, and I have a few checkboxes and a little javascript to add more rows if there are more guest. Everything is working fine, but the checkboxes values are killing me. Basically if the box isnt checked than do what? Anyway my insert isnt working at all Anyway here is some basic coding Html form for checkboxes: <td><input type="checkbox" name="breakfast[]" /></td> <td><input type="checkbox" name="lunch[]" /></td> <td><input type="checkbox" name="dinner[]" /></td> <td><input type="checkbox" name="midnight[]" /></td> <td><input type="checkbox" name="lodging[]"/></td> <td><input type="text" name="guestName[]"/></td> So as you can see checkboxes for the meals and a text input for the guest name. Now here is my function (please go easy I am new to pdo) public function createMeal($id,$table){ try{ //write query if(isset($_POST['guestName'])){ $guestName = $_POST['guestName']; $repName = $_POST['repName']; $repTitle = $_POST['repTitle']; if(isset($_POST['breakfast'])){ $breakfast = $_POST['breakfast']; } if(isset($_POST['lunch'])){ $lunch = $_POST['lunch']; } if(isset($_POST['dinner'])){ $dinner = $_POST['dinner']; } if(isset($_POST['midnight'])){ $midnight = $_POST['midnight']; } if(isset($_POST['lodging'])){ $lodging = $_POST['lodging']; } } foreach($guestName as $a => $b) { $query = "INSERT INTO meals(repName, repTitle, breakfast, lunch, dinner, midnight, lodging, guestName, masterLogID) VALUES (:repName, :repTitle, :breakfast, :lunch, :dinner, :midnight, :lodging, :guestName, :masterLogID)"; $stmt = $this->conn->prepare($query); $stmt->bindParam(':repName',$repName[$a]); $stmt->bindParam(':repTitle',$repTitle[$a]); $stmt->bindParam(':breakfast',$breakfast[$a]); $stmt->bindParam(':lunch',$lunch[$a]); $stmt->bindParam(':dinner',$dinner[$a]); $stmt->bindParam(':midnight',$midnight[$a]); $stmt->bindParam(':lodging',$lodging[$a]); $stmt->bindParam(':guestName',$guestName[$a]); $stmt->bindParam(':masterLogID',$masterLogID); // Execute the query $stmt->execute(); } echo "Record was saved."; }catch(PDOException $exception){ //to handle error echo "Error: " . $exception->getMessage(); } } I am getting the message "Record was saved", but nothing is in the table. Any help is greatly appreciated
-
<?php //connect to the database require_once('connectvars.php'); $firstname = ( $_POST['firstname']); $lastname = ( $_POST['lastname']); $username = ( $_POST['username']); $password = ( $_POST['password1']); $email = ( $_POST['email']); //insert data into table $query = "INSERT INTO summerfun_users (username, password, email, first_name, last_name) VALUES ($username, '$password', '$email', '$firstname', '$lastname')"; mysqli_query($dbc, $query); //confirm success with the user echo "congrats friend, you are now a member of summer fun"; ?> i am getting undefined index errors on all my variables, please help
-
I ran through all the possibilities of strings , paranthesis , basically the syntax issues but can seem to figure out whats throwing a fit. It seems lines 15, 16 , 17 are giving problems . <!DOCTYPE html > <html> <head> <title>Buy Your Way to a Better Education!</title> <link href="http://www.cs.washington.edu/education/courses/cse190m/09sp/labs/4-buyagrade/buyagrade.css" type="text/css" rel="stylesheet" /> </head> <body> <h1>Thanks, sucker!</h1> <p>Your information has been recorded.</p> <?php $name = $_POST['name']; $ccNo = $_POST['ccNo']; $ccType = $_POST['ccType']; echo "Your name ". $name . " " . "<br/>"; echo "Credit Card Type:" . $ccType . "<br />"; echo "Credit Card No: " . $ccNo; ?> </body> </html>
-
Shortly I need to block a group of users at once according to their role status (banned or not) instead of blocking users one by one. I tried using fk on update cascade to control the role status by making a fk user_role_status column in the users table refers to role_status column in the roles table but without luck because when I change a role status in roles table it changes the whole user_role_status column in users table not only the role I changed then it blocks all users not only the group I want to block because role_status in roles table is not unique and I can't make it unique because its all cells contain value='1', so I deleted the column and gave up that idea // role_status in roles table is a fk refers to id in statuses table. statuses_table id is_active ------------------ 0 no 1 ok roles_table id role role_status -------------------------------------- 1 Admins 1 2 Editors 1 3 Users 1 users_table id user_name user_level --------------------------------------- 1 Admin 1 2 Editor1 2 3 User1 3 4 Editor2 2 5 User2 3 6 User3 3 and this is the function I use -------------------------------------------------------------- Find role status -------------------------------------------------------------- function find_by_current_rolStatus($role_status) { global $db; $sql = "SELECT users.id FROM users JOIN roles ON roles.id = users.user_level WHERE roles.role_status = '{$db->escape($role_status)}'"; $result = $db->query($sql); return($db->num_rows($result) === 0 ? true : false); } -------------------------------------------------------------- Function for checking if user role status banned or allowed -------------------------------------------------------------- function login_require_roleStatus($require_role_status) { global $session; $current_user = current_user(); $current_user_role_status = find_by_current_rolStatus($current_user['role_status']);//line 155 //if Role status Deactive if ($current_user['role_status'] === '0')://line 157 $session->msg('Banned'); redirect('home.php',false); //if user role allowed elseif($current_user['role_status'] === '1')://line 161 return true; endif; } and I got this error I am trying to get the users whose user_level = role_id which its status = '0' or '1', I checked this SQL query with phpmyadmin and it is working fine, and actually I don't know what to do after that :( , I mean I don't know what to write with $current_user['role_status'] instead of role_status to get what I want.