<?php

$amime=array(
	     "flv"=>"video/flv",
	     "mpg"=>"video/mpeg",
	     "jpg"=>"image/jpeg",
	     "png"=>"image/png",
	     "gif"=>"image/gif",
	     "wmv"=>"video/asf",
	     "mp3"=>"audio/mpeg",
	     "mp4"=>"video/mp4",
	     "ogv"=>"video/ogg",
	     "ogm"=>"video/ogg",
	     "wav"=>"audio/x-wav",
	     "avi"=>"video/x-msvideo",
	     "webm"=>"video/webm",
	     );


function downloadFormat($id,$format) {
  global $amime;
  $id=intval($id); 
  $format=intval($format);
  $me=@mysql_fetch_array(mysql_query("SELECT * FROM media WHERE id='$id';"));
  //  Retourne un media dans un format donn�.
  if ($format<5) {
    $ext=substr($me["filename"],strrpos($me["filename"],".")+1);
    $mime=$amime[$ext]; if (!$mime) $mime="application/x-force-download";
    
    $filename="files/".$me["filename"];

    if (!is_file($filename)) {
      header('HTTP/1.0 404 Not Found');
      exit();
      return false;
    }

    if (!is_readable($filename)) {
      header('HTTP/1.0 403 Forbidden');
      exit();
      return false;
    }

    $stat = @stat($filename);
    $etag = sprintf('%x-%x-%x', $stat['ino'], $stat['size'], $stat['mtime'] * 1000000);

    header('Expires: ');
    header('Cache-Control: ');
    header('Pragma: ');

    if(isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == $etag) {
      header('Etag: "' . $etag . '"');
      header('HTTP/1.0 304 Not Modified');
      exit();
      return true;
    } elseif(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $stat['mtime']) {
      header('Last-Modified: ' . date('r', $stat['mtime']));
      header('HTTP/1.0 304 Not Modified');
      exit();
      return true;
    }

    header('Last-Modified: ' . date('r', $stat['mtime']));
    header('Etag: "' . $etag . '"');
    header('Accept-Ranges: bytes');

    ob_start();
    print_r($_SERVER);
    file_put_contents("/tmp/rien",ob_get_clean());

    $begin=0;
    $end=$stat['size'];

    if (isset($_SERVER['HTTP_RANGE'])) {
      if (preg_match('/bytes=\h*(\d+)-(\d*)/i', trim($_SERVER['HTTP_RANGE']), $matches)) {
	$begin=intval($matches[1]);
	if(!empty($matches[2]))
	  $end=intval($matches[2]);
      }
    }

  
    if($begin>0||$end<$size)
      header('HTTP/1.0 206 Partial Content');
    else
      header('HTTP/1.0 200 OK'); 
    
    if($begin>0||$end<$stat['size'])
      header('HTTP/1.0 206 Partial Content');
    else
      header('HTTP/1.0 200 OK'); 

    header('Content-Length:'.($end-$begin));
    header("Content-Range: bytes ".$begin."-".$end."/".$stat["size"]."");
    header("Content-Type: ".$mime);
    header("Content-Disposition: attachment; filename=\"".str_replace('"',"'",$me["filename"])."\"");

    $fm=@fopen($filename,'rb');
    fseek($fm,$begin,0);
    while (!feof($fm)&&$cur<$end&&(connection_status()==0)) { 
      print fread($fm,min(1024*16,$end-$cur));
      $cur+=1024*16;
    }
    exit();    
  }

  $f=@mysql_fetch_array(mysql_query("SELECT * FROM formats WHERE id='$format';"));
  if (file_exists("formats/$format/$id")) {
    header("Content-Type: ".$f["mime"]);
    $strp=strrpos($me["filename"],"."); if ($strp==0) $strp=strlen($me["filename"]);
    header("Content-Disposition: attachment; filename=\"".str_replace('"',"'",substr($me["filename"],0,$strp)).".".$f["ext"]."\"");
    header("Content-Length: " . filesize("formats/$format/$id")); 
    readfile("formats/$format/$id");
    exit();
  }
  echo "Fichier non trouv�. Probablement en attente d'encodage";
}



function createImage($id,$filename,$format) {
  // Cr�e l'image au format $format (cf table formats) pour le media d'id $id et de nom $filename
  switch ($format) {
  case 5: // PNG taille d'origine
    exec("convert ".escapeshellarg("files/".$filename)." png:formats/$format/$id ");
    break;
  case 7: // JPEG 800x600 qualite 80%
    exec("convert ".escapeshellarg("files/".$filename)." -resize 800x600 -quality 80 jpeg:formats/$format/$id ");
    break;
  case 8: // JPEG 250x250 qualite 80%
    exec("convert ".escapeshellarg("files/".$filename)." -resize 250x250 -quality 80 jpeg:formats/$format/$id ");
    break;
  case 15: // JPEG 32x32 qualite 80%
    exec("convert ".escapeshellarg("files/".$filename)." -resize 32x32 -quality 80 jpeg:formats/$format/$id ");
    break;
  default:
    echo "ERREUR : FORMAT $format NON RECONNU POUR LE MEDIA $id\n";
    return;
  }
  $size=filesize("formats/$format/$id");
  mysql_query("INSERT INTO mediaformat SET media=$id, format=$format, size=$size;");
}



function createAudio($id,$filename,$format) {
  // Cr�e le fichier audio au format $format (cf table formats) pour le media d'id $id et de nom $filename
  switch ($format) {
  case 9: // OGG Vorbis 96kbps
    unset($out);
    exec("ffmpeg -i ".escapeshellarg("files/".$filename)."  -vn -acodec libvorbis -f ogg -ar 44100 -ab 96k -ac 2 -y formats/$format/$id",$out,$ret);
    if ($ret!=0) {
      // TODO ~ logguer l'erreur ...
    }
    break;
  case 10: // MP3 96Kbps
    unset($out);
    exec("ffmpeg -i ".escapeshellarg("files/".$filename)."  -vn -acodec libmp3lame -f mp3 -ar 44100 -ab 96k -y formats/$format/$id ",$out,$ret);
    if ($ret!=0) {
      // TODO ~ logguer l'erreur ...
    }
    break;
  case 11: // WAV / PCM qualit� CD
    unset($out);
    exec("ffmpeg -i ".escapeshellarg("files/".$filename)."  -vn -acodec pcm_s16le -f wav -ar 44100 -y formats/$format/$id ",$out,$ret);
    if ($ret!=0) {
      // TODO ~ logguer l'erreur ...
    }
    break;
  default:
    echo "ERREUR : FORMAT $format NON RECONNU POUR LE MEDIA $id\n";
    return;
  }
  $size=filesize("formats/$format/$id");
  mysql_query("INSERT INTO mediaformat SET media=$id, format=$format, size=$size;");
}


function createVideo($id,$filename,$format) {
  $size=0; // may be created by the encoder...
  $size2=0; // may be created by the encoder...
  // Cr�e le fichier video au format $format (cf table formats) pour le media d'id $id et de nom $filename
  switch ($format) {
  case 12: // Flash Sorenson / MP3 diffusion web (400Kbps total)
    unset($out);
    exec("ffmpeg -i ".escapeshellarg("files/".$filename)." -vcodec flv -b 300k -s 360x288 -r 12  -acodec libmp3lame -f flv -ar 44100 -ab 96k -y formats/$format/$id ",$out,$ret);
    if ($ret!=0) {
      // TODO ~ logguer l'erreur ...
    }
    break;
  case 13: // Ogg / Theora diffusion web (400Kbps total)
    unset($out);
    //    exec("ffmpeg -i ".escapeshellarg("files/".$filename)." -vcodec libtheora -b 300k -s 360x288 -r 12  -acodec vorbis -f ogg -ar 44100 -ab 96k -y formats/$format/$id ",$out,$ret);
    //    exec("ffmpeg2theora ".escapeshellarg("files/".$filename)." -V 300k -A 96k -x 360 -y 288 -F 12  -o formats/$format/$id ",$out,$ret);
    exec("2theora ".escapeshellarg("files/".$filename)." ".escapeshellarg("formats/$format/$id"),$out,$ret);
    if ($ret!=0) {
      // TODO ~ logguer l'erreur ...
    }
    break;
  case 14: // DV headerless (~15Mbps)
    unset($out);
    exec("ffmpeg -i ".escapeshellarg("files/".$filename)." -vcodec dvvideo -s 720x576 -r 25 -acodec pcm_s16le -f dv -ar 48000 -ac 2 -t 300 -y formats/$format/$id ",$out,$ret);
    /*
    if ($ret!=0) {
      // TODO ~ logguer l'erreur ...
    }
    */
    touch("formats/$format/$id");
    break;
  case 16: // Image vignette 250x250 max + 32x32 max
    if (!file_exists("formats/14/".$id) || filesize("formats/14/".$id)<144000) 
      return;
    unset($out);
    $skip=intval(filesize("formats/14/".$id)/144000/3);
    @unlink("/tmp/img.dv");
    exec("dd if=".escapeshellarg("formats/14/".$id)." of=/tmp/img.dv bs=144000 count=1 skip=$skip",$out,$ret);
    if ($ret==0) {
      exec("ffmpeg -i /tmp/img.dv -an -y /tmp/img.png",$out,$ret);
      if ($ret==0) {
	exec("convert /tmp/img.png -resize 250x250 -quality 60% jpg:formats/16/".$id."");
	exec("convert /tmp/img.png -resize 32x32 -quality 60% jpg:formats/16/".$id."_small");
	exec("convert /tmp/img.png -resize 96x77 -quality 60% jpg:formats/16/".$id."_medium");
      }
    }
    if ($ret!=0) {
      // TODO ~ logguer l'erreur ...
    }
    break;
  case 17: // DV headerless (~15Mbps) SANS LIMITE DE DUREE
    unset($out);
    //    exec("ffmpeg -i ".escapeshellarg("files/".$filename)." -vcodec dvvideo -s 720x576 -r 25 -acodec pcm_s16le -f dv -ar 48000 -ac 2 -y formats/$format/$id ",$out,$ret);
    touch("formats/$format/$id");
    if ($ret!=0) {
      // TODO ~ logguer l'erreur ...
    }
    break;

  case 18: // Theora/Vorbis/Ogg at 2Mbps & 500Kbps
    unset($out);
    $me=@mysql_fetch_assoc(mq("SELECT * FROM media WHERE id='$id'"));
    // Get the ratio : 4:3 or 16:9 
    // And get the max resolution available. 

    list($sx,$sy,$aspect)=getSizeAndAspect($me);
    if ($sx!=$me["vx"] || $sy!=$me["vy"]) {
      $vf=" -vf pad=".$sx.":".$sy." ";
    }
    list($smallx,$smally,$bigx,$bigy)=getEncodeSizes($aspect,$sx,$sy);

    $bigb="1900k"; $bigbmax="4000k"; $bigab="128k";
    $smallb="404k"; $smallbmax="1500k"; $smallab="96k";
    /*
    // BIG encoding : 
    exec("ffmpeg -y -i ".escapeshellarg("files/".$filename)." $vf -r 30000/1001 -s ".$bigx."x".$bigy." -aspect ".$aspect."  -vcodec libtheora -g 15 -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -b ".$bigb." -bt 1024k -maxrate ".$bigbmax." -bufsize 4M -an -pass 1 -an -f ogg formats/$format/".$id."_big.ogg",$out,$ret);  
    exec("ffmpeg -y -i ".escapeshellarg("files/".$filename)." $vf -r 30000/1001 -s ".$bigx."x".$bigy." -aspect ".$aspect."  -vcodec libtheora -g 15 -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -b ".$bigb." -bt 1024k -maxrate ".$bigbmax." -bufsize 4M -acodec libvorbis -ac 2 -ab ".$bigab." -y -f ogg formats/$format/".$id."_big.ogg",$out,$ret);
    $size=@filesize("formats/$format/".$id."_big.ogg");
    // SMALL encoding : 
    exec("ffmpeg -y -i ".escapeshellarg("files/".$filename)." $vf -r 30000/1001 -s ".$smallx."x".$smally." -aspect ".$aspect."  -vcodec libtheora -g 15 -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -b ".$smallb." -bt 1024k -maxrate ".$smallbmax." -bufsize 4M -an -pass 1 -an -f ogg formats/$format/".$id."_small.ogg",$out,$ret);  
    exec("ffmpeg -y -i ".escapeshellarg("files/".$filename)." $vf -r 30000/1001 -s ".$smallx."x".$smally." -aspect ".$aspect."  -vcodec libtheora -g 15 -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -b ".$smallb." -bt 1024k -maxrate ".$smallbmax." -bufsize 4M -acodec libvorbis -ac 2 -ab ".$smallab." -y -f ogg formats/$format/".$id."_small.ogg",$out,$ret);
    $size2=@filesize("formats/$format/".$id."_small.ogg");
    */
    $size2=1000;
    $size=1000;

    if ($ret!=0) {
      // TODO ~ logguer l'erreur ...
    }
    break;

  case 19: // Vp8/Vorbis/Webm at 1Mbps

    $me=@mysql_fetch_assoc(mq("SELECT * FROM media WHERE id='$id'"));

    // Get the ratio : 4:3 or 16:9 
    // And get the max resolution available. 
    list($sx,$sy,$aspect)=getSizeAndAspect($me);
    if ($sx!=$me["vx"] || $sy!=$me["vy"]) {
      $vf=" -vf pad=".$sx.":".$sy." ";
    }
    list($smallx,$smally,$bigx,$bigy)=getEncodeSizes($aspect,$sx,$sy);
    
    $bigb="1900k"; $bigbmax="4000k"; $bigab="128k";
    $smallb="404k"; $smallbmax="1500k"; $smallab="96k";

    unset($out);
    exec("ffmpeg -i ".escapeshellarg("files/".$filename)." $vf -s ".$bigx."x".$bigy." -aspect ".$aspect." -vpre libvpx-720p -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -b ".$bigb." -bt 1024k -maxrate ".$bigbmax." -bufsize 4M -pass 1 -an -f webm -y formats/$format/".$id."_big.webm",$out,$ret);  
    exec("ffmpeg -i ".escapeshellarg("files/".$filename)." $vf -s ".$bigx."x".$bigy." -aspect ".$aspect." -vpre libvpx-720p -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -b ".$bigb." -bt 1024k -maxrate ".$bigbmax." -bufsize 4M -pass 2 -acodec libvorbis -ab ".$bigab." -ac 2 -f webm -y formats/$format/".$id."_big.webm",$out,$ret);
    $size=@filesize("formats/$format/".$id."_big.webm");
    // SMALL encoding : 
    exec("ffmpeg -i ".escapeshellarg("files/".$filename)." $vf -s ".$smallx."x".$smally." -aspect ".$aspect." -vpre libvpx-720p -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -b ".$smallb." -bt 1024k -maxrate ".$smallbmax." -bufsize 4M -pass 1 -an -f webm -y formats/$format/".$id."_small.webm",$out,$ret);  
    exec("ffmpeg -i ".escapeshellarg("files/".$filename)." $vf -s ".$smallx."x".$smally." -aspect ".$aspect." -vpre libvpx-720p -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -b ".$smallb." -bt 1024k -maxrate ".$smallbmax." -bufsize 4M -pass 2 -acodec libvorbis -ab ".$smallab." -ac 2 -f webm -y formats/$format/".$id."_small.webm",$out,$ret);
    $size2=@filesize("formats/$format/".$id."_small.webm");
    
    if ($ret!=0) {
      // TODO ~ logguer l'erreur ...
    }
    break;


  case 20: // H.264/AAC/MP4 at 1Mbps

    $me=@mysql_fetch_assoc(mq("SELECT * FROM media WHERE id='$id'"));
    // Get the ratio : 4:3 or 16:9 
    // And get the max resolution available. 
    list($sx,$sy,$aspect)=getSizeAndAspect($me);
    if ($sx!=$me["vx"] || $sy!=$me["vy"]) {
      $vf=" -vf pad=".$sx.":".$sy." ";
    }
    list($smallx,$smally,$bigx,$bigy)=getEncodeSizes($aspect,$sx,$sy);
    
    $bigb="1900k"; $bigbmax="4000k"; $bigab="128k";
    $smallb="404k"; $smallbmax="1500k"; $smallab="96k";

    unset($out);
    // BIG encoding
    exec("ffmpeg -y -i ".escapeshellarg("files/".$filename)." $vf -r 30000/1001 -s ".$bigx."x".$bigy." -aspect ".$aspect." -vcodec libx264 -b ".$bigb." -bt 1024k -maxrate ".$bigbmax." -flags +loop -cmp +chroma -me_range 16 -g 300 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -rc_eq \"blurCplx^(1-qComp)\" -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -coder 0 -refs 1 -bufsize 4M -level 21 -partitions parti4x4+partp8x8+partb8x8 -subq 5 -f mp4 -pass 1 -an formats/$format/".$id."_big.tmp",$out,$ret);  
    exec("ffmpeg -y -i ".escapeshellarg("files/".$filename)." $vf -r 30000/1001 -s ".$bigx."x".$bigy." -aspect ".$aspect." -vcodec libx264 -b ".$bigb." -bt 1024k -maxrate ".$bigbmax." -flags +loop -cmp +chroma -me_range 16 -g 300 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -rc_eq \"blurCplx^(1-qComp)\" -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -coder 0 -refs 1 -bufsize 4M -level 21 -partitions parti4x4+partp8x8+partb8x8 -subq 5 -f mp4 -pass 2 -acodec libfaac -ac 2 -ar 44100 -ab ".$bigab." formats/$format/".$id."_big.tmp",$out,$ret);
    exec("qt-faststart formats/$format/".$id."_big.tmp formats/$format/".$id."_big.mp4 2>&1");
    exec("rm -f formats/$format/".$id."_big.tmp 2>&1");
    $size=@filesize("formats/$format/".$id."_big.mp4");

    // SMALL encoding
    exec("ffmpeg -y -i ".escapeshellarg("files/".$filename)." $vf -r 30000/1001 -s ".$smallx."x".$smally." -aspect ".$aspect." -vcodec libx264 -b ".$smallb." -bt 1024k -maxrate ".$smallbmax." -flags +loop -cmp +chroma -me_range 16 -g 300 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -rc_eq \"blurCplx^(1-qComp)\" -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -coder 0 -refs 1 -bufsize 4M -level 21 -partitions parti4x4+partp8x8+partb8x8 -subq 5 -f mp4 -pass 1 -an formats/$format/".$id."_small.tmp",$out,$ret);  
    exec("ffmpeg -y -i ".escapeshellarg("files/".$filename)." $vf -r 30000/1001 -s ".$smallx."x".$smally." -aspect ".$aspect." -vcodec libx264 -b ".$smallb." -bt 1024k -maxrate ".$smallbmax." -flags +loop -cmp +chroma -me_range 16 -g 300 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -rc_eq \"blurCplx^(1-qComp)\" -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -coder 0 -refs 1 -bufsize 4M -level 21 -partitions parti4x4+partp8x8+partb8x8 -subq 5 -f mp4 -pass 2 -acodec libfaac -ac 2 -ar 44100 -ab ".$smallab." formats/$format/".$id."_small.tmp",$out,$ret);
    exec("qt-faststart formats/$format/".$id."_small.tmp formats/$format/".$id."_small.mp4 2>&1");
    exec("rm -f formats/$format/".$id."_small.tmp 2>&1");
    $size2=@filesize("formats/$format/".$id."_small.mp4");

    if ($ret!=0) {
      // TODO ~ logguer l'erreur ...
    }
    break;

  case 21: 
    // TORRENT of Webm/Ogg/mp4 big :
    if (
	!file_exists("formats/20/".$id."_big.mp4") ||
	!file_exists("formats/19/".$id."_big.webm") ||
	//	!file_exists("formats/18/".$id."_big.ogg")
	false
	) {
      $size=0;
      break;
    }
    // Ok, we have all three of them, let's make a copy and a .torrent : 
    $me=@mysql_fetch_assoc(mq("SELECT * FROM media WHERE id='$id'"));
    $tmp=substr(md5(microtime(true)),0,8);
    mkdir("/tmp/".$tmp);
    $file=str_replace("/"," ",$me["title"]);
    mkdir("/tmp/".$tmp."/".$file);
    copy("formats/20/".$id."_big.mp4","/tmp/$tmp/$file/".$file.".mp4");
    copy("formats/19/".$id."_big.webm","/tmp/$tmp/$file/".$file.".webm");
    //    copy("formats/18/".$id."_big.ogg","/tmp/$tmp/$file/".$file.".ogg");
    exec("cd /tmp/$tmp ; btmakemetafile udp://tracker.publicbt.com:80/announce ".escapeshellarg($file)." --comment ".escapeshellarg($me["description"])." --announce_list ".escapeshellarg("udp://tracker.publicbt.com:80/announce|udp://tracker.openbittorrent.com:80/announce")." --target ".escapeshellarg(getcwd()."/formats/21/".$id.".torrent")." ");
    $size=filesize("formats/21/".$id.".torrent");
    if ($size) {
      mkdir("/data/stuff/www/content/$file");
      copy("formats/20/".$id."_big.mp4","/data/stuff/www/content/$file/".$file.".mp4");
      copy("formats/19/".$id."_big.webm","/data/stuff/www/content/$file/".$file.".webm");
      //      copy("formats/18/".$id."_big.ogg","/data/stuff/www/content/$file/".$file.".ogg");
      copy("formats/21/".$id.".torrent","/data/stuff/www/watch/".$id.".torrent");
    }
    exec("rm -rf /tmp/$tmp");
    break;
  default:
    echo "ERREUR : FORMAT $format NON RECONNU POUR LE MEDIA VIDEO $id\n";
    return;
  }
  if (!$size) $size=@filesize("formats/$format/$id");
  mysql_query("INSERT INTO mediaformat SET media=$id, format=$format, size='$size', size2='$size2';");
}




function downloadDV($id,$debut,$fin) {
  global $amime;
  $format=14; // DV quoi ...
  $id=intval($id); 
  $format=intval($format);
  $me=@mysql_fetch_array(mysql_query("SELECT * FROM media WHERE id='$id';"));
  //  Retourne un media dans un format donn�.
  $f=@mysql_fetch_array(mysql_query("SELECT * FROM formats WHERE id='$format';"));
  if (file_exists("formats/$format/$id")) {
    header("Content-Type: ".$f["mime"]);
    header("Content-Disposition: attachment; filename=\"".str_replace('"',"'",substr($me["filename"],0,strrpos($me["filename"],".")))."_".$debut."_".$fin.".".$f["ext"]."\"");
    header("Content-Length: " . (144000*25*($fin-$debut)) ); 
    $f=fopen("formats/$format/$id","rb");
    fseek($f,$debut*144000*25);
    for($i=0;$i<$fin-$debut;$i++) {
      for($j=0;$j<439;$j++) {
	echo fread($f,8192);
      }
      echo fread($f,3712); // Soit au total 8192*439 + 3712 = 144000*25 = 1sec DV.
    }
    exit();
  }
  echo "Fichier non trouv�. Probablement en attente d'encodage";
}


?>