mirror of
https://github.com/DanielnetoDotCom/YouPHPTube
synced 2025-10-05 19:42:38 +02:00
235 lines
7.4 KiB
PHP
235 lines
7.4 KiB
PHP
<?php
|
|
|
|
|
|
function get_ffmpeg($ignoreGPU = false)
|
|
{
|
|
global $global;
|
|
$complement = ' -user_agent "' . getSelfUserAgent() . '" ';
|
|
//return 'ffmpeg -headers "User-Agent: '.getSelfUserAgent("FFMPEG").'" ';
|
|
$ffmpeg = 'ffmpeg ';
|
|
if (empty($ignoreGPU) && !empty($global['ffmpegGPU'])) {
|
|
$ffmpeg .= ' --enable-nvenc ';
|
|
}
|
|
if (!empty($global['ffmpeg'])) {
|
|
_error_log('get_ffmpeg $global[ffmpeg] detected ' . $global['ffmpeg']);
|
|
$ffmpeg = "{$global['ffmpeg']}{$ffmpeg}";
|
|
} else {
|
|
_error_log('get_ffmpeg default ' . $ffmpeg . $complement);
|
|
}
|
|
return $ffmpeg . $complement;
|
|
}
|
|
|
|
function get_ffprobe() {
|
|
global $global;
|
|
$complement = ' -user_agent "' . getSelfUserAgent() . '" ';
|
|
//return 'ffmpeg -user_agent "'.getSelfUserAgent("FFMPEG").'" ';
|
|
//return 'ffmpeg -headers "User-Agent: '.getSelfUserAgent("FFMPEG").'" ';
|
|
$ffprobe = 'ffprobe ';
|
|
if (!empty($global['ffprobe'])) {
|
|
|
|
$dir = dirname($global['ffprobe']);
|
|
|
|
$ffprobe = "{$dir}/{$ffprobe}";
|
|
}
|
|
return $ffprobe.$complement;
|
|
}
|
|
|
|
function convertVideoToMP3FileIfNotExists($videos_id)
|
|
{
|
|
global $global;
|
|
if (!empty($global['disableMP3'])) {
|
|
return false;
|
|
}
|
|
$video = Video::getVideoLight($videos_id);
|
|
if (empty($video)) {
|
|
return false;
|
|
}
|
|
$types = ['video', 'audio'];
|
|
if (!in_array($video['type'], $types)) {
|
|
return false;
|
|
}
|
|
|
|
$paths = Video::getPaths($video['filename']);
|
|
$mp3File = "{$paths['path']}{$video['filename']}.mp3";
|
|
if (!file_exists($mp3File)) {
|
|
$f = convertVideoFileWithFFMPEGIsLockedInfo($mp3File);
|
|
if ($f['isUnlocked']) {
|
|
$sources = getVideosURLOnly($video['filename'], false);
|
|
|
|
if (!empty($sources)) {
|
|
$source = end($sources);
|
|
convertVideoFileWithFFMPEG($source['url'], $mp3File);
|
|
if (file_exists($mp3File)) {
|
|
return Video::getSourceFile($video['filename'], ".mp3", true);
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
} else {
|
|
return Video::getSourceFile($video['filename'], ".mp3", true);
|
|
}
|
|
}
|
|
|
|
function m3u8ToMP4($input)
|
|
{
|
|
$videosDir = getVideosDir();
|
|
$outputfilename = str_replace($videosDir, "", $input);
|
|
$parts = explode("/", $outputfilename);
|
|
$resolution = Video::getResolutionFromFilename($input);
|
|
$outputfilename = $parts[0] . "_{$resolution}_.mp4";
|
|
$outputpath = "{$videosDir}cache/downloads/{$outputfilename}";
|
|
$msg = '';
|
|
$error = true;
|
|
if (empty($outputfilename)) {
|
|
$msg = "downloadHLS: empty outputfilename {$outputfilename}";
|
|
_error_log($msg);
|
|
return ['error' => $error, 'msg' => $msg];
|
|
}
|
|
_error_log("downloadHLS: m3u8ToMP4($input)");
|
|
//var_dump(!preg_match('/^http/i', $input), filesize($input), preg_match('/.m3u8$/i', $input));
|
|
$ism3u8 = preg_match('/.m3u8$/i', $input);
|
|
if (!preg_match('/^http/i', $input) && (filesize($input) <= 10 || $ism3u8)) { // dummy file
|
|
$filepath = pathToRemoteURL($input, true, true);
|
|
if ($ism3u8 && !preg_match('/.m3u8$/i', $filepath)) {
|
|
$filepath = addLastSlash($filepath) . 'index.m3u8';
|
|
}
|
|
|
|
$token = getToken(60);
|
|
$filepath = addQueryStringParameter($filepath, 'globalToken', $token);
|
|
} else {
|
|
$filepath = escapeshellcmd($input);
|
|
}
|
|
|
|
if (is_dir($filepath)) {
|
|
$filepath = addLastSlash($filepath) . 'index.m3u8';
|
|
}
|
|
|
|
if (!file_exists($outputpath)) {
|
|
//var_dump('m3u8ToMP4 !file_exists', $filepath, $outputpath);
|
|
//exit;
|
|
$return = convertVideoFileWithFFMPEG($filepath, $outputpath);
|
|
//var_dump($return);
|
|
//exit;
|
|
if (empty($return)) {
|
|
$msg3 = "downloadHLS: ERROR 2 ";
|
|
$finalMsg = $msg . PHP_EOL . $msg3;
|
|
_error_log($msg3);
|
|
return ['error' => $error, 'msg' => $finalMsg];
|
|
} else {
|
|
return $return;
|
|
}
|
|
} else {
|
|
$msg = "downloadHLS: outputpath already exists ({$outputpath})";
|
|
_error_log($msg);
|
|
}
|
|
$error = false;
|
|
return ['error' => $error, 'msg' => $msg, 'path' => $outputpath, 'filename' => $outputfilename];
|
|
}
|
|
|
|
function getConvertVideoFileWithFFMPEGProgressFilename($toFileLocation)
|
|
{
|
|
$progressFile = $toFileLocation . '.log';
|
|
return $progressFile;
|
|
}
|
|
|
|
function convertVideoToDownlaodProgress($toFileLocation)
|
|
{
|
|
$progressFile = getConvertVideoFileWithFFMPEGProgressFilename($toFileLocation);
|
|
return parseFFMPEGProgress($progressFile);
|
|
}
|
|
|
|
function parseFFMPEGProgress($progressFilename)
|
|
{
|
|
//get duration of source
|
|
$obj = new stdClass();
|
|
|
|
$obj->duration = 0;
|
|
$obj->currentTime = 0;
|
|
$obj->progress = 0;
|
|
$obj->from = '';
|
|
$obj->to = '';
|
|
if (!file_exists($progressFilename)) {
|
|
return $obj;
|
|
}
|
|
|
|
$obj->filemtime = filemtime($progressFilename);
|
|
$obj->secondsOld = time() - $obj->filemtime;
|
|
|
|
$content = url_get_contents($progressFilename);
|
|
if (empty($content)) {
|
|
return $obj;
|
|
}
|
|
//var_dump($content);exit;
|
|
preg_match("/Duration: (.*?), start:/", $content, $matches);
|
|
if (!empty($matches[1])) {
|
|
$rawDuration = $matches[1];
|
|
|
|
//rawDuration is in 00:00:00.00 format. This converts it to seconds.
|
|
$ar = array_reverse(explode(":", $rawDuration));
|
|
$duration = floatval($ar[0]);
|
|
if (!empty($ar[1])) {
|
|
$duration += intval($ar[1]) * 60;
|
|
}
|
|
if (!empty($ar[2])) {
|
|
$duration += intval($ar[2]) * 60 * 60;
|
|
}
|
|
|
|
//get the time in the file that is already encoded
|
|
preg_match_all("/time=(.*?) bitrate/", $content, $matches);
|
|
|
|
$rawTime = array_pop($matches);
|
|
|
|
//this is needed if there is more than one match
|
|
if (is_array($rawTime)) {
|
|
$rawTime = array_pop($rawTime);
|
|
}
|
|
if (empty($rawTime)) {
|
|
$rawTime = '00:00:00.00';
|
|
}
|
|
//rawTime is in 00:00:00.00 format. This converts it to seconds.
|
|
$ar = array_reverse(explode(":", $rawTime));
|
|
$time = floatval($ar[0]);
|
|
if (!empty($ar[1])) {
|
|
$time += intval($ar[1]) * 60;
|
|
}
|
|
if (!empty($ar[2])) {
|
|
$time += intval($ar[2]) * 60 * 60;
|
|
}
|
|
|
|
if (!empty($duration)) {
|
|
//calculate the progress
|
|
$progress = round(($time / $duration) * 100);
|
|
} else {
|
|
$progress = 'undefined';
|
|
}
|
|
$obj->duration = $duration;
|
|
$obj->currentTime = $time;
|
|
$obj->remainTime = ($obj->duration - $time);
|
|
$obj->remainTimeHuman = secondsToVideoTime($obj->remainTime);
|
|
$obj->progress = $progress;
|
|
}
|
|
|
|
preg_match("/Input[a-z0-9 #,]+from '([^']+)':/", $content, $matches);
|
|
if (!empty($matches[1])) {
|
|
$path_parts = pathinfo($matches[1]);
|
|
$partsExtension = explode('?', $path_parts['extension']);
|
|
$obj->from = $partsExtension[0];
|
|
}
|
|
|
|
preg_match("/Output[a-z0-9 #,]+to '([^']+)':/", $content, $matches);
|
|
if (!empty($matches[1])) {
|
|
$path_parts = pathinfo($matches[1]);
|
|
$partsExtension = explode('?', $path_parts['extension']);
|
|
$obj->to = $partsExtension[0];
|
|
}
|
|
|
|
return $obj;
|
|
}
|
|
|
|
|
|
function removeUserAgentIfNotURL($cmd){
|
|
if (!preg_match('/ -i [\'"]?https?:/i', $cmd) && !preg_match('/ffprobe.*[\'"]?https?:/i', $cmd)) {
|
|
$cmd = preg_replace('/-user_agent "[^"]+"/', '', $cmd);
|
|
}
|
|
return $cmd;
|
|
}
|