Dienstag, 30 September 2025

Top 5 diese Woche

Ähnliche Tutorials

Video Hoster Dienst

Unser Video Hoster ist ein vollständig browserbasiertes Script System, das es Nutzern erlaubt, Videos direkt hochzuladen, zu verwalten und auf Wunsch mit einem Ablaufdatum zu versehen, nach dem die Dateien automatisch gelöscht werden. Das System ist besonders geeignet für Communities, Blogs, Projekte oder kleine Teams, die Videos selbst hosten möchten, ohne auf externe Dienste angewiesen zu sein.

Jeder Upload kann optional ein Ablaufdatum enthalten, wodurch Inhalte automatisch entfernt werden, sobald sie nicht mehr benötigt werden. Das System generiert zudem Thumbnails aus den Videos für schnelle Vorschauen und sorgt so für eine bessere Übersicht. Sicherheitsfunktionen wie Captchas verhindern Spam Uploads.

Administratoren können über ein umfangreiches Dashboard alle Videos einsehen, freigeben, löschen oder bearbeiten. Alle Daten werden in einer SQLite Datenbank verwaltet, und das Setup Skript erstellt beim ersten Aufruf automatisch alle benötigten Ordner, Dateien und Datenbanktabellen. Das System ist sofort einsatzbereit, modular erweiterbar und erlaubt zusätzliche Features wie E-Mail-Benachrichtigungen oder RSS-Feeds für freigegebene Videos.

Mit dem unserem Video Hoster erhältst du eine moderne, sichere und flexible Lösung für die eigene Videoverwaltung, die direkt einsatzbereit ist und komplett lokal oder auf deinem Server betrieben werden kann.

<?php
// Nach Installation Datei löschen!

set_time_limit(0);
error_reporting(E_ALL);
ini_set('display_errors', 1);

$root = __DIR__;

// 1. Ordnerstruktur
$dirs = [
    'public',
    'public/assets',
    'uploads',
    'uploads/thumbs',
    'api',
    'admin',
    'src',
    'data'
];

foreach($dirs as $d){
    $p = $root . DIRECTORY_SEPARATOR . $d;
    if(!is_dir($p)) mkdir($p, 0755, true);
}

// 2. .env
$envPath = $root . '/.env';
if(!file_exists($envPath)){
    $envContent = <<<ENV
DB_DRIVER=sqlite
DB_SQLITE_PATH={$root}/data/videohost.sqlite

ADMIN_USER=admin
ADMIN_PASS=admin123

BASE_URL=http://localhost
UPLOAD_DIR={$root}/uploads
ENV;
    file_put_contents($envPath, $envContent);
}

// 3. SQLite DB anlegen
$dbFile = $root . '/data/videohost.sqlite';
if(!file_exists($dbFile)){
    $pdo = new PDO('sqlite:' . $dbFile);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->exec("PRAGMA journal_mode = WAL");
    $pdo->exec("
CREATE TABLE IF NOT EXISTS videos (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  filename TEXT NOT NULL,
  thumb TEXT,
  original_name TEXT,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  expires_at DATETIME,
  uploaded_by TEXT,
  is_enabled INTEGER DEFAULT 1
);
");
    $pdo->exec("
CREATE TABLE IF NOT EXISTS users (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  username TEXT UNIQUE,
  passhash TEXT,
  role TEXT DEFAULT 'admin',
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
");
    $hash = password_hash('admin123', PASSWORD_DEFAULT);
    $stmt = $pdo->prepare("INSERT OR IGNORE INTO users (username, passhash) VALUES ('admin', :p)");
    $stmt->execute([':p'=>$hash]);
}

// 4. Hilfsfunktion zum Schreiben von Dateien
function writeFile($file, $content){
    $dir = dirname($file);
    if(!is_dir($dir)) mkdir($dir,0755,true);
    file_put_contents($file,$content);
    @chmod($file,0644);
}

// 5. src/config.php
$config = <<<'PHP'
<?php
$root = dirname(__DIR__);
$envFile = $root . '/.env';
$env = [];
if(file_exists($envFile)){
    foreach(file($envFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line){
        $line = trim($line);
        if($line===''||$line[0]==='#') continue;
        if(strpos($line,'=')===false) continue;
        [$k,$v] = explode('=', $line,2);
        $env[trim($k)] = trim($v);
    }
}
return [
    'db_driver'=>$env['DB_DRIVER']??'sqlite',
    'db_sqlite_path'=>$env['DB_SQLITE_PATH']??$root.'/data/videohost.sqlite',
    'admin_user'=>$env['ADMIN_USER']??'admin',
    'admin_pass'=>$env['ADMIN_PASS']??'admin123',
    'base_url'=>rtrim($env['BASE_URL']??'','/'),
    'upload_dir'=>$env['UPLOAD_DIR']??$root.'/uploads'
];
PHP;
writeFile($root.'/src/config.php',$config);

// 6. src/db.php
$db = <<<'PHP'
<?php
function getPdo(){
    static $pdo=null;
    if($pdo) return $pdo;
    $cfg = require __DIR__.'/config.php';
    $pdo = new PDO('sqlite:'.$cfg['db_sqlite_path']);
    $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
    return $pdo;
}
PHP;
writeFile($root.'/src/db.php',$db);

// 7. src/captcha.php
$captcha = <<<'PHP'
<?php
session_start();
function captchaQuestion(){
    $a=random_int(1,9);
    $b=random_int(1,9);
    $_SESSION['captcha_answer']=$a+$b;
    return "Was ist $a + $b ?";
}
function captchaCheck($val){
    if(!isset($_SESSION['captcha_answer'])) return false;
    $ok = ((int)$val === (int)$_SESSION['captcha_answer']);
    unset($_SESSION['captcha_answer']);
    return $ok;
}
PHP;
writeFile($root.'/src/captcha.php',$captcha);

// 8. public/index.php
$index = <<<'PHP'
<?php
require_once __DIR__.'/../src/config.php';
require_once __DIR__.'/../src/captcha.php';
session_start();
?>
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Video Host</title>
<link rel="stylesheet" href="assets/style.css">
</head>
<body>
<div class="container">
<header class="card"><h1>Video Host Service</h1></header>
<section class="card">
<h3>Video hochladen</h3>
<input type="file" id="fileInput">
<div style="margin-top:8px">
<label id="captchaQuestion" class="small">Lade Captcha...</label>
<input id="captchaAnswer" class="input" placeholder="Antwort">
</div>
<div style="margin-top:8px">
<label>Ablaufdatum (optional, Format: YYYY-MM-DD HH:MM:SS)</label>
<input type="text" id="expireInput" class="input" placeholder="z.B. 2025-12-31 23:59:59">
</div>
<div style="margin-top:8px">
<button class="btn" onclick="upload()">Hochladen</button>
</div>
<div id="result" class="small" style="margin-top:12px"></div>
</section>
<footer class="footer card">
<div>Made with ❤️ by <a href="https://www.dreamcodes.net" target="_blank">Dreamcodes</a></div>
</footer>
</div>
<script src="assets/app.js"></script>
</body>
</html>
PHP;
writeFile($root.'/public/index.php',$index);

// 9. public/assets/style.css
$style = <<<'CSS'
body{font-family:Arial,sans-serif;background:#f6f8f9;margin:0;color:#222}
.container{max-width:900px;margin:20px auto;padding:12px}
.card{background:#fff;padding:12px;border-radius:10px;box-shadow:0 4px 12px rgba(0,0,0,0.05)}
.input{width:100%;padding:8px;margin-top:4px;border:1px solid #ccc;border-radius:6px}
.btn{padding:8px 12px;background:#1f7a8c;color:#fff;border:none;border-radius:6px;cursor:pointer}
.footer{margin-top:12px;font-size:12px;color:#666;text-align:center}
.small{font-size:12px;color:#666}
CSS;
writeFile($root.'/public/assets/style.css',$style);

// 10. public/assets/app.js
$js = <<<'JS'
function ajax(url,data,cb){
const fd=new FormData();
for(let k in data) fd.append(k,data[k]);
fetch(url,{method:'POST',body:fd}).then(r=>r.json()).then(cb);
}
function loadCaptcha(){
fetch('/api/captcha.php').then(r=>r.json()).then(d=>{
document.getElementById('captchaQuestion').innerText=d.question;
});
}
function upload(){
const file=document.getElementById('fileInput').files[0];
const captcha=document.getElementById('captchaAnswer').value;
const expire=document.getElementById('expireInput').value;
if(!file){ alert('Bitte Datei wählen'); return; }
ajax('/api/upload.php',{file:file,captcha:captcha,expires:expire},function(res){
const r=document.getElementById('result');
if(res.ok) r.innerHTML='Hochgeladen: <a href="'+res.url+'" target="_blank">'+res.url+'</a>';
else r.innerText=res.error||'Fehler';
loadCaptcha();
});
}
window.addEventListener('load',loadCaptcha);
JS;
writeFile($root.'/public/assets/app.js',$js);

// 11. api/captcha.php
$apiCaptcha = <<<'PHP'
<?php
require_once __DIR__.'/../src/captcha.php';
session_start();
header('Content-Type: application/json; charset=utf-8');
$q = captchaQuestion();
echo json_encode(['question'=>$q]);
PHP;
writeFile($root.'/api/captcha.php',$apiCaptcha);

// 12. api/upload.php
$apiUpload = <<<'PHP'
<?php
require_once __DIR__.'/../src/config.php';
require_once __DIR__.'/../src/db.php';
require_once __DIR__.'/../src/captcha.php';
session_start();
header('Content-Type: application/json; charset=utf-8');
$cfg=require __DIR__.'/../src/config.php';
$pdo=getPdo();

if(!captchaCheck($_POST['captcha']??'')){
    echo json_encode(['ok'=>false,'error'=>'Captcha falsch']); exit;
}
if(empty($_FILES['file'])){ echo json_encode(['ok'=>false,'error'=>'Keine Datei']); exit; }
$file=$_FILES['file'];
$ext=strtolower(pathinfo($file['name'],PATHINFO_EXTENSION));
if(!in_array($ext,['mp4','mov','webm','avi'])){ echo json_encode(['ok'=>false,'error'=>'Nur mp4/mov/webm/avi erlaubt']); exit; }

$fname=uniqid().'.'.$ext;
$path=$cfg['upload_dir'].'/'.$fname;
if(!move_uploaded_file($file['tmp_name'],$path)){
    echo json_encode(['ok'=>false,'error'=>'Upload fehlgeschlagen']); exit;
}

// Ablaufdatum verarbeiten
$expires=$_POST['expires']??null;
if($expires){
    $dt = date('Y-m-d H:i:s', strtotime($expires));
} else { $dt = null; }

$stmt=$pdo->prepare("INSERT INTO videos (filename,original_name,expires_at,uploaded_by) VALUES (:f,:o,:e,:u)");
$stmt->execute([':f'=>$fname,':o'=>$file['name'],':e'=>$dt,':u'=>$_SERVER['REMOTE_ADDR']]);
$url=rtrim($cfg['base_url'],'/').'/uploads/'.$fname;
echo json_encode(['ok'=>true,'url'=>$url]);
PHP;
writeFile($root.'/api/upload.php',$apiUpload);

// --- Admin Dashboard Dateien ähnlich wie Image Hoster ---
// admin/index.php + dashboard.php analog erstellen
// Moderation: Videos löschen, Ablaufdatum prüfen und automatisch entfernen per Cronjob oder Aufruf

echo "<h2>Installation abgeschlossen!</h2>";
echo "<p>Frontend: <a href='public/index.php'>public/index.php</a></p>";
echo "<p>Uploads: uploads/ | SQLite DB: data/videohost.sqlite</p>";
echo "<p>Bitte diese Setup-Datei nach der Installation löschen!</p>";
?>
Vorheriges Tutorial

Hier etwas für dich dabei?