first commit
This commit is contained in:
commit
d2db6d0376
|
|
@ -0,0 +1,99 @@
|
|||
Urmi Downloader / Converter
|
||||
----------------------------------------
|
||||
|
||||
Yt-dlp webui
|
||||
Samba share to access
|
||||
FFmpeg to convert files
|
||||
|
||||
Instalation
|
||||
----------------------------------------
|
||||
|
||||
Install Ubuntu server 24.04 and run following commands as root
|
||||
|
||||
cd /tmp
|
||||
apt install git -y
|
||||
cd /tmp
|
||||
git clone --depth 1 https://git.dbhatt.org/hw_partner/urmic_digital_encoder_decoder.git
|
||||
cd urmic_digital_encoder_decoder
|
||||
chmod +x install.sh
|
||||
./install.sh
|
||||
|
||||
after reboot visit http://IP
|
||||
default Username :- shreebhattji
|
||||
default password :- foreverstreamingpartner
|
||||
|
||||
Under Licence https://github.com/shreebhattji/Urmi
|
||||
|
||||
|
||||
Urmi an "you happy me happy" license
|
||||
----------------------------------------
|
||||
|
||||
|
||||
In the name , memory and honor of
|
||||
|
||||
|
||||
Every single mother who given birth , love , part of it self to their child ,
|
||||
|
||||
Every single father who fulfilled his every single duty ,
|
||||
|
||||
Every single teacher who taught human and made civilization possible ,
|
||||
|
||||
Every single warrior who stood still and took a fall on own self for protection of other ,
|
||||
|
||||
Every single savior who risked their life own life to save others ,
|
||||
|
||||
Every single power who helped individuals in the greatest hour of need ,
|
||||
|
||||
Every single artist who made human life happy , pleasant and colorful ,
|
||||
|
||||
Every single human who ever walked and contributed to constructive work of humanity.
|
||||
|
||||
Every single Power ever existed in universe who done good
|
||||
|
||||
|
||||
This is given to every single human , goverment , NGO , educational institutes .
|
||||
|
||||
If you use things under this licence you have to spend 11$ or more (US dollar) for one of the following in ascending order.
|
||||
|
||||
|
||||
1 > If you have a sister, hand over 11$ or more to her .
|
||||
|
||||
2 > If you have a loan on you, repay 11$ or more extra .
|
||||
|
||||
3 > If your parents ever taken care of you, hand over 11$ or more to them .
|
||||
|
||||
4 > If any relative ever helped you , find some family members in need and send them 11$ or more.
|
||||
|
||||
5 > If you ever enjoyed any service from your state, donate 11$ or more to your state .
|
||||
|
||||
6 > If you are protected in your country, donate 11$ or more to your country .
|
||||
|
||||
7 > we came empty handed and we go empty handed from earth, however while on earth if you ever got help please help others .
|
||||
|
||||
|
||||
Distribution Rules
|
||||
----------------------------------------------------------------------
|
||||
work published under this licence can be obtained by any entity .
|
||||
|
||||
work published under this licence is permenent and only share able with same licene , selling ,leasing reselling or doing any thing else is illigal .
|
||||
|
||||
|
||||
|
||||
What about me ... ??? hmmmmmmm
|
||||
-----------------------------------
|
||||
|
||||
To achieve any goal in life anyone need to have two main things "GOOD KARMA" and "BLESSINGS" ,
|
||||
|
||||
I am taking care of good karma ,now providing blessing is gods responsibility .
|
||||
|
||||
We all have only one life , death is only truth of our life.
|
||||
|
||||
I wish every soul a life with good health ,happy family ,mighty power , highest respect and unlimited fortune.
|
||||
|
||||
- With faith and hope
|
||||
|
||||
|
||||
|
||||
Notice :- We do not accept any kind of donation in any way in any manner.
|
||||
|
||||
If you dont spend 11$ or more after seeing this email god will transfer all of your good KARMA to my account so dont forgot to spend 11$ or more according to licence.
|
||||
|
|
@ -0,0 +1,208 @@
|
|||
<?php
|
||||
include_once('FileHandler.php');
|
||||
|
||||
class Downloader
|
||||
{
|
||||
private $urls = [];
|
||||
private $config = [];
|
||||
private $audio_only = false;
|
||||
private $errors = [];
|
||||
private $download_path = "";
|
||||
|
||||
public function __construct($post, $audio_only)
|
||||
{
|
||||
$this->config = require dirname(__DIR__).'/config/config.php';
|
||||
|
||||
$this->download_path = (new FileHandler())->get_downloads_folder();
|
||||
|
||||
$this->audio_only = $audio_only;
|
||||
$this->urls = explode(",", $post);
|
||||
|
||||
if(!$this->check_requirements($audio_only))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->urls as $url)
|
||||
{
|
||||
if(!$this->is_valid_url($url))
|
||||
{
|
||||
$this->errors[] = "\"".$url."\" is not a valid url !";
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($this->errors) && count($this->errors) > 0)
|
||||
{
|
||||
$_SESSION['errors'] = $this->errors;
|
||||
return;
|
||||
}
|
||||
|
||||
if($this->config["max_dl"] == 0)
|
||||
{
|
||||
$this->do_download();
|
||||
}
|
||||
elseif($this->config["max_dl"] > 0)
|
||||
{
|
||||
if($this->background_jobs() >= 0 && $this->background_jobs() < $this->config["max_dl"])
|
||||
{
|
||||
$this->do_download();
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->errors[] = "Simultaneous downloads limit reached !";
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($this->errors) && count($this->errors) > 0)
|
||||
{
|
||||
$_SESSION['errors'] = $this->errors;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public static function background_jobs()
|
||||
{
|
||||
return shell_exec("ps aux | grep -v grep | grep -v \"yt-dlp -U\" | grep yt-dlp | wc -l");
|
||||
}
|
||||
|
||||
public static function max_background_jobs()
|
||||
{
|
||||
$config = require dirname(__DIR__).'/config/config.php';
|
||||
return $config["max_dl"];
|
||||
}
|
||||
|
||||
public static function get_current_background_jobs()
|
||||
{
|
||||
exec("ps -A -o user,pid,etime,cmd | grep -v grep | grep -v \"yt-dlp -U\" | grep yt-dlp", $output);
|
||||
|
||||
$bjs = [];
|
||||
|
||||
if(count($output) > 0)
|
||||
{
|
||||
foreach($output as $line)
|
||||
{
|
||||
$line = explode(' ', preg_replace ("/ +/", " ", $line), 4);
|
||||
$bjs[] = array(
|
||||
'user' => $line[0],
|
||||
'pid' => $line[1],
|
||||
'time' => $line[2],
|
||||
'cmd' => $line[3]
|
||||
);
|
||||
}
|
||||
|
||||
return $bjs;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static function kill_them_all()
|
||||
{
|
||||
exec("ps -A -o pid,cmd | grep -v grep | grep yt-dlp | awk '{print $1}'", $output);
|
||||
|
||||
if(count($output) <= 0)
|
||||
return;
|
||||
|
||||
foreach($output as $p)
|
||||
{
|
||||
shell_exec("kill ".$p);
|
||||
}
|
||||
|
||||
$config = require dirname(__DIR__).'/config/config.php';
|
||||
$folder = $this->download_path;
|
||||
|
||||
foreach(glob($folder.'*.part') as $file)
|
||||
{
|
||||
unlink($file);
|
||||
}
|
||||
}
|
||||
|
||||
private function check_requirements($audio_only)
|
||||
{
|
||||
if($this->is_youtubedl_installed() != 0)
|
||||
{
|
||||
$this->errors[] = "yt-dlp is not installed, see <a>https://rg3.github.io/yt-dlp/download.html</a> !";
|
||||
}
|
||||
|
||||
$this->check_outuput_folder();
|
||||
|
||||
if($audio_only)
|
||||
{
|
||||
if($this->is_extracter_installed() != 0)
|
||||
{
|
||||
$this->errors[] = "Install an audio extracter (ex: avconv) !";
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($this->errors) && count($this->errors) > 0)
|
||||
{
|
||||
$_SESSION['errors'] = $this->errors;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function is_youtubedl_installed()
|
||||
{
|
||||
exec("which yt-dlp", $out, $r);
|
||||
return $r;
|
||||
}
|
||||
|
||||
private function is_extracter_installed()
|
||||
{
|
||||
exec("which ".$this->config["extracter"], $out, $r);
|
||||
return $r;
|
||||
}
|
||||
|
||||
private function is_valid_url($url)
|
||||
{
|
||||
return filter_var($url, FILTER_VALIDATE_URL);
|
||||
}
|
||||
|
||||
private function check_outuput_folder()
|
||||
{
|
||||
if(!is_dir($this->download_path))
|
||||
{
|
||||
//Folder doesn't exist
|
||||
if(!mkdir($this->download_path, 0775))
|
||||
{
|
||||
$this->errors[] = "Output folder doesn't exist and creation failed !";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Exists but can I write ?
|
||||
if(!is_writable($this->download_path))
|
||||
{
|
||||
$this->errors[] = "Output folder isn't writable !";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function do_download()
|
||||
{
|
||||
$cmd = "yt-dlp -f 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/bestvideo+bestaudio' --merge-output-format mp4";
|
||||
$cmd .= " -o ".$this->download_path."/";
|
||||
$cmd .= escapeshellarg("%(title)s.%(ext)s");
|
||||
|
||||
if($this->audio_only)
|
||||
{
|
||||
$cmd .= " -x --audio-format mp3 ";
|
||||
}
|
||||
|
||||
foreach($this->urls as $url)
|
||||
{
|
||||
$cmd .= " ".escapeshellarg($url);
|
||||
}
|
||||
|
||||
$cmd .= " --restrict-filenames"; // --restrict-filenames is for specials chars
|
||||
$cmd .= " > /dev/null & echo $!";
|
||||
|
||||
shell_exec($cmd);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
<?php
|
||||
|
||||
class FileHandler
|
||||
{
|
||||
private $config = [];
|
||||
private $videos_ext = ".{avi,mp4,flv,webm,mkv}";
|
||||
private $musics_ext = ".{mp3,ogg,m4a,opus}";
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->config = require dirname(__DIR__).'/config/config.php';
|
||||
}
|
||||
|
||||
public function listVideos()
|
||||
{
|
||||
$videos = [];
|
||||
|
||||
if(!$this->outuput_folder_exists())
|
||||
return;
|
||||
|
||||
$folder = $this->get_downloads_folder().'/';
|
||||
|
||||
foreach(glob($folder.'*'.$this->videos_ext, GLOB_BRACE) as $file)
|
||||
{
|
||||
$video = [];
|
||||
$video["name"] = str_replace($folder, "", $file);
|
||||
$video["size"] = $this->to_human_filesize(filesize($file));
|
||||
|
||||
$videos[] = $video;
|
||||
}
|
||||
|
||||
return $videos;
|
||||
}
|
||||
|
||||
public function listMusics()
|
||||
{
|
||||
$musics = [];
|
||||
|
||||
if(!$this->outuput_folder_exists())
|
||||
return;
|
||||
|
||||
$folder = $this->get_downloads_folder().'/';
|
||||
|
||||
foreach(glob($folder.'*'.$this->musics_ext, GLOB_BRACE) as $file)
|
||||
{
|
||||
$music = [];
|
||||
$music["name"] = str_replace($folder, "", $file);
|
||||
$music["size"] = $this->to_human_filesize(filesize($file));
|
||||
|
||||
$musics[] = $music;
|
||||
}
|
||||
|
||||
return $musics;
|
||||
}
|
||||
|
||||
public function delete($id, $type)
|
||||
{
|
||||
$folder = $this->get_downloads_folder().'/';
|
||||
$i = 0;
|
||||
|
||||
if($type === 'v')
|
||||
{
|
||||
$exts = $this->videos_ext;
|
||||
}
|
||||
elseif($type === 'm')
|
||||
{
|
||||
$exts = $this->musics_ext;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach(glob($folder.'*'.$exts, GLOB_BRACE) as $file)
|
||||
{
|
||||
if($i == $id)
|
||||
{
|
||||
unlink($file);
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
private function outuput_folder_exists()
|
||||
{
|
||||
if(!is_dir($this->get_downloads_folder()))
|
||||
{
|
||||
//Folder doesn't exist
|
||||
if(!mkdir($this->get_downloads_folder(),0777))
|
||||
{
|
||||
return false; //No folder and creation failed
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function to_human_filesize($bytes, $decimals = 0)
|
||||
{
|
||||
$sz = 'BKMGTP';
|
||||
$factor = floor((strlen($bytes) - 1) / 3);
|
||||
return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$sz[$factor];
|
||||
}
|
||||
|
||||
public function free_space()
|
||||
{
|
||||
return $this->to_human_filesize(disk_free_space($this->get_downloads_folder()));
|
||||
}
|
||||
|
||||
public function get_downloads_folder()
|
||||
{
|
||||
$path = $this->config["outputFolder"];
|
||||
if(strpos($path , "/") !== 0)
|
||||
{
|
||||
$path = dirname(__DIR__).'/' . $path;
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
class Session
|
||||
{
|
||||
private $config = [];
|
||||
|
||||
private static $_instance;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
session_start();
|
||||
|
||||
$this->config = require dirname(__DIR__).'/config/config.php';
|
||||
|
||||
if($this->config["security"])
|
||||
{
|
||||
if(!isset($_SESSION["logged_in"]))
|
||||
{
|
||||
$_SESSION["logged_in"] = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$_SESSION["logged_in"] = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static function getInstance()
|
||||
{
|
||||
if(is_null(self::$_instance))
|
||||
{
|
||||
self::$_instance = new Session();
|
||||
}
|
||||
|
||||
return self::$_instance;
|
||||
}
|
||||
|
||||
public function login($password)
|
||||
{
|
||||
if($this->config["password"] === md5($password))
|
||||
{
|
||||
$_SESSION["logged_in"] = true;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$_SESSION["logged_in"] = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function is_logged_in()
|
||||
{
|
||||
return $_SESSION["logged_in"];
|
||||
}
|
||||
|
||||
public function logout()
|
||||
{
|
||||
$_SESSION = array();
|
||||
session_destroy();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
// Mahadev@123 password
|
||||
|
||||
return array(
|
||||
"security" => true,
|
||||
"password" => "efd6f45f7fe2cf3a2f0bd3812b201fc0",
|
||||
"outputFolder" => "/var/www/html/download",
|
||||
"extracter" => "ffmpeg",
|
||||
"max_dl" => 10);
|
||||
|
||||
?>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,200 @@
|
|||
<?php
|
||||
|
||||
require_once 'class/Session.php';
|
||||
require_once 'class/Downloader.php';
|
||||
require_once 'class/FileHandler.php';
|
||||
|
||||
$session = Session::getInstance();
|
||||
$file = new FileHandler;
|
||||
|
||||
if(!$session->is_logged_in())
|
||||
{
|
||||
header("Location: login.php");
|
||||
}
|
||||
|
||||
###############################################################
|
||||
# File Download 1.31
|
||||
###############################################################
|
||||
# Visit http://www.zubrag.com/scripts/ for updates
|
||||
###############################################################
|
||||
# Sample call:
|
||||
# download.php?f=phptutorial.zip
|
||||
#
|
||||
# Sample call (browser will try to save with new file name):
|
||||
# download.php?f=phptutorial.zip&fc=php123tutorial.zip
|
||||
###############################################################
|
||||
|
||||
// Allow direct file download (hotlinking)?
|
||||
// Empty - allow hotlinking
|
||||
// If set to nonempty value (Example: example.com) will only allow downloads when referrer contains this text
|
||||
define('ALLOWED_REFERRER', '');
|
||||
|
||||
// Download folder, i.e. folder where you keep all files for download.
|
||||
// MUST end with slash (i.e. "/" )
|
||||
define('BASE_DIR',$file->get_downloads_folder());
|
||||
|
||||
// log downloads? true/false
|
||||
define('LOG_DOWNLOADS',true);
|
||||
|
||||
// log file name
|
||||
define('LOG_FILE','downloads.log');
|
||||
|
||||
// Allowed extensions list in format 'extension' => 'mime type'
|
||||
// If myme type is set to empty string then script will try to detect mime type
|
||||
// itself, which would only work if you have Mimetype or Fileinfo extensions
|
||||
// installed on server.
|
||||
$allowed_ext = array (
|
||||
|
||||
// audio
|
||||
'mp3' => 'audio/mpeg',
|
||||
'wav' => 'audio/x-wav',
|
||||
|
||||
// video
|
||||
'mpeg' => 'video/mpeg',
|
||||
'mpg' => 'video/mpeg',
|
||||
'mpe' => 'video/mpeg',
|
||||
'mkv' => 'video/mpeg',
|
||||
'mp4' => 'video/mpeg',
|
||||
'mov' => 'video/quicktime',
|
||||
'avi' => 'video/x-msvideo',
|
||||
'webm' => 'video/mpeg'
|
||||
);
|
||||
|
||||
|
||||
|
||||
####################################################################
|
||||
### DO NOT CHANGE BELOW
|
||||
####################################################################
|
||||
|
||||
// If hotlinking not allowed then make hackers think there are some server problems
|
||||
if (ALLOWED_REFERRER !== ''
|
||||
&& (!isset($_SERVER['HTTP_REFERER']) || strpos(strtoupper($_SERVER['HTTP_REFERER']),strtoupper(ALLOWED_REFERRER)) === false)
|
||||
) {
|
||||
die("Internal server error. Please contact system administrator.");
|
||||
}
|
||||
|
||||
// Make sure program execution doesn't time out
|
||||
// Set maximum script execution time in seconds (0 means no limit)
|
||||
set_time_limit(0);
|
||||
|
||||
if (!isset($_GET['f']) || empty($_GET['f'])) {
|
||||
die("Please specify file name for download.");
|
||||
}
|
||||
|
||||
// Nullbyte hack fix
|
||||
if (strpos($_GET['f'], "\0") !== FALSE) die('');
|
||||
|
||||
// Get real file name.
|
||||
// Remove any path info to avoid hacking by adding relative path, etc.
|
||||
$fname = basename($_GET['f']);
|
||||
|
||||
// Check if the file exists
|
||||
// Check in subfolders too
|
||||
function find_file ($dirname, $fname, &$file_path) {
|
||||
|
||||
$dir = opendir($dirname);
|
||||
|
||||
while ($file = readdir($dir)) {
|
||||
if (empty($file_path) && $file != '.' && $file != '..') {
|
||||
if (is_dir($dirname.'/'.$file)) {
|
||||
find_file($dirname.'/'.$file, $fname, $file_path);
|
||||
}
|
||||
else {
|
||||
if (file_exists($dirname.'/'.$fname)) {
|
||||
$file_path = $dirname.'/'.$fname;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // find_file
|
||||
|
||||
// get full file path (including subfolders)
|
||||
$file_path = '';
|
||||
find_file(BASE_DIR, $fname, $file_path);
|
||||
|
||||
if (!is_file($file_path)) {
|
||||
die("File does not exist. Make sure you specified correct file name.");
|
||||
}
|
||||
|
||||
// file size in bytes
|
||||
$fsize = filesize($file_path);
|
||||
|
||||
// file extension
|
||||
$fext = strtolower(substr(strrchr($fname,"."),1));
|
||||
|
||||
// check if allowed extension
|
||||
if (!array_key_exists($fext, $allowed_ext)) {
|
||||
die("Not allowed file type.");
|
||||
}
|
||||
|
||||
// get mime type
|
||||
if ($allowed_ext[$fext] == '') {
|
||||
$mtype = '';
|
||||
// mime type is not set, get from server settings
|
||||
if (function_exists('mime_content_type')) {
|
||||
$mtype = mime_content_type($file_path);
|
||||
}
|
||||
else if (function_exists('finfo_file')) {
|
||||
$finfo = finfo_open(FILEINFO_MIME); // return mime type
|
||||
$mtype = finfo_file($finfo, $file_path);
|
||||
finfo_close($finfo);
|
||||
}
|
||||
if ($mtype == '') {
|
||||
$mtype = "application/force-download";
|
||||
}
|
||||
}
|
||||
else {
|
||||
// get mime type defined by admin
|
||||
$mtype = $allowed_ext[$fext];
|
||||
}
|
||||
|
||||
// Browser will try to save file with this filename, regardless original filename.
|
||||
// You can override it if needed.
|
||||
|
||||
if (!isset($_GET['fc']) || empty($_GET['fc'])) {
|
||||
$asfname = $fname;
|
||||
}
|
||||
else {
|
||||
// remove some bad chars
|
||||
$asfname = str_replace(array('"',"'",'\\','/'), '', $_GET['fc']);
|
||||
if ($asfname === '') $asfname = 'NoName';
|
||||
}
|
||||
|
||||
// set headers
|
||||
header("Pragma: public");
|
||||
header("Expires: 0");
|
||||
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
|
||||
header("Cache-Control: public");
|
||||
header("Content-Description: File Transfer");
|
||||
header("Content-Type: $mtype");
|
||||
header("Content-Disposition: attachment; filename=\"$asfname\"");
|
||||
header("Content-Transfer-Encoding: binary");
|
||||
header("Content-Length: " . $fsize);
|
||||
|
||||
// download
|
||||
// @readfile($file_path);
|
||||
$file = @fopen($file_path,"rb");
|
||||
if ($file) {
|
||||
while(!feof($file)) {
|
||||
print(fread($file, 1024*8));
|
||||
flush();
|
||||
if (connection_status()!=0) {
|
||||
@fclose($file);
|
||||
die();
|
||||
}
|
||||
}
|
||||
@fclose($file);
|
||||
}
|
||||
|
||||
// log downloads
|
||||
if (!LOG_DOWNLOADS) die();
|
||||
|
||||
$f = @fopen(LOG_FILE, 'a+');
|
||||
if ($f) {
|
||||
@fputs($f, date("m.d.Y g:ia")." ".$_SERVER['REMOTE_ADDR']." ".$fname."\n");
|
||||
@fclose($f);
|
||||
}
|
||||
|
||||
?>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 318 B |
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 93 KiB |
|
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
require_once 'class/Session.php';
|
||||
require_once 'class/Downloader.php';
|
||||
require_once 'class/FileHandler.php';
|
||||
|
||||
$session = Session::getInstance();
|
||||
$file = new FileHandler;
|
||||
|
||||
require 'views/header.php';
|
||||
|
||||
if(!$session->is_logged_in())
|
||||
{
|
||||
header("Location: login.php");
|
||||
}
|
||||
else
|
||||
{
|
||||
if(isset($_GET['kill']) && !empty($_GET['kill']) && $_GET['kill'] === "all")
|
||||
{
|
||||
Downloader::kill_them_all();
|
||||
}
|
||||
|
||||
if(isset($_POST['urls']) && !empty($_POST['urls']))
|
||||
{
|
||||
$audio_only = false;
|
||||
|
||||
if(isset($_POST['audio']) && !empty($_POST['audio']))
|
||||
{
|
||||
$audio_only = true;
|
||||
}
|
||||
|
||||
$downloader = new Downloader($_POST['urls'], $audio_only);
|
||||
|
||||
if(!isset($_SESSION['errors']))
|
||||
{
|
||||
header("Location: index.php");
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<div class="container">
|
||||
<h1>Download</h1>
|
||||
<?php
|
||||
|
||||
if(isset($_SESSION['errors']) && $_SESSION['errors'] > 0)
|
||||
{
|
||||
foreach ($_SESSION['errors'] as $e)
|
||||
{
|
||||
echo "<div class=\"alert alert-warning\" role=\"alert\">$e</div>";
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<form id="download-form" class="form-horizontal" action="index.php" method="post">
|
||||
<div class="form-group">
|
||||
<div class="col-md-10">
|
||||
<input class="form-control" id="url" name="urls" placeholder="Link(s) separated by a comma" type="text">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" name="audio"> Audio Only
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Download</button>
|
||||
</form>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading"><h3 class="panel-title">Info</h3></div>
|
||||
<div class="panel-body">
|
||||
<p>Free space : <?php echo $file->free_space(); ?></b></p>
|
||||
<p>Download folder : <?php echo $file->get_downloads_folder(); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading"><h3 class="panel-title">Help</h3></div>
|
||||
<div class="panel-body">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
unset($_SESSION['errors']);
|
||||
require 'views/footer.php';
|
||||
?>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
require_once 'class/Session.php';
|
||||
require_once 'class/Downloader.php';
|
||||
require_once 'class/FileHandler.php';
|
||||
|
||||
$session = Session::getInstance();
|
||||
$file = new FileHandler;
|
||||
|
||||
if(!$session->is_logged_in())
|
||||
{
|
||||
header("Location: login.php");
|
||||
}
|
||||
|
||||
if(isset($_GET['type']) && !empty($_GET['type']))
|
||||
{
|
||||
$t = $_GET['type'];
|
||||
if($t === 'v')
|
||||
{
|
||||
$type = "videos";
|
||||
$files = $file->listVideos();
|
||||
}
|
||||
elseif($t === 'm')
|
||||
{
|
||||
$type = "musics";
|
||||
$files = $file->listMusics();
|
||||
}
|
||||
}
|
||||
|
||||
if($session->is_logged_in() && isset($_GET["delete"]))
|
||||
{
|
||||
$file->delete($_GET["delete"], $t);
|
||||
header("Location: list.php?type=".$t);
|
||||
}
|
||||
|
||||
require 'views/header.php';
|
||||
?>
|
||||
<div class="container">
|
||||
<?php
|
||||
if(!empty($files))
|
||||
{
|
||||
?>
|
||||
<h2>List of available <?php echo $type ?> :</h2>
|
||||
<table class="table table-striped table-hover ">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="min-width:800px; height:35px">Title</th>
|
||||
<th style="min-width:80px">Size</th>
|
||||
<th style="min-width:80px">Play</th>
|
||||
<th style="min-width:80px">Download</th>
|
||||
<th style="min-width:110px">Delete link</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$i = 0;
|
||||
$totalSize = 0;
|
||||
|
||||
foreach($files as $f)
|
||||
{
|
||||
echo "<tr>";
|
||||
echo "<td>".$f["name"]."</td>";
|
||||
echo "<td>".$f["size"]."</td>";
|
||||
echo "<td><a href=\play.php?f=".$f["name"]." class=\"btn btn-danger btn-sm\">Play</a></td>";
|
||||
echo "<td><a href=\download.php?f=".$f["name"]." class=\"btn btn-danger btn-sm\">Download</a></td>";
|
||||
echo "<td><a href=\"./list.php?delete=$i&type=$t\" class=\"btn btn-danger btn-sm\">Delete</a></td>";
|
||||
echo "</tr>";
|
||||
$i++;
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
<br/>
|
||||
<br/>
|
||||
<?php
|
||||
}
|
||||
else
|
||||
{
|
||||
if(isset($t) && ($t === 'v' || $t === 'm'))
|
||||
{
|
||||
echo "<br><div class=\"alert alert-warning\" role=\"alert\">No $type !</div>";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "<br><div class=\"alert alert-warning\" role=\"alert\">No such type !</div>";
|
||||
}
|
||||
}
|
||||
?>
|
||||
<br/>
|
||||
</div><!-- End container -->
|
||||
<?php
|
||||
require 'views/footer.php';
|
||||
?>
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
require_once 'class/Session.php';
|
||||
require_once 'class/Downloader.php';
|
||||
|
||||
$session = Session::getInstance();
|
||||
$loginError = "";
|
||||
|
||||
if(isset($_POST["password"]))
|
||||
{
|
||||
if($session->login($_POST["password"]))
|
||||
{
|
||||
header("Location: index.php");
|
||||
}
|
||||
else
|
||||
{
|
||||
$loginError = "Wrong password !";
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<?php require 'views/header.php'; ?>
|
||||
<div class="container">
|
||||
<?php
|
||||
if($loginError !== "")
|
||||
{
|
||||
?>
|
||||
<div class="alert alert-danger" role="alert"><?php echo $loginError; ?></div>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<div class="row">
|
||||
<div class="col-md-4"></div>
|
||||
<div class="col-md-4">
|
||||
<h2>Login :</h2>
|
||||
</div>
|
||||
<div class="col-md-4"></div>
|
||||
</div>
|
||||
<form class="form-horizontal" action="login.php" method="POST">
|
||||
<div class="form-group">
|
||||
<div class="col-lg-4"></div>
|
||||
<div class="col-lg-4">
|
||||
<input class="form-control" id="password" name="password" placeholder="Password" type="password">
|
||||
</div>
|
||||
<div class="col-lg-4"></div>
|
||||
</div>
|
||||
</form>
|
||||
</div><!-- End container -->
|
||||
<?php require 'views/footer.php'; ?>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
require 'class/Session.php';
|
||||
Session::getInstance()->logout();
|
||||
header("Location: index.php");
|
||||
?>
|
||||
|
|
@ -0,0 +1,188 @@
|
|||
<?php
|
||||
|
||||
require_once 'class/Session.php';
|
||||
require_once 'class/Downloader.php';
|
||||
require_once 'class/FileHandler.php';
|
||||
|
||||
$session = Session::getInstance();
|
||||
$file = new FileHandler;
|
||||
|
||||
if(!$session->is_logged_in())
|
||||
{
|
||||
header("Location: login.php");
|
||||
}
|
||||
|
||||
###############################################################
|
||||
# File Download 1.31
|
||||
###############################################################
|
||||
# Visit http://www.zubrag.com/scripts/ for updates
|
||||
###############################################################
|
||||
# Sample call:
|
||||
# download.php?f=phptutorial.zip
|
||||
#
|
||||
# Sample call (browser will try to save with new file name):
|
||||
# download.php?f=phptutorial.zip&fc=php123tutorial.zip
|
||||
###############################################################
|
||||
|
||||
// Allow direct file download (hotlinking)?
|
||||
// Empty - allow hotlinking
|
||||
// If set to nonempty value (Example: example.com) will only allow downloads when referrer contains this text
|
||||
define('ALLOWED_REFERRER', '');
|
||||
|
||||
// Download folder, i.e. folder where you keep all files for download.
|
||||
// MUST end with slash (i.e. "/" )
|
||||
|
||||
//BASE_DIR = $file->get_downloads_folder();
|
||||
define('BASE_DIR',$file->get_downloads_folder());
|
||||
|
||||
// log plays? true/false
|
||||
define('LOG_PLAYS',true);
|
||||
|
||||
// log file name
|
||||
define('LOG_FILE','plays.log');
|
||||
|
||||
// Allowed extensions list in format 'extension' => 'mime type'
|
||||
// If myme type is set to empty string then script will try to detect mime type
|
||||
// itself, which would only work if you have Mimetype or Fileinfo extensions
|
||||
// installed on server.
|
||||
$allowed_ext = array (
|
||||
|
||||
// audio
|
||||
'mp3' => 'audio/mpeg',
|
||||
'wav' => 'audio/x-wav',
|
||||
|
||||
// video
|
||||
'mpeg' => 'video/mpeg',
|
||||
'mp4' => 'video/mp4',
|
||||
'mpg' => 'video/mpeg',
|
||||
'mpe' => 'video/mpeg',
|
||||
'mkv' => 'video/mpeg',
|
||||
'mov' => 'video/quicktime',
|
||||
'avi' => 'video/x-msvideo',
|
||||
'webm' => 'video/mpeg'
|
||||
);
|
||||
|
||||
|
||||
|
||||
####################################################################
|
||||
### DO NOT CHANGE BELOW
|
||||
####################################################################
|
||||
|
||||
// If hotlinking not allowed then make hackers think there are some server problems
|
||||
if (ALLOWED_REFERRER !== ''
|
||||
&& (!isset($_SERVER['HTTP_REFERER']) || strpos(strtoupper($_SERVER['HTTP_REFERER']),strtoupper(ALLOWED_REFERRER)) === false)
|
||||
) {
|
||||
die("Internal server error. Please contact system administrator.");
|
||||
}
|
||||
|
||||
// Make sure program execution doesn't time out
|
||||
// Set maximum script execution time in seconds (0 means no limit)
|
||||
set_time_limit(0);
|
||||
|
||||
if (!isset($_GET['f']) || empty($_GET['f'])) {
|
||||
die("Please specify file name for download.");
|
||||
}
|
||||
|
||||
// Nullbyte hack fix
|
||||
if (strpos($_GET['f'], "\0") !== FALSE) die('');
|
||||
|
||||
// Get real file name.
|
||||
// Remove any path info to avoid hacking by adding relative path, etc.
|
||||
$fname = basename($_GET['f']);
|
||||
|
||||
// Check if the file exists
|
||||
// Check in subfolders too
|
||||
function find_file ($dirname, $fname, &$file_path) {
|
||||
|
||||
$dir = opendir($dirname);
|
||||
|
||||
while ($file = readdir($dir)) {
|
||||
if (empty($file_path) && $file != '.' && $file != '..') {
|
||||
if (is_dir($dirname.'/'.$file)) {
|
||||
find_file($dirname.'/'.$file, $fname, $file_path);
|
||||
}
|
||||
else {
|
||||
if (file_exists($dirname.'/'.$fname)) {
|
||||
$file_path = $dirname.'/'.$fname;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // find_file
|
||||
|
||||
// get full file path (including subfolders)
|
||||
$file_path = '';
|
||||
find_file(BASE_DIR, $fname, $file_path);
|
||||
|
||||
if (!is_file($file_path)) {
|
||||
die("File does not exist. Make sure you specified correct file name.");
|
||||
}
|
||||
|
||||
// file size in bytes
|
||||
$fsize = filesize($file_path);
|
||||
|
||||
// file extension
|
||||
$fext = strtolower(substr(strrchr($fname,"."),1));
|
||||
|
||||
// check if allowed extension
|
||||
if (!array_key_exists($fext, $allowed_ext)) {
|
||||
die("Not allowed file type.");
|
||||
}
|
||||
|
||||
// get mime type
|
||||
if ($allowed_ext[$fext] == '') {
|
||||
$mtype = '';
|
||||
// mime type is not set, get from server settings
|
||||
if (function_exists('mime_content_type')) {
|
||||
$mtype = mime_content_type($file_path);
|
||||
}
|
||||
else if (function_exists('finfo_file')) {
|
||||
$finfo = finfo_open(FILEINFO_MIME); // return mime type
|
||||
$mtype = finfo_file($finfo, $file_path);
|
||||
finfo_close($finfo);
|
||||
}
|
||||
if ($mtype == '') {
|
||||
$mtype = "application/force-download";
|
||||
}
|
||||
}
|
||||
else {
|
||||
// get mime type defined by admin
|
||||
$mtype = $allowed_ext[$fext];
|
||||
}
|
||||
|
||||
// Browser will try to save file with this filename, regardless original filename.
|
||||
// You can override it if needed.
|
||||
|
||||
if (!isset($_GET['fc']) || empty($_GET['fc'])) {
|
||||
$asfname = $fname;
|
||||
}
|
||||
else {
|
||||
// remove some bad chars
|
||||
$asfname = str_replace(array('"',"'",'\\','/'), '', $_GET['fc']);
|
||||
if ($asfname === '') $asfname = 'NoName';
|
||||
}
|
||||
|
||||
// set headers
|
||||
|
||||
|
||||
|
||||
header("Content-Type:video/".$fext);
|
||||
header("Content-Length: " . filesize($file_path));
|
||||
header("Cache-Control:no-cache");
|
||||
header("Content-Transfer-Encoding:binary");
|
||||
readfile($file_path);
|
||||
|
||||
|
||||
|
||||
// log plays
|
||||
if (!LOG_PLAYS) die();
|
||||
|
||||
$f = @fopen(LOG_FILE, 'a+');
|
||||
if ($f) {
|
||||
@fputs($f, date("m.d.Y g:ia")." ".$_SERVER['REMOTE_ADDR']." ".$fname."\n");
|
||||
@fclose($f);
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -0,0 +1 @@
|
|||
User-agent: *
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<footer class="footer">
|
||||
<div class="well text-center">
|
||||
<p><a href="https://github.com/shreebhattji/Urmi">Urmi Licence</a> - <a href="https://urmic.org/">Made With love from ShreeBhattji</a></p>
|
||||
</div>
|
||||
</footer>
|
||||
<script type="text/javascript" src="js/jquery-1.11.1.min.js"></script>
|
||||
<script type="text/javascript" src="js/bootstrap.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$("#url").focus();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Youtube-dl WebUI</title>
|
||||
<link rel="stylesheet" href="css/bootstrap.min.css" media="screen">
|
||||
<link rel="stylesheet" href="css/font-awesome.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="navbar navbar-default">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="">Youtube-dl</a>
|
||||
</div>
|
||||
<div class="navbar-collapse collapse navbar-responsive-collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li><a href="./">Download</a></li>
|
||||
<li><a href="./list.php?type=v">List of videos</a></li>
|
||||
<li><a href="./list.php?type=m">List of songs</a></li>
|
||||
<?php
|
||||
if($session->is_logged_in())
|
||||
{
|
||||
?>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
|
||||
<?php if(Downloader::background_jobs() > 0) echo "<b>"; ?>Background downloads : <?php echo Downloader::background_jobs()." / ".Downloader::max_background_jobs(); if(Downloader::background_jobs() > 0) echo "</b>"; ?> <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<?php
|
||||
if(Downloader::get_current_background_jobs() != null)
|
||||
{
|
||||
foreach(Downloader::get_current_background_jobs() as $key)
|
||||
{
|
||||
if (strpos($key['cmd'], '-x') !== false) //Music
|
||||
{
|
||||
echo "<li><a href=\"#\"><i class=\"fa fa-music\"></i> Elapsed time : ".$key['time']."</a></li>";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "<li><a href=\"#\"><i class=\"fa fa-video-camera\"></i> Elapsed time : ".$key['time']."</a></li>";
|
||||
}
|
||||
}
|
||||
|
||||
echo "<li class=\"divider\"></li>";
|
||||
echo "<li><a href=\"./index.php?kill=all\">Kill all downloads</a></li>";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "<li><a>No jobs !</a></li>";
|
||||
}
|
||||
|
||||
?>
|
||||
</ul>
|
||||
</li>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<?php
|
||||
if($session->is_logged_in())
|
||||
{
|
||||
echo "<li><a href=\"./logout.php\">Logout</a></li>";
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,586 @@
|
|||
<?php
|
||||
// settings/index.php
|
||||
|
||||
// Start session to store settings
|
||||
session_start();
|
||||
|
||||
// Define settings file path - save in same directory as this file
|
||||
$settings_file = __DIR__ . '/settings.json';
|
||||
|
||||
// Default settings
|
||||
$default_settings = [
|
||||
'video_format' => 'h264',
|
||||
'audio_format' => 'mp3',
|
||||
'video_bitrate' => '1000k',
|
||||
'audio_bitrate' => '128k',
|
||||
'resolution' => '1280x720',
|
||||
'frame_rate' => '30',
|
||||
'gop' => '30',
|
||||
];
|
||||
|
||||
// Initialize settings from JSON file or use defaults
|
||||
if (file_exists($settings_file)) {
|
||||
$settings_json = file_get_contents($settings_file);
|
||||
$settings = json_decode($settings_json, true);
|
||||
|
||||
// Merge with defaults if any keys are missing
|
||||
foreach ($default_settings as $key => $value) {
|
||||
if (!isset($settings[$key])) {
|
||||
$settings[$key] = $value;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$settings = $default_settings;
|
||||
}
|
||||
|
||||
// Handle form submission
|
||||
$message = '';
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
// Validate video format
|
||||
$allowed_video_formats = ['mpeg2', 'h264', 'h265', 'vp9', 'av1'];
|
||||
if (isset($_POST['video_format']) && in_array($_POST['video_format'], $allowed_video_formats)) {
|
||||
$settings['video_format'] = $_POST['video_format'];
|
||||
}
|
||||
|
||||
// Validate audio format
|
||||
$allowed_audio_formats = ['mp2', 'mp3', 'aac'];
|
||||
if (isset($_POST['audio_format']) && in_array($_POST['audio_format'], $allowed_audio_formats)) {
|
||||
$settings['audio_format'] = $_POST['audio_format'];
|
||||
}
|
||||
|
||||
// Update other settings
|
||||
$settings['video_bitrate'] = $_POST['video_bitrate'] ?? $settings['video_bitrate'];
|
||||
$settings['audio_bitrate'] = $_POST['audio_bitrate'] ?? $settings['audio_bitrate'];
|
||||
$settings['resolution'] = $_POST['resolution'] ?? $settings['resolution'];
|
||||
$settings['frame_rate'] = $_POST['frame_rate'] ?? $settings['frame_rate'];
|
||||
$settings['gop'] = $_POST['gop'] ?? $settings['gop'];
|
||||
|
||||
// Save settings to JSON file
|
||||
$settings_json = json_encode($settings, JSON_PRETTY_PRINT);
|
||||
if (file_put_contents($settings_file, $settings_json) !== false) {
|
||||
$message = "Settings saved successfully!";
|
||||
} else {
|
||||
$message = "Error saving settings!";
|
||||
}
|
||||
}
|
||||
|
||||
// Save settings to session as backup
|
||||
$_SESSION['settings'] = $settings;
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Video Settings</title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background: linear-gradient(135deg, #0f2027, #203a43, #2c5364);
|
||||
color: #fff;
|
||||
min-height: 100vh;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 800px;
|
||||
width: 100%;
|
||||
background: rgba(13, 19, 33, 0.85);
|
||||
backdrop-filter: blur(12px);
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.7);
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(92, 107, 192, 0.3);
|
||||
transform: translateZ(0);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.container::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -2px;
|
||||
left: -2px;
|
||||
right: -2px;
|
||||
bottom: -2px;
|
||||
background: linear-gradient(45deg, #1a2a6c, #2a5298, #4facfe, #00f2fe, #1a2a6c);
|
||||
z-index: -1;
|
||||
border-radius: 22px;
|
||||
animation: gradient 15s ease infinite;
|
||||
background-size: 400% 400%;
|
||||
}
|
||||
|
||||
@keyframes gradient {
|
||||
0% { background-position: 0% 50%; }
|
||||
50% { background-position: 100% 50%; }
|
||||
100% { background-position: 0% 50%; }
|
||||
}
|
||||
|
||||
.header {
|
||||
background: linear-gradient(90deg, #1a2a6c, #2a5298);
|
||||
padding: 30px;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
border-bottom: 2px solid rgba(92, 107, 192, 0.5);
|
||||
transform: translateZ(0);
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 10px;
|
||||
text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
|
||||
background: linear-gradient(to right, #4facfe, #00f2fe);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.header h1::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -5px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 80%;
|
||||
height: 2px;
|
||||
background: linear-gradient(to right, transparent, #4facfe, #00f2fe, transparent);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.header p {
|
||||
font-size: 1.1rem;
|
||||
opacity: 0.9;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 25px;
|
||||
position: relative;
|
||||
transform: translateZ(0);
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
display: block;
|
||||
margin-bottom: 10px;
|
||||
font-weight: 600;
|
||||
font-size: 1.1rem;
|
||||
color: #4facfe;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
position: relative;
|
||||
/* Fix for label visibility */
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.form-group label::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: -25px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
background: #4facfe;
|
||||
box-shadow: 0 0 10px rgba(79, 172, 254, 0.7);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
input, select {
|
||||
width: 100%;
|
||||
padding: 15px;
|
||||
border: 2px solid rgba(92, 107, 192, 0.5);
|
||||
border-radius: 12px;
|
||||
background: rgba(13, 19, 33, 0.7);
|
||||
color: #fff;
|
||||
font-size: 1rem;
|
||||
transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
|
||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
|
||||
backdrop-filter: blur(5px);
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
input:focus, select:focus {
|
||||
outline: none;
|
||||
border-color: #4facfe;
|
||||
box-shadow: 0 0 20px rgba(79, 172, 254, 0.6);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
input:focus {
|
||||
box-shadow: 0 0 20px rgba(79, 172, 254, 0.6), 0 0 0 3px rgba(79, 172, 254, 0.2);
|
||||
}
|
||||
|
||||
.btn {
|
||||
background: linear-gradient(90deg, #1a2a6c, #2a5298);
|
||||
color: white;
|
||||
padding: 16px 30px;
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
cursor: pointer;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
width: 100%;
|
||||
transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
|
||||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
|
||||
letter-spacing: 1px;
|
||||
text-transform: uppercase;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
z-index: 1;
|
||||
transform: translateZ(0);
|
||||
}
|
||||
|
||||
.btn::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
|
||||
transition: 0.5s;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.4);
|
||||
background: linear-gradient(90deg, #2a5298, #1a2a6c);
|
||||
}
|
||||
|
||||
.btn:hover::before {
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
.btn:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.message {
|
||||
padding: 15px;
|
||||
margin: 20px 0;
|
||||
border-radius: 12px;
|
||||
text-align: center;
|
||||
font-weight: 500;
|
||||
animation: fadeIn 0.5s ease;
|
||||
backdrop-filter: blur(5px);
|
||||
border: 1px solid;
|
||||
transform: translateZ(0);
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; transform: translateY(-10px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
.success {
|
||||
background: rgba(46, 204, 113, 0.2);
|
||||
border: 1px solid rgba(46, 204, 113, 0.5);
|
||||
color: #2ecc71;
|
||||
}
|
||||
|
||||
.error {
|
||||
background: rgba(231, 76, 60, 0.2);
|
||||
border: 1px solid rgba(231, 76, 60, 0.5);
|
||||
color: #e74c3c;
|
||||
}
|
||||
|
||||
.format-note {
|
||||
background: rgba(92, 107, 192, 0.2);
|
||||
border: 1px solid rgba(92, 107, 192, 0.4);
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
margin: 25px 0;
|
||||
font-size: 0.95rem;
|
||||
transform: translateZ(0);
|
||||
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.format-note h3 {
|
||||
color: #4facfe;
|
||||
margin-bottom: 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.format-note h3 i {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.format-note p {
|
||||
margin: 8px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.format-note p i {
|
||||
margin-right: 10px;
|
||||
color: #4facfe;
|
||||
}
|
||||
|
||||
.footer {
|
||||
text-align: center;
|
||||
padding: 25px;
|
||||
background: rgba(13, 19, 33, 0.9);
|
||||
border-top: 1px solid rgba(92, 107, 192, 0.3);
|
||||
font-size: 1.1rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
transform: translateZ(0);
|
||||
}
|
||||
|
||||
.footer i {
|
||||
color: #e74c3c;
|
||||
margin: 0 5px;
|
||||
font-size: 1.3rem;
|
||||
animation: heartbeat 1.5s infinite;
|
||||
}
|
||||
|
||||
@keyframes heartbeat {
|
||||
0% { transform: scale(1); }
|
||||
50% { transform: scale(1.2); }
|
||||
100% { transform: scale(1); }
|
||||
}
|
||||
|
||||
.footer p {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.settings-info {
|
||||
background: rgba(13, 19, 33, 0.7);
|
||||
border: 1px solid rgba(92, 107, 192, 0.3);
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
margin-bottom: 25px;
|
||||
font-size: 0.9rem;
|
||||
transform: translateZ(0);
|
||||
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.settings-info p {
|
||||
margin: 8px 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.settings-info strong {
|
||||
color: #4facfe;
|
||||
}
|
||||
|
||||
.pulse {
|
||||
animation: pulse 2s infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0% { box-shadow: 0 0 0 0 rgba(79, 172, 254, 0.4); }
|
||||
70% { box-shadow: 0 0 0 10px rgba(79, 172, 254, 0); }
|
||||
100% { box-shadow: 0 0 0 0 rgba(79, 172, 254, 0); }
|
||||
}
|
||||
|
||||
.floating {
|
||||
animation: floating 3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes floating {
|
||||
0% { transform: translateY(0px); }
|
||||
50% { transform: translateY(-10px); }
|
||||
100% { transform: translateY(0px); }
|
||||
}
|
||||
|
||||
.glow {
|
||||
text-shadow: 0 0 10px rgba(79, 172, 254, 0.7);
|
||||
}
|
||||
|
||||
.input-group {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.input-group input {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.input-group input:first-child {
|
||||
border-radius: 12px 0 0 12px;
|
||||
}
|
||||
|
||||
.input-group input:last-child {
|
||||
border-radius: 0 12px 12px 0;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.container {
|
||||
margin: 10px;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.input-group {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.input-group input {
|
||||
border-radius: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.animate-on-load {
|
||||
animation: slideIn 0.8s ease-out;
|
||||
}
|
||||
|
||||
@keyframes slideIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.form-group:nth-child(1) { animation-delay: 0.1s; }
|
||||
.form-group:nth-child(2) { animation-delay: 0.2s; }
|
||||
.form-group:nth-child(3) { animation-delay: 0.3s; }
|
||||
.form-group:nth-child(4) { animation-delay: 0.4s; }
|
||||
.form-group:nth-child(5) { animation-delay: 0.5s; }
|
||||
.form-group:nth-child(6) { animation-delay: 0.6s; }
|
||||
.form-group:nth-child(7) { animation-delay: 0.7s; }
|
||||
|
||||
.form-group {
|
||||
animation: slideIn 0.5s ease-out forwards;
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
|
||||
.form-group.animate {
|
||||
animation: slideIn 0.5s ease-out forwards;
|
||||
}
|
||||
|
||||
.btn-container {
|
||||
margin-top: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container animate-on-load">
|
||||
<div class="header">
|
||||
<h1 class="glow"><i class="fas fa-cog"></i> Video Settings</h1>
|
||||
<p>Configure your video processing parameters</p>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<?php if ($message): ?>
|
||||
<div class="message <?php echo (strpos($message, 'Error') !== false) ? 'error' : 'success'; ?>">
|
||||
<?php echo $message; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="settings-info">
|
||||
<p><strong>Current Settings:</strong>
|
||||
<span>Video: <?php echo htmlspecialchars($settings['video_format']); ?></span> |
|
||||
<span>Audio: <?php echo htmlspecialchars($settings['audio_format']); ?></span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="format-note">
|
||||
<h3><i class="fas fa-info-circle"></i> Format Restrictions</h3>
|
||||
<p><i class="fas fa-video"></i> Video format is limited to: MPEG-2, H.264, H.265, VP9, and AV1</p>
|
||||
<p><i class="fas fa-music"></i> Audio format is limited to: MP2, MP3, and AAC</p>
|
||||
</div>
|
||||
|
||||
<form method="POST" action="">
|
||||
<div class="form-group">
|
||||
<label for="video_format"><i class="fas fa-film"></i> Video Format</label>
|
||||
<select name="video_format" id="video_format">
|
||||
<option value="mpeg2" <?php echo ($settings['video_format'] === 'mpeg2') ? 'selected' : ''; ?>>MPEG-2</option>
|
||||
<option value="h264" <?php echo ($settings['video_format'] === 'h264') ? 'selected' : ''; ?>>H.264</option>
|
||||
<option value="h265" <?php echo ($settings['video_format'] === 'h265') ? 'selected' : ''; ?>>H.265</option>
|
||||
<option value="vp9" <?php echo ($settings['video_format'] === 'vp9') ? 'selected' : ''; ?>>VP9</option>
|
||||
<option value="av1" <?php echo ($settings['video_format'] === 'av1') ? 'selected' : ''; ?>>AV1</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="audio_format"><i class="fas fa-music"></i> Audio Format</label>
|
||||
<select name="audio_format" id="audio_format">
|
||||
<option value="mp2" <?php echo ($settings['audio_format'] === 'mp2') ? 'selected' : ''; ?>>MP2</option>
|
||||
<option value="mp3" <?php echo ($settings['audio_format'] === 'mp3') ? 'selected' : ''; ?>>MP3</option>
|
||||
<option value="aac" <?php echo ($settings['audio_format'] === 'aac') ? 'selected' : ''; ?>>AAC</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="video_bitrate"><i class="fas fa-tachometer-alt"></i> Video Bitrate</label>
|
||||
<input type="text" name="video_bitrate" id="video_bitrate" value="<?php echo htmlspecialchars($settings['video_bitrate']); ?>">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="audio_bitrate"><i class="fas fa-volume-up"></i> Audio Bitrate</label>
|
||||
<input type="text" name="audio_bitrate" id="audio_bitrate" value="<?php echo htmlspecialchars($settings['audio_bitrate']); ?>">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="resolution"><i class="fas fa-expand"></i> Resolution</label>
|
||||
<select name="resolution" id="resolution">
|
||||
<option value="720x576" <?php echo ($settings['resolution'] === '720x576') ? 'selected' : ''; ?>>720x576 (PAL)</option>
|
||||
<option value="720x480" <?php echo ($settings['resolution'] === '720x480') ? 'selected' : ''; ?>>720x480 (NTSC)</option>
|
||||
<option value="1280x720" <?php echo ($settings['resolution'] === '1280x720') ? 'selected' : ''; ?>>1280x720 (HD 720p)</option>
|
||||
<option value="1920x1080" <?php echo ($settings['resolution'] === '1920x1080') ? 'selected' : ''; ?>>1920x1080 (HD 1080p)</option>
|
||||
<option value="2560x1440" <?php echo ($settings['resolution'] === '2560x1440') ? 'selected' : ''; ?>>2560x1440 (QHD 1440p)</option>
|
||||
<option value="3840x2160" <?php echo ($settings['resolution'] === '3840x2160') ? 'selected' : ''; ?>>3840x2160 (4K UHD)</option>
|
||||
<option value="4096x2160" <?php echo ($settings['resolution'] === '4096x2160') ? 'selected' : ''; ?>>4096x2160 (4K DCI)</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="frame_rate"><i class="fas fa-play-circle"></i> Frame Rate (fps)</label>
|
||||
<input type="text" name="frame_rate" id="frame_rate" value="<?php echo htmlspecialchars($settings['frame_rate']); ?>">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="gop"><i class="fas fa-layer-group"></i> GOP (Group of Pictures)</label>
|
||||
<input type="text" name="gop" id="gop" value="<?php echo htmlspecialchars($settings['gop']); ?>">
|
||||
</div>
|
||||
|
||||
<div class="btn-container">
|
||||
<button type="submit" class="btn pulse"><i class="fas fa-save"></i> Save Settings</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<p>Made with <i class="fas fa-heart"></i> from ShreeBhattJi</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"video_format": "mpeg2",
|
||||
"audio_format": "mp3",
|
||||
"video_bitrate": "1000k",
|
||||
"audio_bitrate": "128k",
|
||||
"resolution": "1280x720",
|
||||
"frame_rate": "30",
|
||||
"gop": "30"
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
apt updtae;
|
||||
apt upgrade -y;
|
||||
apt install php ffmpeg apache2 samba -y
|
||||
|
||||
mkdir -p /var/www/download /var/www/downloader /var/www/download/queue /var/www/download/ready
|
||||
|
||||
cp -r downloader/* /var/www/downloader
|
||||
|
||||
|
||||
sudo smbpasswd -a shreebhattji
|
||||
echo "foreverstreamingpartner" | sudo smbpasswd -s -a shreebhattji
|
||||
sudo chmod 755 /var/www/download
|
||||
|
||||
sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.backup
|
||||
|
||||
cat << EOF | sudo tee -a /etc/samba/smb.conf
|
||||
|
||||
[download]
|
||||
path = /var/www/download
|
||||
browseable = yes
|
||||
writable = yes
|
||||
guest ok = no
|
||||
read only = no
|
||||
valid users = shreebhattji
|
||||
EOF
|
||||
|
||||
sudo systemctl restart smbd nmbd
|
||||
sudo systemctl enable smbd nmbd
|
||||
|
||||
cat << EOF | sudo tee -a /etc/systemd/system/transcode.service
|
||||
|
||||
[Unit]
|
||||
Description=Video Transcoding Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=www-data
|
||||
Group=www-data
|
||||
WorkingDirectory=/var/www/
|
||||
ExecStart=/usr/bin/python3 /var/www/transcode.sh
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Configuration
|
||||
QUEUE_DIR="/var/www/download/queue"
|
||||
READY_DIR="/var/www/download/ready"
|
||||
SETTINGS_FILE="/path/to/settings/settings.json"
|
||||
LOG_FILE="/var/log/convert.log"
|
||||
|
||||
# Create directories if they don't exist
|
||||
mkdir -p "$QUEUE_DIR"
|
||||
mkdir -p "$READY_DIR"
|
||||
|
||||
# Load settings from JSON file
|
||||
load_settings() {
|
||||
VIDEO_FORMAT=$(jq -r '.video_format' "$SETTINGS_FILE")
|
||||
AUDIO_FORMAT=$(jq -r '.audio_format' "$SETTINGS_FILE")
|
||||
VIDEO_BITRATE=$(jq -r '.video_bitrate' "$SETTINGS_FILE")
|
||||
AUDIO_BITRATE=$(jq -r '.audio_bitrate' "$SETTINGS_FILE")
|
||||
RESOLUTION=$(jq -r '.resolution' "$SETTINGS_FILE")
|
||||
FRAME_RATE=$(jq -r '.frame_rate' "$SETTINGS_FILE")
|
||||
GOP=$(jq -r '.gop' "$SETTINGS_FILE")
|
||||
}
|
||||
|
||||
# Function to sanitize filename
|
||||
sanitize_filename() {
|
||||
local filename="$1"
|
||||
# Remove special characters, keep only a-z, A-Z, 0-9, and .
|
||||
local sanitized=$(echo "$filename" | sed 's/[^a-zA-Z0-9.]*//g')
|
||||
|
||||
# If filename starts with number, add prefix
|
||||
if [[ "$sanitized" =~ ^[0-9] ]]; then
|
||||
sanitized="dev_${sanitized}"
|
||||
fi
|
||||
|
||||
# If filename is empty after sanitization, use timestamp
|
||||
if [[ -z "$sanitized" ]]; then
|
||||
sanitized="dev_$(date +%s)"
|
||||
fi
|
||||
|
||||
echo "$sanitized"
|
||||
}
|
||||
|
||||
# Main processing loop
|
||||
while true; do
|
||||
# Load settings at start of each loop
|
||||
load_settings
|
||||
|
||||
# Find all files in queue directory
|
||||
for file in "$QUEUE_DIR"/*; do
|
||||
# Skip if no files found
|
||||
[ -f "$file" ] || continue
|
||||
|
||||
# Get original filename
|
||||
original_name=$(basename "$file")
|
||||
|
||||
# Sanitize filename
|
||||
sanitized_name=$(sanitize_filename "$original_name")
|
||||
|
||||
# Add .ts extension
|
||||
sanitized_name="${sanitized_name}.ts"
|
||||
|
||||
# Set output path
|
||||
output_file="$READY_DIR/$sanitized_name"
|
||||
|
||||
# Convert file with ffmpeg using settings from JSON
|
||||
if ffmpeg -i "$file" \
|
||||
-c:v "$VIDEO_FORMAT" \
|
||||
-b:v "$VIDEO_BITRATE" \
|
||||
-c:a "$AUDIO_FORMAT" \
|
||||
-b:a "$AUDIO_BITRATE" \
|
||||
-s "$RESOLUTION" \
|
||||
-r "$FRAME_RATE" \
|
||||
-g "$GOP" \
|
||||
"$output_file" 2>>"$LOG_FILE"; then
|
||||
# If conversion successful, remove original file
|
||||
rm "$file"
|
||||
echo "$(date): Successfully converted $original_name to $sanitized_name" >> "$LOG_FILE"
|
||||
else
|
||||
# If conversion failed, log error
|
||||
echo "$(date): Failed to convert $original_name" >> "$LOG_FILE"
|
||||
fi
|
||||
done
|
||||
|
||||
# Wait before checking for new files
|
||||
sleep 5
|
||||
done
|
||||
Loading…
Reference in New Issue