<?php

$DIR="/var/data/spielfilme";
$POSTER="/var/tmp/spielfilme";
$CONVERT=$POSTER;

/** Check the HTTP Get Variables */
function checkGet($var) {
  if (isset($_GET[$var]) && ereg('[^-_.A-Za-z0-9]', $_GET[$var])) {
    ?><html>
      <body>
        <p>wrong parameter <?php echo $var ?>:
          "<code><?php echo htmlentities($_GET["img"]) ?></code>"
        </p>
      </body>
    </html><?php
    exit;
  }
}

/** Check whether a specific file path exists */
function checkPath($path, $file) {
  if (!is_file($path.'/'.$file)) {
    ?><html>
      <body>
        <p>File not found:
          "<code><?php echo htmlentities($file) ?></code>"
        </p>
      </body>
    </html><?php
    exit;
  }
  return $path.'/'.$file;
}

/** Get Full Page URL */
function pageUrl() {
  $pageURL = 'http';
  if (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on") $pageURL .= "s";
  $pageURL .= "://";
  if ($_SERVER["SERVER_PORT"] != "80") {
     $pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"]
       .$_SERVER["REQUEST_URI"];
   } else {
     $pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
   }
   return $pageURL;
}

/** Generate an Image Tag to a Poster Image.
    @param $alt alternative image description attribute
    @param $src should be an image path below $POSTER
    @param $class optionall class attribute
    Returns an image tag, if the image file exists, empty otherwise. */
function img($alt, $src, $class="image") {
  global $POSTER;
  $URL=pageUrl();
  if (is_file($POSTER.'/'.$src.'.jpg'))
     return '<img alt="'.htmlentities($alt).'" src="'
       .htmlentities($URL.'?img='.$src).'.jpg" class="'.$class.'"/>';
  return '';
}

/** Generate a source entry for a given file.
    Returns source tag, if the image file exists, empty otherwise. */
function source($dir, $file, $mime=NULL) {
  $URL=pageUrl();
  $path=$dir.'/'.$file;
  if (is_file($path)) {
    if (!$mime) $type=mime_content_type($path);
    else $type='video/'.$mime;
    echo '<source src="'.$URL.'&play=1'.($mime?'&mime='.$mime:'')
      .'" type="'.$type.'">'."\n";
  } else {
    echo "Not Found: $path for $mime";
  }
}

/** Output only a part of a file */
function fileRange($path, $size, $mime) {
  $ranges = array_map('intval', // Parse the parts into integer
                      explode('-', // The range separator
                              // Skip the `bytes=` part of the header
                              substr($_SERVER['HTTP_RANGE'], 6)));
  // If the last range param is empty, it means the EOF (End of File)
  if (!$ranges[1]) $ranges[1] = $size-1;
  
  // Send the appropriate headers
  header('HTTP/1.1 206 Partial Content');
  header('Accept-Ranges: bytes');
  header('Content-Length: '.($ranges[1]-$ranges[0])); // The size of the range
 
  // Send the ranges we offered
  header(sprintf('Content-Range: bytes %d-%d/%d', // The header format
                 $ranges[0], // The start range
                 $ranges[1], // The end range
                 $size)); // Total size of the file
  
  // It's time to output the file
  $f = fopen($path, 'rb'); // Open the file in binary mode
  $chunkSize = 8192; // The size of each chunk to output
 
  // Seek to the requested start range
  fseek($f, $ranges[0]);
 
  // output the data
  while (ftell($f) < $ranges[1]) {
    echo fread($f, $chunkSize);
    @ob_flush();
    flush();
  }
}

/** Output a file */
function output($path) {
  $size = filesize($path); // The size of the file
  $mime = mime_content_type($path);
  ob_clean();
  @ini_set('error_reporting', E_ALL & ~ E_NOTICE);
  @apache_setenv('no-gzip', 1);
  @ini_set('zlib.output_compression', 'Off');
  header('Content-type: ' . $mime);
  if (isset($_SERVER['HTTP_RANGE'])) {
    fileRange($path, $size, $mime);
  } else {
    header('Content-Length: ' . $size);
    @readfile($path);
    @ob_flush();
    flush();
  }
  exit;
}

/** Replace file extension */
function ext($file, $newext) {
  return preg_replace('/\.[^.]*$/', '.'.$newext, $file);
}

/** Show a video player for the given video */
function player($video) {
  global $DIR, $CONVERT;
  $URL=pageUrl();
  ?><!DOCTYPE html>
    <html>
      <body>
        <p>
          <video controls>
            <?php
              source($DIR, $video);
              if ($d=opendir($CONVERT)) {
                while (false!==($f=readdir($d)))
                  if ($f!='.' && $f!=".." && is_dir($CONVERT.'/'.$f)) {
                    source($CONVERT.'/'.$f, ext($video, $f), $f);
                  }
                closedir($d);
              }
            ?>
            Your browser does not support the video tag.
          </video>
          <br/>
          [<a href="<?php echo $URL.'&play=1' ?>">Click to Download or
           copy link to VLC player</a>]
        </p>
      </body>
    </html><?php
  exit;
}

/** Show list and preview images of available videos */
function overview() {
  global $DIR;
  ?><html>
      <head>
        <title>Videofilme</title>
        <style>
          ul {
            list-style-type: none;
          }
          ul li {
            display: inline-block;
            text-weight: bold;
            border: .5ex groove green;
            padding: 0;
            margin: .5ex;
          }
          table {}
          td.poster {}
          img.poster {
            height: 210px;
          }
          img.preview {
            height: 70px;
          }
        </style>
      </head>
      <body>
        <h1>Videofilme</h1>
        <ul>
  <?php
    $URL=pageUrl();
    if ($d=opendir($DIR)) {
      while (false!==($f=readdir($d)))
        if (is_file($DIR.'/'.$f)) {
          $b=ereg_replace('\.[^.]*', '', $f);
          $t=ereg_replace(' - ', '<br/>',
             ereg_replace('[0-9]*-[^ ]*$', '',
             ereg_replace('( - )?(part|[cC][dD]|[Tt][eE][iI][lL])[0-9]+', '',
             ereg_replace('_', ' ', htmlentities($b)))));
          if (preg_match('/.*(part|[cC][dD]|[Tt][eE][iI][lL])([0-9]+).*/',
                         $b, $m))
            $t.='<br/>Teil '.$m[2];
          $t=ereg_replace('<br/>$', '', ereg_replace('(<br/>)+', '<br/>', $t));
          echo '<li><table><tr><th colspan="2" class="poster"><a href="'
            .htmlentities($URL.'?video='.urlencode($f).'&play=1').'">'.$t
            .'</a></td></tr><tr><td rowspan="3"><a href="'
            .htmlentities($URL.'?video='.urlencode($f)).'">'
            .img($b, $b, "poster").'</a></td><td>'
            .img("$b preview 25%", "$b-25", "preview")
            .'</td></tr><tr><td>'
            .img("$b preview 50%", "$b-50", "preview").'</td></tr><tr><td>'
            .img("$b preview 75%", "$b-75", "preview")
            .'</td></tr></table></li>'."\n";
        }
      closedir($d);
    }
  ?>
        </ul>
      </body>
    </html><?php
  exit;
}

/* Check all Parameters */
checkGet('img');
checkGet('video');
checkGet('mime');

/* Now $_GET Parameters are save */
if (isset($_GET["img"])) {
  output(checkPath($POSTER, $_GET["img"]));
} elseif (isset($_GET["video"])) {
  if (isset($_GET["play"])) {
    if (isset($_GET["mime"])) {
      output(checkPath($CONVERT.'/'.$_GET["mime"],
                       ext($_GET["video"], $_GET["mime"])));
    } else {
      output(checkPath($DIR, $_GET["video"]));
    }
  } else {
    player($_GET["video"]);
  }
} else {
  overview();
}
