Friends, I need to integrate this function of the system ffmpeg upload drag and drop. I’m doing well, but when I click to upload, nothing happens:
PHP Code:
$fn = (isset($_SERVER['HTTP_X_FILENAME']) ? $_SERVER['HTTP_X_FILENAME'] : false);
extension_loaded('ffmpeg') or die('Error in loading ffmpeg');
function ExtractThumb($in, $out)
{
$thumb_stdout;
$errors;
$retval = 0;
// Delete the file if it already exists
if (file_exists($out)) { unlink($out); }
$dir = rtrim(dirname(__FILE__), '/\\\\') . DIRECTORY_SEPARATOR . 'ffmpeg/ffmpeg';
// Use ffmpeg to generate a thumbnail from the movie
$cmd = "".$dir." -itsoffset -4 -i $in -vcodec mjpeg -vframes 1 -an -f rawvideo -s 320x240 $out 2>&1";
exec($cmd, $thumb_stdout, $retval);
}
if ($fn) {
// AJAX call
file_put_contents(
'uploads/' . $_SERVER['HTTP_X_HEIGHT'] . "_" . $fn,
file_get_contents('php://input')
);
echo "$fn uploaded";
ExtractThumb($fn, $fn . '.jpg');
exit();
}
else {
// form submit
$files = $_FILES['fileselect'];
foreach ($files['error'] as $id => $err) {
if ($err == UPLOAD_ERR_OK) {
$fn = $files['name'][$id];
move_uploaded_file(
$files['tmp_name'][$id],
'uploads/' . $fn
);
echo "<p>File $fn uploaded.</p>";
}
}
}
If using Chrome, I highly recommend opening Developer Tools, then go to the Network tab, then drag your file onto your webpage, and the network tab should show the AJAX request. Click on the request to see what output was generated (any errors, notices, warning, echo statements, etc). Then post those here so we can help you decipher those messages.
After clicking the file .js, I click on Headers?
You will want to click on the php file that your Ajax executes (if you don’t see one being executed, then your ajax request never fired).
And you will be primarily looking at the Response
The php file is not listed in Network. = /
Silly question, as I assumed you are attempting to do this via Ajax based on your PHP code. Are you using Ajax? Or are you primarily trying to upload it via a button?
The upload should be done by clicking the button. The js is the one you helped me to adapt:
(function() {
var filesThatWereDropped = new Array();
// getElementById
function $id(id) {
return document.getElementById(id);
}
// output information
function Output(msg) {
var m = $id("messages");
m.innerHTML = msg + m.innerHTML;
}
// file drag hover
function FileDragHover(e) {
e.stopPropagation();
e.preventDefault();
e.target.className = (e.type == "dragover" ? "hover" : "");
}
// file selection
function FileSelectHandler(e) {
// cancel event and hover styling
FileDragHover(e);
// fetch FileList object
var files = e.target.files || e.dataTransfer.files;
// process all File objects
for (var i = 0, f; f = files[i]; i++) {
ParseFile(f);
}
}
function UploadFiles(e) {
e.stopPropagation();
e.preventDefault();
// process all File objects
while (filesThatWereDropped.length > 0) {
var f = filesThatWereDropped.pop();
UploadFile(f);
}
}
// output file information
function ParseFile(file) {
fileInfo = "<div><strong>Nome:</strong> " + file.name + "</div>";
fileInfo += "<div><strong>Tamanho:</strong> " + file.size + " kb</div>";
fileInfo += "<div><strong>Tipo:</strong> " + file.type + "</div>";
document.getElementById('messages').innerHTML = fileInfo + document.getElementById('messages').innerHTML;
// display text
if (file.type.indexOf("text") == 0) {
var reader = new FileReader();
reader.onload = function(e) {
Output(
"<p><strong>" + file.name + ":</strong></p><pre>" +
e.target.result.replace(/</g, "<").replace(/>/g, ">") +
"</pre>"
);
}
reader.readAsText(file);
}
filesThatWereDropped.push(file);
}
// upload JPEG files
function UploadFile(file) {
// following line is not necessary: prevents running on SitePoint servers
if (location.host.indexOf("sitepointstatic") >= 0) return
var xhr = new XMLHttpRequest();
if (xhr.upload && file.type == "application/vnd.rn-realmedia-vbr" || file.type == "application/pdf" || file.type == "video/x-ms-wmv" || file.type == "video/x-flv" || file.type == "image/png" || file.type == "image/jpeg" || file.type == "image/gif" && file.size <= $id("MAX_FILE_SIZE").value) {
// create progress bar
var o = $id("progress");
var progress = o.appendChild(document.createElement("p"));
progress.appendChild(document.createTextNode("upload " + file.name));
// progress bar
xhr.upload.addEventListener("progress", function(e) {
var pc = parseInt(100 - (e.loaded / e.total * 100));
progress.style.backgroundPosition = pc + "% 0";
}, false);
// file received/failed
xhr.onreadystatechange = function(e) {
if (xhr.readyState == 4) {
progress.className = (xhr.status == 200 ? "success" : "failure");
}
};
// start upload
//'upload.php?titulo=teste'
xhr.open("POST", $id("upload").action, true);
xhr.setRequestHeader("X_FILENAME", file.name);
xhr.setRequestHeader("X_SIZE", file.size);
xhr.setRequestHeader("X_WIDTH", file.width);
xhr.setRequestHeader("X_HEIGHT", file.height);
xhr.send(file);
}
}
// initialize
function Init() {
var fileselect = $id("fileselect"),
filedrag = $id("filedrag"),
submitbutton = $id("btnSubmit");
// file select
fileselect.addEventListener("change", FileSelectHandler, false);
// is XHR2 available?
var xhr = new XMLHttpRequest();
if (xhr.upload) {
// file drop
filedrag.addEventListener("dragover", FileDragHover, false);
filedrag.addEventListener("dragleave", FileDragHover, false);
filedrag.addEventListener("drop", FileSelectHandler, false);
filedrag.style.display = "block";
submitbutton.addEventListener("click", UploadFiles, false);
}
}
// call initialization file
if (window.File && window.FileList && window.FileReader) {
Init();
}
})();
Ah, okay. So you would have needed to click the button to see the event register in the network tab.
Also, when you do that, be sure to change this code
// form submit
$files = $_FILES['fileselect'];
foreach ($files['error'] as $id => $err) {
if ($err == UPLOAD_ERR_OK) {
$fn = $files['name'][$id];
move_uploaded_file(
$files['tmp_name'][$id],
'uploads/' . $fn
);
echo "<p>File $fn uploaded.</p>";
}
}
To this
// form submit
$files = $_FILES['fileselect'];
foreach ($files['error'] as $id => $err) {
if ($err == UPLOAD_ERR_OK) {
$fn = $files['name'][$id];
move_uploaded_file(
$files['tmp_name'][$id],
'uploads/' . $fn
);
echo "<p>File $fn uploaded.</p>";
}
else {
echo "<p>{$id} - {$err}</p>";
}
}
So you can see the error you are receiving
Same thing. Whether I drag to select a file and when I click “Upload” nothing happens and no error returns.
Doesn’t the upload button invoke the UploadFiles function in your JavaScript? If that is the case, you should see a request start to happen in the Developer Tools Network section.
Now is uploading normally. I had forgotten to enable video .avi: file.type == “video/avi”.
The problem now is that the image is not being generated, only. This is wrong, I believe:
if ($fn) {
// AJAX call
file_put_contents(
'uploads/' . $_SERVER['HTTP_X_HEIGHT'] . "_" . $fn,
file_get_contents('php://input')
);
echo "$fn uploaded";
ExtractThumb('uploads/'.$fn, 'imgs/test.jpg');
exit();
}
I would try this because you are technically renaming the file when it is written to your server to have the height as a prefix:
if ($fn) {
$localFileName = 'uploads/' . $_SERVER['HTTP_X_HEIGHT'] . "_" . $fn;
// AJAX call
file_put_contents(
$localFileName,
file_get_contents('php://input')
);
echo "$fn uploaded";
ExtractThumb($localFileName, $localFileName . '.jpg');
exit();
}
It worked! Would you like to do so, is?
ExtractThumb($localFileName, ‘imgs/’ . $localFileName . ‘.jpg’);
Currently, both the video and the image is saved in the directory /uploads. I created a directory /imgs inside.
Another thing I’m trying to do is record the width and height of the image. Are being saved as “undefined”.
I’m doing this:
JS
xhr.open("POST", $id("upload").action, true);
xhr.setRequestHeader("X_FILENAME", file.name);
xhr.setRequestHeader("X_SIZE", file.size);
xhr.setRequestHeader("X_WIDTH", file.width);
xhr.setRequestHeader("X_HEIGHT", file.height);
xhr.send(file);
PHP
$localFileName = 'uploads/' . $_SERVER['HTTP_X_HEIGHT'] . "_" . $fn;
I’m not certain you can get the width and height of a video file the way you are attempting to. I bet it works for images, but not likely for video (I searched on google, but didn’t quickly find a solution, so you may want to try it yourself to see if you can come up with anything).
The below code should place the uploaded file in uploads, and the thumbnail in imgs
if ($fn) {
$uploadFileName = 'uploads/' . $_SERVER['HTTP_X_HEIGHT'] . "_" . $fn;
$imgFileName = 'imgs/' . $_SERVER['HTTP_X_HEIGHT'] . "_" . $fn;
// AJAX call
file_put_contents(
$uploadFileName,
file_get_contents('php://input')
);
echo "$fn uploaded";
ExtractThumb($uploadFileName, $imgFileName . '.jpg');
exit();
}
For video height and width I use ffmpeg. I get the dimensions of the images only.
How do I run the ExtractThumb () only if I’m uploading a video? I make an “if”?
I would add this to your JavaScript
xhr.setRequestHeader("X_TYPE", file.type);
Then check for your video types in your PHP before calling ExtractThumb
So it does not work:
if ($_SERVER['HTTP_X_TYPE'] == 'video/avi' || $_SERVER['HTTP_X_TYPE'] == 'video/x-ms-wmv' || $_SERVER['HTTP_X_TYPE'] == 'video/x-flv' || $_SERVER['HTTP_X_TYPE'] == 'application/vnd.rn-realmedia-vbr'){
ExtractThumb($uploadFileName, $imgFileName . '.jpg');
}
var_dump($_SERVER['HTTP_X_TYPE']);
if ($_SERVER['HTTP_X_TYPE'] == 'video/avi' || $_SERVER['HTTP_X_TYPE'] == 'video/x-ms-wmv' || $_SERVER['HTTP_X_TYPE'] == 'video/x-flv' || $_SERVER['HTTP_X_TYPE'] == 'application/vnd.rn-realmedia-vbr'){
ExtractThumb($uploadFileName, $imgFileName . '.jpg');
}
Open Developer Tools, Network tab, upload your video, click on the PHP file and paste the output of the Response section so I can see what the value of HTTP_X_TYPE is