PDA

View Full Version : Need some PHP assistance...



Marci
07-15-2008, 04:21 AM
Am in middle of sorting a website... need to be able to upload video via PHP. Server (FreeBSD6.2) is all setup for encoding & playback and that bit's done n' dusted and verified working (Lame / ffMpeg / Ruby / FLVTool2 / SWFObject / JWPlayer). Have previously been doing conversions as and when required on WinXP workstation then ftping them up - I have scripts scanning folders to build playlists on-the-fly etc, but am now at the point where I just wanna be able to tell folks to upload their video clips thru the site rather than coming to me...

Here's as far as I've got...

The form:

<form enctype="multipart/form-data" action="processupload.php" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="104857600" />
Send this file: <input name="userfile" type="file" />
<input type="submit" value="Send File" />
</form>

processupload.php:

<?php
error_reporting(E_ALL);
ini_set("session.gc_maxlifetime","10800");
$uploaddir = '/INCOMINGPATH/';
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);

echo '<pre>';
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
echo "File is valid, and was successfully uploaded.\n";
} else {
echo "File upload was unsuccesful.\n";
}
if (chmod($uploadfile, 0744)) {
echo "CHMOD was succesful. \n";
} else {
echo "CHMOD failed. File is executable. \n";
}

$last_line = system('ffmpeg -i '.$uploadfile.' '.$uploadfile.'.flv', $retval);
$last_line = system('cat '.$uploadfile.'.flv | flvtool2 -U stdin '.$uploadfile.'.flv', $retval);
exec('rm '.$uploadfile.'');

echo 'Here is some more debugging info:';
print_r($_FILES);
print "</pre>";

?>


Thus far, works peachy... it accepts uploaded file and automatically converts to FLV using FFMPEG then injects MetaData using FLVTOOL2... but I need to tweak it a bit more and it goes beyond my (very basic) skills... am a designer not a programmer.

1 - I need it to only allow upload of video formats (avi, mpg, mov)...
2 - the filename of the flv file produced is currently originalfilename.originalextension.flv - I need to lose the original extension...

Can anyone point me in the right direction?

Marci
07-15-2008, 06:19 AM
Nevermind - sorted it...

yngndrw
07-22-2008, 02:15 PM
Just incase you did it a different way:

$FileNameArray = explode( '.', $UploadFile );
$FileExtension = array_pop( $FileNameArray );
$FileName = implode( '.', $FileNameArray );
You can then check FileExtension for valid file types and use FileName for the conversion call.
It will also accept filenames which have dots in them.

E.g.: Video.File.avi

Marci
07-22-2008, 11:51 PM
Here's what I came up with in the end... it works... whether it does so with any grace or dignity is a different matter!

Pre-requisites (following is for FreeBSD btw)

Step 1 - Install FFMpeg (converts video formats)

cd /usr/ports/multimedia/ffmpeg
make config (plonk a cross in LAME libmp3codec box >> OK )
&& make install clean


Step 2 - Install Ruby (interpreter for FLVTool2)

cd /usr/ports/lang/ruby18
&& make install clean


Step 3 - Install FLVTool2 (injects metadata into FLV files)

cd /usr/ports/multimedia/ruby-flvtool2
&& make install clean


Step 4 - Configure Ruby
ruby setup.rb config
ruby setup.rb setup


The form (upload.php):

<?php
$maxsize = ini_get('upload_max_filesize');
if (!is_numeric($maxsize)) {
if (strpos($maxsize, 'G') !== false)
$size = intval($maxsize)*1024*1024*1024;
elseif (strpos($maxsize, 'M') !== false)
$size = intval($maxsize)*1024*1024;
elseif (strpos($maxsize, 'K') !== false)
$size = intval($maxsize)*1024; }
echo "<p style=\"text-align:center;\"><strong>This facility should be used within school only.</strong> Please do not attempt to upload files from home.<br /><br />Upload only mpg, avi, wmv or mov files.<br />Ensure there are no spaces in the filename, and that the file is less than ".$maxsize."b in size.<br />If your file is larger than ".$maxsize."b you will need to take it to ICT Support to be put on the site.<br /><br />To remove spaces, right-click on the file and select <strong>\"Rename\"</strong>. You should then replace any spaces in the filename with underscores ( _ )<br />Underscore = shift and the minus key on the top row of the keyboard to the right of the zero.<br />To check the file size, right-click on the file and select <strong>\"Properties\"</strong>. The <strong>Size on Disk:</strong> field must be LESS than ".$maxsize."b</p>";
echo "<div style=\"width:250px;margin-left:auto;margin-right:auto;\"><form enctype=\"multipart/form-data\" action=\"processupload.php\" method=\"POST\">
<input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\".$size.\" />
Send this file: <input name=\"userfile\" type=\"file\" />
<br />Choose subject area:
<select name=\"subjectarea\" id=\"subject\">
<option value=\"eng\">English</option>
<option value=\"drama\">Drama</option>
<option value=\"music\">Music</option>
<option value=\"PE\">PE</option>
<option value=\"history\">History</option>
<option value=\"geography\">Geography</option>
<option value=\"MFL\">MFL</option>
<option value=\"ict\">ICT</option>
<option value=\"maths\">Maths</option>
<option value=\"phse\">PHSE</option>
<option value=\"re\">RE</option>
<option value=\"Science\">Science</option>
<option value=\"public\">Public Area</option>
</select>
<br /><br />
<input type=\"submit\" value=\"Send File\" /></form></div>";
?>

Processing the upload form (processupload.php):

<?php
error_reporting(E_ALL);
ini_set("session.gc_maxlifetime","10800");
$finallocation = $_REQUEST['subjectarea'];
$allowable_ext = array('avi','mpg','mov','wmv');
$pieces = explode('.', $_FILES['userfile']['name']);
$ext = $pieces[count($pieces) - 1];
if(!in_array($ext, $allowable_ext)) {
echo "Error Code 001: Invalid filetype or no file selected - you may only upload files smaller than 100Mb which end in .mpg, .avi, .wmv or .mov.<br /><br /><a href=\"upload.php\">Return to the Upload Form</a>\n"; exit;
}
$uploaddir = '/home/user/uploads/';
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);
$origname = basename($_FILES['userfile']['name']);
$newname = substr($origname, 0, -4);
$newfile = $uploaddir . $newname;
$uf = escapeshellcmd($uploadfile);
$nf = escapeshellcmd($newfile);
if ((($_FILES['userfile']['type'] == "video/mpeg")
|| ($_FILES['userfile']['type'] == "video/msvideo")
|| ($_FILES['userfile']['type'] == "video/quicktime")
|| ($_FILES['userfile']['type'] == "video/x-ms-wmv"))
&& ($_FILES['userfile']['size'] < 104857600))
{
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
echo "File is valid, and was successfully uploaded.<br />\n";
} else {
echo "Error Code 002: File upload was unsuccesful.<br />\n";
}
if (chmod($uploadfile, 0744)) {
echo "CHMOD was succesful.<br />\n";
} else {
echo "Error Code 003: CHMOD failed. File is executable.<br />\n";
}

$last_line = system('ffmpeg -i '.$uf.' '.$nf.'.flv', $retval);
$last_line = system('cat '.$nf.'.flv | flvtool2 -U stdin '.$nf.'.flv', $retval);
echo "Source file has been succesfully converted to FLV...<br />";
exec('rm '.$uf.'');
echo "Original source file has now been removed...<br />";
exec('cp '.$nf.'.flv /home/user/public_html/video/'.$finallocation.'/');
exec('rm '.$nf.'.flv');
echo "The converted FLV file has now been added to your chosen subject area's playlist.<br />";
echo "For reference, the chosen subject area was <strong>".$finallocation."</strong>.<br />You may now <a href=\"../protected/subjectmedia.php\"><strong>head to the playlist</strong></a> to verify the file.";
}
else { echo "Error Code 004: Invalid filetype - you may only upload files smaller than 100Mb which end in .mpg, .avi, .wmv or .mov.<br /><br /><a href=\"upload.php\">Go back to Upload Form</a>\n"; }
?>


Building playlist on-the-fly (SUBJECT_playlist.php):

<?php
$filter = ".flv";
$directory = "SUBJECT/"; //<< ie: Eng / Maths / Science etc...
$site = "http://www.site.com/video/";

@$d = dir($directory);
if ($d) {
while($entry=$d->read()) {
$ps = strpos(strtolower($entry), $filter);
if (!($ps === false)) {
$items[] = $entry;
}
}
$d->close();
sort($items);
}

header("content-type:text/xml;charset=utf-8");
echo "<playlist version='1' xmlns='http://xspf.org/ns/0/'>\n";
echo " <title>SUBJECT Media Playlist</title>\n";
echo " <info>http://www.site.com</info>\n";
echo " <trackList>\n";

foreach($items as $value)
{
$title = preg_replace('/.flv/', '', $value);
$title = preg_replace('/_/', ' ', $title);
print " <track>\n";
print " <title>" . $title . "</title>\n";
print " <location>" . $site . '/video/' . $directory . '/' . $value . "</location>\n";
print " </track>\n";
}

echo " </trackList>\n";
echo "</playlist>\n";
?>



And the player itself (using JW Player (http://www.jeroenwijering.com/) & SWFObject (http://code.google.com/p/swfobject/)):

<script type="text/javascript" src="http://www.site.com/js/swfobject.js"></script>
<div id="player">Please enable Javascript to use our Media
Player</div>
<script type="text/javascript">
var so = new SWFObject('http://www.site.com/video/mediaplayer.swf','mpl','620','260','8');
so.addParam('allowscriptaccess','always');
so.addParam('allowfullscreen','true');
so.addVariable('height','260');
so.addVariable('width','620');
so.addVariable('file','http://www.site.com/video/SUBJECT_playlist.php');
so.addVariable('backcolor','0x000000');
so.addVariable('frontcolor','0xffffff');
so.addVariable('lightcolor','0xffffff');
so.addVariable('displayheight','240');
so.addVariable('displaywidth','350');
so.addVariable('overstretch','fit');
so.addVariable('showstop','true');
so.addVariable('showdownload','false');
so.addVariable('repeat','list');
so.write('player');
</script>


Site Structure:

/home/user/public_html/{protected_by_htaccess}/upload.php
/home/user/public_html/{protected_by_htaccess}/processupload.php
/home/user/public_html/js/swfobject.js
/home/user/public_html/video/mediaplayer.swf
/home/user/public_html/video/SUBJECT_playlist.php
/home/user/public_html/video/SUBJECT/*.flv
/home/user/uploads/

IanB
07-23-2008, 12:44 PM
The code looks fine, Marci, and I can see me using it as an example starting point for some future projects. :up:

I'd just mention, in case you or any other HTML authors weren't aware, that the code you've given is not HTML compliant and won't validate. It will validate as XHTML however. The reason is the <tag /> endings which are specifically syntactically incorrect in HTML. If you are using a non-XHTML DTD for your pages you should remove ALL those trailing slashes.

For more information, read http://www.cs.tut.fi/~jkorpela/html/empty.html which is an excellent information resource on validation (it's actually linked from the W3C validation page :p:).

Marci
07-23-2008, 01:31 PM
Aye - sorry, I do everything as xhtml... have done fer a while now...!

Todo list: some form of upload status bar for the duration of the file-upload. Not found a simple solution yet that doesn't encompass a file manager also...

Teqqles
08-21-2008, 05:04 AM
Maybe I'm being a little picky here, but I'd offload the system processes into a cron job, I'm not sure you really want to be processing video for every upload, a better solution would be to fire them into a directory ready for processing and have a separate script bash through them in its own time (faster page response for the user and less chance of a security concern).

I'd also consider refactoring the line '$finallocation = $_REQUEST['subjectarea'];' which then directly uses this variable to complete a system path, a definite no-no.

One final thing (and then you can laugh at my attempts at water cooling when project: Chrome is complete ;) ) - are you using error_reporting( ALL ) on a production environment? Fine for development, but it may well give away to much about your scripting activities on a world-wide box...

Marci
05-23-2009, 06:19 AM
Resurrecting an old one... error_reporting(ALL) was just whilst I got everything working... s'gone now. Hadn't picked up on that $finallocation pointer... shall re-examine that this week whilst I've no students in breaking things to distract me. I've been sidetracked for a while now getting an LDAP authentication system to work and simultaneously initiate Moodle and Invisionboard cookies, and then remove all of them again on logoff from the central LDAP system... s'getting RIGHT on my tits! Moodle sucks for ease of working out what the hell it's doing, and doesn't have a decently accessible API for authenticating via an external app :( Invision however is ace for that, but then falls over trying to match up AD groups against forum groups... watercooling was certainly more fun!

ahmad
05-26-2009, 04:09 PM
If I understand your process correctly, you want users to put their ad username/pass into moodle then log them in?

Marci
07-02-2009, 08:19 AM
Nope... I want them to put their AD User and Pass into a page that isn't part of Moodle. That page should then ideally call the moodle api invisibly to create necessary auth cookies/sessions (which is perfectly doable with Invisionboard's API, but there's no documentation to say how it can be done for Moodle), so that when they DO go to moodle, it doesn't prompt them for credentials as this was already done when they logged into our staff portal.

At the moment, all I can find is instructions to do the reverse... log into Moodle first and use that to create the auth cookies for all the other systems.