idProjections.com - Freelance Designer, Coder, and Developer

Hello! My Name is Kyle Knight and I'm a Web Developer.

Kyle Knight - Web Developer

PHP/MySQL w/ FFmpeg Video Upload and Fancybox w/ Flowplayer w/ a Thumbnail Preview

Okay. Wow! Where to even start? Let’s start with getting everything you need all in one place.

I’ll wait here while you go and get all of that…

Back? Great!

First, let’s get connected to the database.

<?php
$dbhost = "localhost"; //This might need to change depending on your host setup
$dbname = "database_name";
$dbuser = "database_user";
$dbpass = "database_pa$$w0rd";

$conn = mysql_connect($dbhost, $dbuser, $dbpass) or die ('Error connecting to mysql');

$db = mysql_select_db($dbname);
?>

I usually make this it’s own file and just include it at the top of the pages that will need database access. So, let’s create a folder called “inc” or “includes” and name it dbconnect.inc.php

With that all said and done, here comes the fun part! I will post it all out and then break it down into segments to understand what each part is doing.

<?php
include('inc/dbconnect.inc.php');

$output = "Please upload your video in AVI, WMV, MOV or MPG. 20MB Limit.";

//      width/height has to be multiples of two
function makeMultipleTwo ($value) {
  $sType = gettype($value/2);

  if($sType == “integer”) {
    return $value;
  } else {
    return ($value-1);
  }
}

if(isset($_POST['submit'])) {
  $caption = stripslashes($_POST['video_caption']);

  /****************************** LOAD FFMPEG */

  $extension = "ffmpeg";
  $extension_soname = $extension . "." . PHP_SHLIB_SUFFIX;
  $extension_fullname = PHP_EXTENSION_DIR . "/" . $extension_soname;

  // load extension
  if (!extension_loaded($extension)) {
    dl($extension_soname) or die("Can't load extension $extension_fullname\n");
  }

  /****************************** SAVE RAW VIDEO TO DIRECTORY */

  $current_time = time();
  $video_file = $_FILES['video_file'];
  $fileName = $video_file["name"];
  $fileSize = $video_file["size"];
  $fileNameParts = explode( ".", $fileName );
  $fileExtension = end( $fileNameParts );
  $fileExtension = strtolower( $fileExtension );

  $newFile = "uploads/videos/" . $current_time .".". $fileExtension;
  if(file_exists($newFile)) { // If file already exists in the uploads folder
    $output = "Too many files uploading simultaneously. Please wait a few moments and try again.";
  } elseif ($fileSize > 20971520) {
    $output = "Please upload a video smaller than 20MB.";
  }
  $result = move_uploaded_file($video_file["tmp_name"], $newFile);
  if($result != 1){ $output = "Error Uploading File."; }

  if($fileExtension=="avi" || $fileExtension=="wmv" || $fileExtension=="mpeg" || $fileExtension=="mpg" || $fileExtension=="mov") {

    /****************************** SET DESTINATION DIR AND INVOKE NEW MOVIE */

    $flvFile = "uploads/videos/flv/" . $current_time .".flv";
    exec("ffmpeg -i ".$newFile." -ar 22050 -ab 32 -f flv -s 320x240 ".$flvFile." | flvtool2 -U stdin ".$flvFile."");

    /****************************** CREATE THUMBNAIL OF VIDEO */

    $thumbFile = "uploads/videos/thumbs/" . $current_time . ".jpg";
    exec("ffmpeg  -itsoffset -2  -i ".$newFile." -vcodec mjpeg -vframes 1 -an -f rawvideo -s 110x90 ".$thumbFile."");

    /****************************** WRITE TO DATABASE */
    $page_url = "uploads/videos/".$current_time.".php";
    mysql_query("INSERT INTO videos (id, filename, tn_filename, page_url, caption) VALUES ('', '$flvFile', '$thumbFile', '$page_url', '$caption')");
    $partyPageFile = file_get_contents('tpl/video_template.php');

    $partyPageFileWrite = fopen($page_url, 'w');

    fwrite($partyPageFileWrite, $partyPageFile);
    fclose($partyPageFileWrite);

    unlink($newFile);
    $output = "Your video was successfully uploaded. Please allow up to 24 hours for moderation.";
  } else {
    $output = "Please only upload your video in AVI, WMV, MOV or MPG formats only.";
  }
}

?>

Don’t get scared, it’s not as bad as it looks!

First off, let’s connect to the database.

include('inc/dbconnect.inc.php');

Then we’re going to set the initial output of what’s going to show up in the HTML of the page

$output = "Please upload your video in AVI, WMV, MOV or MPG. 20MB Limit.";

This can say anything you want, but basically, these are the file types we will be accepting.
The initial function will be taking the video that is uploaded and making sure the resolution of the video is a multiple of two, if it’s not, it’ll remove a pixel and make so.

//      width/height has to be multiples of two
function makeMultipleTwo ($value) {
  $sType = gettype($value/2);

  if($sType == “integer”) {
    return $value;
  } else {
    return ($value-1);
  }
}

Now it gets the nitty gritty stuff that you’ll need to pay attention to and make changes to the code to match your setup.

if(isset($_POST['submit'])) {

This makes sure the PHP within does not fire off until the form is submitted.

$caption = stripslashes($_POST['video_caption']);

This grabs the form input for the caption of the video.

$extension = "ffmpeg";
  $extension_soname = $extension . "." . PHP_SHLIB_SUFFIX;
  $extension_fullname = PHP_EXTENSION_DIR . "/" . $extension_soname;

  // load extension
  if (!extension_loaded($extension)) {
    dl($extension_soname) or die("Can't load extension $extension_fullname\n");
  }

This loads up the ffmpeg extension. So far, there shouldn’t be anything you need to change, so don’t worry. It’s coming though, so pay attention! If this dies, you will need to work with your system administrator to make sure the ffmpeg extension is setup in the php.ini file along with correct permissions enabled.

$current_time = time();
  $video_file = $_FILES['video_file'];
  $fileName = $video_file["name"];
  $fileSize = $video_file["size"];
  $fileNameParts = explode( ".", $fileName );
  $fileExtension = end( $fileNameParts );
  $fileExtension = strtolower( $fileExtension );

This sets a few variables that will be needed later on. Basically, we will be renaming all of the video files to the current UNIX time, this will make sure you don’t get any duplicate files in your database and server. Then it grabs the name of the file you uploaded and the size of it. It then strips out the file name and takes the extension to make sure we accept that type of file.

$newFile = "uploads/videos/" . $current_time .".". $fileExtension;
  if(file_exists($newFile)) { // If file already exists in the uploads folder
    $output = "Too many files uploading simultaneously. Please wait a few moments and try again.";
  } elseif ($fileSize > 20971520) {
    $output = "Please upload a video smaller than 20MB.";
  }
  $result = move_uploaded_file($video_file["tmp_name"], $newFile);
  if($result != 1){ $output = "Error Uploading File."; }

Here is where you will need to work on possibly changing some variables.
I have setup a folder called “uploads” that is writable with sub directory of “videos”, “flv” and “thumbs” which are writable.
For the time being, we are temporarily saving the raw file to the server, but only after making sure that for some crazy reason two people are uploading a file simultaneously at the exact same millisecond. This is HIGHLY unlikely, but better safe than sorry. Then we verify that the video file is no larger than 20mb. After this is confirmed, we will save the raw movie file to the server. If it can’t save the file you will get an error. If you get the error, check the permissions of the directory.

Pretty easy so far, right? Nothing too terribly complicated.

if($fileExtension=="avi" || $fileExtension=="wmv" || $fileExtension=="mpeg" || $fileExtension=="mpg" || $fileExtension=="mov") { ... } else {
    $output = "Please only upload your video in AVI, WMV, MOV or MPG formats only.";
  }

This is taking the file extension we pulled out earlier and making sure we accept it. If not the else statement will fire off.

Here is where the magic happens!

$flvFile = "uploads/videos/flv/" . $current_time .".flv";
    exec("ffmpeg -i ".$newFile." -ar 22050 -ab 32 -f flv -s 320x240 ".$flvFile." | flvtool2 -U stdin ".$flvFile."");

This is creating $flvFile which is a flv empty shell that is filled in after fmmpeg and flvtool do their conversions. To understand exactly what is going on here. Please check out the FFmpeg Documentation. If this is over your head, then just use what I have here. You’ll end up with a 320×240 FLV video.

$thumbFile = "uploads/videos/thumbs/" . $current_time . ".jpg";
    exec("ffmpeg  -itsoffset -2  -i ".$newFile." -vcodec mjpeg -vframes 1 -an -f rawvideo -s 110x90 ".$thumbFile."");

Now that we have the video file, let’s create a thumbnail to show for when the user views your video gallery.

Again, just leave it all the same and you’ll end up with a 110×90 thumbnail, make changes to this at your own discretion.

Well, now that we have a FLV and it’s thumbnail counterpart, let’s write all of this to your database, remove the raw video file and move on to some more fun stuff!

$page_url = "uploads/videos/".$current_time.".php";
    mysql_query("INSERT INTO videos (id, filename, tn_filename, page_url, caption) VALUES ('', '$flvFile', '$thumbFile', '$page_url', '$caption')");
    $partyPageFile = file_get_contents('tpl/video_template.php');

    $partyPageFileWrite = fopen($page_url, 'w');

    fwrite($partyPageFileWrite, $partyPageFile);
    fclose($partyPageFileWrite);

    unlink($newFile);
    $output = "Your video was successfully uploaded. Please allow up to 24 hours for moderation.";

We create a variable to write to the database then we will need to open up template file (we haven’t created this yet, don’t worry).
It’ll write the file that allows the fancybox and flowplayer to function.

Now, beneath all of this PHP, let’s pop in a quick HTML form for the video upload.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"  dir="ltr" lang="en-US">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Video Upload</title>
  </head>
<body>
  <p><?php echo "$output"; ?></p>
  <form id="videoUpload" action="" method="post" enctype="multipart/form-data">
    <p><label for="image">Select Video</label><input type="file" id="video_file" name="video_file" /></p>
    <p><label for="caption">Video Caption</label><input type="text" id="video_caption" name="video_caption" /></p>
    <p><input type="submit" value="Upload!" name="submit" /></p>
  </form>
</body>
</html>

Tags: , , ,

Leave a Reply