In this code create only Video on chrome, i want video with Audio with one mp4/webm file. is it possible in PHP?
please give me helpful solutions.
var mediaConstraints = { audio: true, video: true };
//var isFirefox = true;
document.querySelector('#start-recording').onclick = function() {
this.disabled = true;
navigator.getUserMedia(mediaConstraints, onMediaSuccess, onMediaError);
};
document.querySelector('#stop-recording').onclick = function() {
this.disabled = true;
mediaRecorder.stop();
};
var mediaRecorder;
function onMediaSuccess(stream) {
var video = document.createElement('video');
var videoWidth = document.getElementById('video-width').value || 320;
var videoHeight = document.getElementById('video-height').value || 240;
video = mergeProps(video, {
controls: true,
id:"preview",
width: videoWidth,
height: videoHeight,
src: URL.createObjectURL(stream)
});
video.play();
//videot='2000';
videosContainer.appendChild(video);
videosContainer.appendChild(document.createElement('hr'));
mediaRecorder = new MediaStreamRecorder(stream);
mediaRecorder.mimeType = 'video/mp4'; // this line is mandatory
mediaRecorder.videoWidth = videoWidth;
mediaRecorder.videoHeight = videoHeight;
mediaRecorder.ondataavailable = function(blob) {
//alert(blob.audio);
//alert(blob.video);
// var a = document.createElement('a');
// a.target = '_blank';
// a.innerHTML = 'Open Recorded Video No. ' + (index++) + ' (Size: ' + bytesToSize(blob.size) + ') Time Length: ' + getTimeLength(timeInterval);
// a.href = URL.createObjectURL(blob);
//videosContainer.appendChild(a);
// videosContainer.appendChild(document.createElement('hr'));
var facedeteval = document.getElementById('facedetectvalue').value;
if(facedeteval !='1')
{
//alert(facedeteval);
var testuserID = document.getElementById("tuid").value;
var capId =document.getElementById("capimg").value;
//alert(capId);
var fileType = 'video'; // or "audio"
var vname = document.getElementById('sect_id').value;
var res = vname;
fileName =res;
var fileName = res+(index++)+'.mp4'; // or "wav" or "ogg"
var formData = new FormData();
formData.append(fileType + '-filename', fileName);
formData.append(fileType + '-blob', blob);
formData.append('test_uid', testuserID);
formData.append('cap_id', capId);
function xhr(url, data, callback) {
var request = new XMLHttpRequest();
request.onreadystatechange = function () {
if (request.readyState == 4 && request.status == 200) {
callback(location.href + request.responseText);
}
};
request.open('POST', url);
request.send(data);
}
xhr('save.php', formData, function (fileURL) {
alert('video save');
stopflag = '0';
document.getElementById('facedetectvalue').value = '1';
});
}
};
var timeInterval = document.querySelector('#time-interval').value;
if(timeInterval) timeInterval = parseInt(timeInterval);
else timeInterval = 5 * 1000;
// get blob after specific time interval
mediaRecorder.start(timeInterval);
document.querySelector('#stop-recording').disabled = false;
}
function onMediaError(e) {
console.error('media error', e);
}
var videosContainer = document.getElementById('videos-container');
var index = 1;
// below function via: http://goo.gl/B3ae8c
function bytesToSize(bytes) {
var k = 1000;
var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
if (bytes === 0) return '0 Bytes';
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(k)),10);
return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i];
}
// below function via: http://goo.gl/6QNDcI
function getTimeLength(milliseconds) {
var data = new Date(milliseconds);
return data.getUTCHours()+" hours, "+data.getUTCMinutes()+" minutes and "+data.getUTCSeconds()+" second(s)";
}
window.onbeforeunload = function() {
document.querySelector('#start-recording').disabled = false;
};
Related
I have this record.js script to toggle a recording that is currently working as expected.
function Record_Current(config) {
config = config || {};
var self = this;
var audioInput;
var audioNode;
var bufferSize = config.bufferSize || 4096;
var recordedData = [];
var recording = false;
var recordingLength = 0;
var startDate;
var audioCtx;
this.toggleRecording = function() {
if (recording) {
self.stop();
} else {
self.start();
}
};
this.start = function() {
// reset any previous data
recordedData = [];
recordingLength = 0;
// webkit audio context shim
audioCtx = new(window.AudioContext || window.webkitAudioContext)();
if (audioCtx.createJavaScriptNode) {
audioNode = audioCtx.createJavaScriptNode(bufferSize, 1, 1);
} else if (audioCtx.createScriptProcessor) {
audioNode = audioCtx.createScriptProcessor(bufferSize, 1, 1);
} else {
throw 'WebAudio not supported!';
}
audioNode.connect(audioCtx.destination);
navigator.mediaDevices.getUserMedia({ audio: true })
.then(onMicrophoneCaptured)
.catch(onMicrophoneError);
};
this.stop = function() {
stopRecording(function(blob) {
self.blob = blob;
config.onRecordingStop && config.onRecordingStop(blob);
});
};
this.upload = function(url, params, callback) {
var formData = new FormData();
formData.append("audio", self.blob, config.filename || 'recording.wav');
for (var i in params)
formData.append(i, params[i]);
var request = new XMLHttpRequest();
request.upload.addEventListener("progress", function(e) {
callback('progress', e, request);
});
request.upload.addEventListener("load", function(e) {
callback('load', e, request);
});
request.onreadystatechange = function(e) {
var status = 'loading';
if (request.readyState === 4) {
status = request.status === 200 ? 'done' : 'error';
}
callback(status, e, request);
};
request.open("POST", url);
request.send(formData);
};
function stopRecording(callback) {
// stop recording
recording = false;
// to make sure onaudioprocess stops firing
window.localStream.getTracks().forEach((track) => { track.stop(); });
audioInput.disconnect();
audioNode.disconnect();
exportWav({
sampleRate: sampleRate,
recordingLength: recordingLength,
data: recordedData
}, function(buffer, view) {
self.blob = new Blob([view], { type: 'audio/wav' });
callback && callback(self.blob);
});
}
function onMicrophoneCaptured(microphone) {
if (config.visualizer)
visualize(microphone);
// save the stream so we can disconnect it when we're done
window.localStream = microphone;
audioInput = audioCtx.createMediaStreamSource(microphone);
audioInput.connect(audioNode);
audioNode.onaudioprocess = onAudioProcess;
recording = true;
self.startDate = new Date();
config.onRecordingStart && config.onRecordingStart();
sampleRate = audioCtx.sampleRate;
}
function onMicrophoneError(e) {
console.log(e);
alert('Unable to access the microphone.');
}
function onAudioProcess(e) {
if (!recording) {
return;
}
recordedData.push(new Float32Array(e.inputBuffer.getChannelData(0)));
recordingLength += bufferSize;
self.recordingLength = recordingLength;
self.duration = new Date().getTime() - self.startDate.getTime();
config.onRecording && config.onRecording(self.duration);
}
function visualize(stream) {
var canvas = config.visualizer.element;
if (!canvas)
return;
var canvasCtx = canvas.getContext("2d");
var source = audioCtx.createMediaStreamSource(stream);
var analyser = audioCtx.createAnalyser();
analyser.fftSize = 2048;
var bufferLength = analyser.frequencyBinCount;
var dataArray = new Uint8Array(bufferLength);
source.connect(analyser);
function draw() {
// get the canvas dimensions
var width = canvas.width,
height = canvas.height;
// ask the browser to schedule a redraw before the next repaint
requestAnimationFrame(draw);
// clear the canvas
canvasCtx.fillStyle = config.visualizer.backcolor || '#fff';
canvasCtx.fillRect(0, 0, width, height);
if (!recording)
return;
canvasCtx.lineWidth = config.visualizer.linewidth || 2;
canvasCtx.strokeStyle = config.visualizer.forecolor || '#f00';
canvasCtx.beginPath();
var sliceWidth = width * 1.0 / bufferLength;
var x = 0;
analyser.getByteTimeDomainData(dataArray);
for (var i = 0; i < bufferLength; i++) {
var v = dataArray[i] / 128.0;
var y = v * height / 2;
i === 0 ? canvasCtx.moveTo(x, y) : canvasCtx.lineTo(x, y);
x += sliceWidth;
}
canvasCtx.lineTo(canvas.width, canvas.height / 2);
canvasCtx.stroke();
}
draw();
}
function exportWav(config, callback) {
function inlineWebWorker(config, cb) {
var data = config.data.slice(0);
var sampleRate = config.sampleRate;
data = joinBuffers(data, config.recordingLength);
console.log(data);
function joinBuffers(channelBuffer, count) {
var result = new Float64Array(count);
var offset = 0;
var lng = channelBuffer.length;
for (var i = 0; i < lng; i++) {
var buffer = channelBuffer[i];
result.set(buffer, offset);
offset += buffer.length;
}
return result;
}
function writeUTFBytes(view, offset, string) {
var lng = string.length;
for (var i = 0; i < lng; i++) {
view.setUint8(offset + i, string.charCodeAt(i));
}
}
var dataLength = data.length;
// create wav file
var buffer = new ArrayBuffer(44 + dataLength * 2);
var view = new DataView(buffer);
writeUTFBytes(view, 0, 'RIFF'); // RIFF chunk descriptor/identifier
view.setUint32(4, 44 + dataLength * 2, true); // RIFF chunk length
writeUTFBytes(view, 8, 'WAVE'); // RIFF type
writeUTFBytes(view, 12, 'fmt '); // format chunk identifier, FMT sub-chunk
view.setUint32(16, 16, true); // format chunk length
view.setUint16(20, 1, true); // sample format (raw)
view.setUint16(22, 1, true); // mono (1 channel)
view.setUint32(24, sampleRate, true); // sample rate
view.setUint32(28, sampleRate * 2, true); // byte rate (sample rate * block align)
view.setUint16(32, 2, true); // block align (channel count * bytes per sample)
view.setUint16(34, 16, true); // bits per sample
writeUTFBytes(view, 36, 'data'); // data sub-chunk identifier
view.setUint32(40, dataLength * 2, true); // data chunk length
// write the PCM samples
var index = 44;
for (var i = 0; i < dataLength; i++) {
view.setInt16(index, data[i] * 0x7FFF, true);
index += 2;
}
if (cb) {
return cb({
buffer: buffer,
view: view
});
}
postMessage({
buffer: buffer,
view: view
});
}
var webWorker = processInWebWorker(inlineWebWorker);
webWorker.onmessage = function(event) {
callback(event.data.buffer, event.data.view);
// release memory
URL.revokeObjectURL(webWorker.workerURL);
};
webWorker.postMessage(config);
}
function processInWebWorker(_function) {
var workerURL = URL.createObjectURL(new Blob([_function.toString(),
';this.onmessage = function (e) {' + _function.name + '(e.data);}'
], {
type: 'application/javascript'
}));
var worker = new Worker(workerURL);
worker.workerURL = workerURL;
console.log(worker);
return worker;
}
function renderRecording(workerURL, list) {
const worker_url = URL.createObjectURL(workerURL);
const li = document.createElement('li');
const audio = document.createElement('audio');
const anchor = document.createElement('a');
anchor.setAttribute('href', workerURL);
const now = new Date();
anchor.setAttribute(
'download',
`recording-${now.getFullYear()}-${(now.getMonth() + 1).toString().padStart(2, '0')}-${now.getDay().toString().padStart(2, '0')}--${now.getHours().toString().padStart(2, '0')}-${now.getMinutes().toString().padStart(2, '0')}-${now.getSeconds().toString().padStart(2, '0')}.webm`
);
anchor.innerText = 'Download';
audio.setAttribute('src', worker_url);
audio.setAttribute('controls', 'controls');
li.appendChild(audio);
li.appendChild(anchor);
list.appendChild(li);
}
}
and this Google Drive Script
var driveLink = require('stream');
module.exports.uploadFile = function(req) {
var file;
console.log("driveApi upload reached")
function blobToFile(req) {
file = req.body.blob
file.lastModifiedDate = new Date();
file.name = req.body.word;
return file;
}
var bufStream = new stream.PassThrough();
bufStream.end(file);
console.log(typeof 42);
var folderId = "Folder"; // Enter Folder Name
var fileMetadata = {
"name": req.body.word,
parents: [folderId]
}
var media = {
mimeType: "audio/mp3",
body: bufStream
}
drive.files.create({
auth: jwToken,
resource: fileMetadata,
media: media,
fields: "id"
}, function(err, file) {
if (err) {
console.error(err);
} else {
console.log("File Id: ", file.id);
}
console.log("driveApi upload accomplished")
});
}
I have tried a few different approaches to combining the two to make it so it automatically saves the .wav file to the Drive API but it does not work.
I believe I am either not merging the two scripts together the right way or I am missing something. Do I need to use V3 of the Google API?
If anyone could provide some guidance on how to merge the two properly that would be greatly appreciated. Thank you!
I want to play webm whose duration is >5s (1.32 mins)
this webm.
I'have been trying to modify this example, when I run it, chunks are not appending and video stops at some point, and I'm getting this error:
InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable
sourceBuffer.appendBuffer(new Uint8Array(e.target.result));
Could someone clarify please?
<script>
var FILE = 'test2.webm'; //that webm
var NUM_CHUNKS = 10;
var video = document.querySelector('video');
window.MediaSource = window.MediaSource || window.WebKitMediaSource;
if (!!!window.MediaSource) {
alert('MediaSource API is not available');
}
var mediaSource = new MediaSource();
//document.querySelector('[data-num-chunks]').textContent = NUM_CHUNKS;
video.src = window.URL.createObjectURL(mediaSource);
function callback(e) {
var sourceBuffer = mediaSource.addSourceBuffer('video/webm; codecs="vorbis,vp8"');
logger.log('mediaSource readyState: ' + this.readyState);
GET(FILE, function(uInt8Array) {
var file = new Blob([uInt8Array], {
type: 'video/webm'
});
var chunkSize = Math.ceil(file.size / NUM_CHUNKS);
logger.log('num chunks:' + NUM_CHUNKS);
logger.log('chunkSize:' + chunkSize + ', totalSize:' + file.size);
// Slice the video into NUM_CHUNKS and append each to the media element.
var i = 0;
(function readChunk_(i) {
var reader = new FileReader();
// Reads aren't guaranteed to finish in the same order they're started in,
// so we need to read + append the next chunk after the previous reader
// is done (onload is fired).
reader.onload = function(e) {
sourceBuffer.appendBuffer(new Uint8Array(e.target.result));
logger.log('appending chunk:' + i);
if (i == NUM_CHUNKS - 1) {
mediaSource.endOfStream();
} else {
if (video.paused) {
video.play(); // Start playing after 1st chunk is appended.
}
readChunk_(++i);
}
};
var startByte = chunkSize * i;
var chunk = file.slice(startByte, startByte + chunkSize);
reader.readAsArrayBuffer(chunk);
})(i); // Start the recursive call by self calling.
});
}
mediaSource.addEventListener('sourceopen', callback, false);
mediaSource.addEventListener('webkitsourceopen', callback, false);
mediaSource.addEventListener('webkitsourceended', function(e) {
logger.log('mediaSource readyState: ' + this.readyState);
}, false);
function GET(url, callback) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'arraybuffer';
xhr.send();
xhr.onload = function(e) {
if (xhr.status != 200) {
alert("Unexpected status code " + xhr.status + " for " + url);
return false;
}
callback(new Uint8Array(xhr.response));
};
}
</script>
<script>
function Logger(id) {
this.el = document.getElementById('log');
}
Logger.prototype.log = function(msg) {
var fragment = document.createDocumentFragment();
fragment.appendChild(document.createTextNode(msg));
fragment.appendChild(document.createElement('br'));
this.el.appendChild(fragment);
};
Logger.prototype.clear = function() {
this.el.textContent = '';
};
var logger = new Logger('log');
</script>
<script>
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-22014378-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script');
ga.type = 'text/javascript';
ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s);
})();
</script>
Your video is working well in my player based on example you provided. I do not call mediaSource.endOfStream(); and i am not slicing file using FileReader class (useless).
Use Range http header to get slices from you webserver directly.
Example:
function GET(url, from = 0, to = '') {
return new Promise((accept, reject) => {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'arraybuffer';
xhr.setRequestHeader("Range", `bytes=${from}-${to}`);
xhr.send();
xhr.onload = function(e) {
if (xhr.status != 200 && xhr.status != 206) {
alert("Unexpected status code " + xhr.status + " for " + url);
reject(e);
}
accept(xhr.response);
};
});
}
I am building an application for ASP.Net MVC 5, in which I need to record a live video and audio stream from the webcam/microphone. I have decided on a web app based solution, RecordRTC. I have used the demo from, Muaz-Khan's github as a starting point, and modified it for my specifications.
The problem I am having is that I am unable to determine how to reduce the size of the webm that is being created. Right now it is about 1.7MB a second, my goal is for it to be 4-10MB a minute.
Also the file that is created from this does not possess time metadata, meaning I cannot use the seek-bar to go to a specific time. i.e. it says 3 secs have elapsed 0 remain, and still runs.
Any help would be appreciated.
NOTE: I am aware that support for the below code will only work in Firefox. I will simply wait for Chrome to add support, and therefore have removed the workaround Muaz Khan has in the demo.
< script >
//script 1
document.createElement('article')< /script>
<script>
//script 2
function PostBlob(blob, fileType, fileName) {
/ / FormData
var formData = new FormData();
formData.append(fileType + '-filename', fileName);
formData.append(fileType + '-blob', blob);
// progress-bar
var hr = document.createElement('hr');
container.appendChild(hr);
var strong = document.createElement('strong');
strong.id = 'percentage';
strong.innerHTML = fileType + ' upload progress: ';
container.appendChild(strong);
var progress = document.createElement('progress');
container.appendChild(progress);
// POST the Blob using XHR2
xhr('/Video/PostRecordedAudioVideo', formData, progress, percentage, function(fName) {
container.appendChild(document.createElement('hr'));
var mediaElement = document.createElement(fileType);
var source = document.createElement('source');
source.src = location.href + 'Files/' + fName.replace(/"/g, '');
if (fileType == 'video') source.type = 'video/webm; codecs="vp8, vorbis"';
if (fileType == 'audio') source.type = 'audio/ogg';
mediaElement.appendChild(source);
mediaElement.controls = true;
container.appendChild(mediaElement);
mediaElement.play();
progress.parentNode.removeChild(progress);
strong.parentNode.removeChild(strong);
hr.parentNode.removeChild(hr);
});
}
var record = document.getElementById('record');
var stop = document.getElementById('stop');
var audio = document.querySelector('audio');
var recordVideo = document.getElementById('record-video');
var preview = document.getElementById('preview');
var container = document.getElementById('container');
var recordAudio, recordVideo;
record.onclick = function() {
record.disabled = true;
navigator.getUserMedia({
audio: {
mandatory: {
googEchoCancellation: false,
googAutoGainControl: false,
googNoiseSuppression: false,
googHighpassFilter: false,
sampleRate: true
},
optional: []
},
video: true
}, function(stream) {
preview.src = window.URL.createObjectURL(stream);
preview.play();
//var legalBufferValues = [256, 512, 1024, 2048, 4096, 8192, 16384];
// sample-rates in at least the range 22050 to 96000.
recordAudio = RecordRTC(stream, {
onAudioProcessStarted: function() {}
});
recordAudio.startRecording();
stop.disabled = false;
}, function(error) {
alert(JSON.stringify(error, null, '\t'));
});
};
var fileName;
stop.onclick = function() {
record.disabled = false;
stop.disabled = true;
preview.src = '';
fileName = Math.round(Math.random() * 99999999) + 99999999 + ".webm";
recordAudio.stopRecording(function(url) {
preview.src = url;
PostBlob(blob, 'video', fileName);
});
};
function xhr(url, data, progress, percentage, callback) {
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState == 4 && request.status == 200) {
callback(request.responseText);
}
};
if (url.indexOf('/Video/DeleteFile') == -1) {
request.upload.onloadstart = function() {
percentage.innerHTML = 'Upload started...';
};
request.upload.onprogress = function(event) {
progress.max = event.total;
progress.value = event.loaded;
percentage.innerHTML = 'Upload Progress ' + Math.round(event.loaded / event.total * 100) + "%";
};
request.upload.onload = function() {
percentage.innerHTML = 'Saved!';
};
}
request.open('POST', url);
request.send(data);
}; < /script>
#{ ViewBag.Title = "Video Record"; }
<--Script 1 goes here-->
<!-- script used for audio/video/gif recording -->
#Scripts.Render("~/bundles/RTCRecording")
<article>
<section class="experiment">
<p style="text-align:center;">
<video id="preview" controls style="border: 1px solid rgb(15, 158, 238);"></video>
</p>
<hr />
<button id="record">Record</button>
<button id="stop" disabled>Stop</button>
<div id="container" style="padding:1em 2em;"></div>
</section>
<--Script 2 goes here-->
</article>
I am working on around 40 Large images each of size 9000KB.
i have below code ,all images are loading at a time which makes my screen to freeze,I want that my control will wait until the first image is successfully progress then loads completely then move on to the next one.any idea is helpful..
//dropping around 40 images
dropbox.addEventListener("drop", dropUpload, false);
function dropUpload(event) {
noop(event);
var dropMethod = event.dataTransfer;
var classicMethod = event.target;
var dropedFiles = (dropMethod == undefined) ? classicMethod.files: dropMethod.files;
for ( var i = 0; i < dropedFiles.length; i++) {
addFilesToUpload(dropedFiles[i]);
}
}
function addFilesToUpload(file) {
var li = document.createElement("li"), div = document.createElement("div"), img, progressBarContainer = document
.createElement("div"), progressBar = document.createElement("div"), tBody;
li.appendChild(div);
progressBarContainer.className = "progress-bar-container";
progressBar.className = "progress-bar";
progressBar.setAttribute("id", "proBar_" + (indexN++));
progressBarContainer.appendChild(progressBar);
li.appendChild(progressBarContainer);
var reader = new FileReader();
reader.onerror = function(event) {
alert("couldn't read file " + event.target.error.code);
};
// Present file info and append it to the list of files
fileInfo = "<div><strong>Name:</strong> " + file.name + "</div>";
fileInfo += "<div><strong>Size:</strong> " + parseInt(file.size / 1024, 10)
+ " kb</div>";
fileInfo += "<div><strong>Type:</strong> " + file.type + "</div>";
div.innerHTML = fileInfo;
if (reader !== "undefined" && (/image/i).test(file.type)) {
img = document.createElement("img");
img.setAttribute("class", "thumb");
img.setAttribute("id", "img_" + (indexN++));
reader.onload = (function(img, li) {
return function(evt) {
img.src = evt.target.result;
img.file = file;
};
}(img, li));
reader.readAsDataURL(file);
}
reader.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
progressBar.style.width = (evt.loaded / evt.total) * 100 + "%";
}
}, false);
reader.addEventListener("load", function() {
progressBarContainer.className += " uploaded";
progressBar.innerHTML = "";
}, false);
tBody = getTableBodyLayout(img, li);
document.getElementById("images_table").appendChild(tBody);
}
You can change addFilesToUpload() to take a callback when the file is done and change dropUpload() to initiate one at a time.
function dropUpload(event) {
noop(event);
var dropMethod = event.dataTransfer;
var classicMethod = event.target;
var dropedFiles = (dropMethod == undefined) ? classicMethod.files: dropMethod.files;
var filesDone = 0;
// local function to process the next file
function next() {
if (filesDone < dropedFiles.length) {
addFilesToUpload(dropedFiles[filesDone++], next);
}
}
// do the first one
next();
}
function addFilesToUpload(file, doneCallback) {
var li = document.createElement("li"), div = document.createElement("div"), img, progressBarContainer = document
.createElement("div"), progressBar = document.createElement("div"), tBody;
li.appendChild(div);
progressBarContainer.className = "progress-bar-container";
progressBar.className = "progress-bar";
progressBar.setAttribute("id", "proBar_" + (indexN++));
progressBarContainer.appendChild(progressBar);
li.appendChild(progressBarContainer);
var reader = new FileReader();
reader.onerror = function(event) {
alert("couldn't read file " + event.target.error.code);
};
// Present file info and append it to the list of files
fileInfo = "<div><strong>Name:</strong> " + file.name + "</div>";
fileInfo += "<div><strong>Size:</strong> " + parseInt(file.size / 1024, 10)
+ " kb</div>";
fileInfo += "<div><strong>Type:</strong> " + file.type + "</div>";
div.innerHTML = fileInfo;
if (reader !== "undefined" && (/image/i).test(file.type)) {
img = document.createElement("img");
img.setAttribute("class", "thumb");
img.setAttribute("id", "img_" + (indexN++));
reader.onload = (function(img, li) {
return function(evt) {
img.src = evt.target.result;
img.file = file;
// call the callback to tell the caller that this file is done now
doneCallback();
};
}(img, li));
reader.readAsDataURL(file);
}
reader.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
progressBar.style.width = (evt.loaded / evt.total) * 100 + "%";
}
}, false);
reader.addEventListener("load", function() {
progressBarContainer.className += " uploaded";
progressBar.innerHTML = "";
}, false);
tBody = getTableBodyLayout(img, li);
document.getElementById("images_table").appendChild(tBody);
}
If you want to wait to proceed to the next image until each image has loaded, then you could change the reader.onload handler to this:
reader.onload = (function(img, li) {
return function(evt) {
img.onload = function() {
// call the callback to tell the caller that this file is done now
doneCallback();
};
img.src = evt.target.result;
img.file = file;
};
}(img, li));
I use this code to upload files, and this code have a progressbar. The problem with this code is that it never send me to "upload.php" after it have uploaded the file, after it reach 100% on the progressbar. (It's not my code).
The code:
// get form data for POSTing
//var vFD = document.getElementById('upload_form').getFormData(); // for FF3
var vFD = new FormData(document.getElementById('upload_form'));
// create XMLHttpRequest object, adding few event listeners, and POSTing our data
var oXHR = new XMLHttpRequest();
oXHR.upload.addEventListener('progress', uploadProgress, false);
oXHR.addEventListener('load', uploadFinish, false);
oXHR.addEventListener('error', uploadError, false);
oXHR.addEventListener('abort', uploadAbort, false);
oXHR.open('POST', 'upload.php');
oXHR.send(vFD);
The whole script
// common variables
var iBytesUploaded = 0;
var iBytesTotal = 0;
var iPreviousBytesLoaded = 0;
var iMaxFilesize = 1048576; // 1MB
var oTimer = 0;
var sResultFileSize = '';
var uploadingcanceld = "حدث خطأ أثناء تحميل الملف";
function secondsToTime(secs) { // we will use this function to convert seconds in normal time format
var hr = Math.floor(secs / 3600);
var min = Math.floor((secs - (hr * 3600))/60);
var sec = Math.floor(secs - (hr * 3600) - (min * 60));
if (hr < 10) {hr = "0" + hr; }
if (min < 10) {min = "0" + min;}
if (sec < 10) {sec = "0" + sec;}
if (hr) {hr = "00";}
return hr + ':' + min + ':' + sec;
};
function bytesToSize(bytes) {
var sizes = ['Bytes', 'KB', 'MB'];
if (bytes == 0) return 'n/a';
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + sizes[i];
};
function fileSelected() {
// hide different warnings
document.getElementById('upload_response').style.display = 'none';
document.getElementById('error').style.display = 'none';
document.getElementById('error2').style.display = 'none';
document.getElementById('abort').style.display = 'none';
document.getElementById('warnsize').style.display = 'none';
// get selected file element
var oFile = document.getElementById('ufile').files[0];
// filter for image files
var rFilter = /^(image\/bmp|image\/gif|image\/jpeg|image\/png|image\/tiff)$/i;
if (! rFilter.test(oFile.type)) {
document.getElementById('error').style.display = 'block';
return;
}
// little test for filesize
if (oFile.size > iMaxFilesize) {
document.getElementById('warnsize').style.display = 'block';
return;
}
// get preview element
var oImage = document.getElementById('preview');
// prepare HTML5 FileReader
var oReader = new FileReader();
oReader.onload = function(e){
// e.target.result contains the DataURL which we will use as a source of the image
oImage.src = e.target.result;
oImage.onload = function () { // binding onload event
// we are going to display some custom image information here
sResultFileSize = bytesToSize(oFile.size);
document.getElementById('fileinfo').style.display = 'block';
document.getElementById('filename').innerHTML = 'Name: ' + oFile.name;
document.getElementById('filesize').innerHTML = 'Size: ' + sResultFileSize;
document.getElementById('filetype').innerHTML = 'Type: ' + oFile.type;
document.getElementById('filedim').innerHTML = 'Dimension: ' + oImage.naturalWidth + ' x ' + oImage.naturalHeight;
};
};
// read selected file as DataURL
oReader.readAsDataURL(oFile);
}
function startUploading() {
// cleanup all temp states
iPreviousBytesLoaded = 0;
$("#upload").animate({height:'75px'},350);
$("#loadingborders").fadeIn(1500);
$("#progress_percent").fadeIn(1500);
$("#upload_button").fadeOut(100);
$("#ufile").fadeOut(100);
document.getElementById('ufile').style.margin = '5px 0px -5px 0px';
document.getElementById('upload_response').style.display = 'none';
document.getElementById('error').style.display = 'none';
document.getElementById('error2').style.display = 'none';
document.getElementById('abort').style.display = 'none';
document.getElementById('warnsize').style.display = 'none';
document.getElementById('progress_percent').innerHTML = '';
var oProgress = document.getElementById('progress');
oProgress.style.display = 'block';
oProgress.style.width = '0px';
// get form data for POSTing
//var vFD = document.getElementById('upload_form').getFormData(); // for FF3
var vFD = new FormData(document.getElementById('upload_form'));
// create XMLHttpRequest object, adding few event listeners, and POSTing our data
var oXHR = new XMLHttpRequest();
oXHR.upload.addEventListener('progress', uploadProgress, false);
oXHR.addEventListener('load', uploadFinish, false);
oXHR.addEventListener('error', uploadError, false);
oXHR.addEventListener('abort', uploadAbort, false);
oXHR.open('POST', 'upload.php');
oXHR.send(vFD);
// set inner timer
oTimer = setInterval(doInnerUpdates, 300);
}
function doInnerUpdates() { // we will use this function to display upload speed
var iCB = iBytesUploaded;
var iDiff = iCB - iPreviousBytesLoaded;
// if nothing new loaded - exit
if (iDiff == 0)
return;
iPreviousBytesLoaded = iCB;
iDiff = iDiff * 2;
var iBytesRem = iBytesTotal - iPreviousBytesLoaded;
var secondsRemaining = iBytesRem / iDiff;
// update speed info
var iSpeed = iDiff.toString() + 'B/s';
if (iDiff > 1024 * 1024) {
iSpeed = (Math.round(iDiff * 100/(1024*1024))/100).toString() + 'MB/s';
} else if (iDiff > 1024) {
iSpeed = (Math.round(iDiff * 100/1024)/100).toString() + 'KB/s';
}
document.getElementById('speed').innerHTML = iSpeed;
document.getElementById('remaining').innerHTML = '| ' + secondsToTime(secondsRemaining);
}
function uploadProgress(e) { // upload process in progress
if (e.lengthComputable) {
iBytesUploaded = e.loaded;
iBytesTotal = e.total;
var iPercentComplete = Math.round(e.loaded * 100 / e.total);
var iBytesTransfered = bytesToSize(iBytesUploaded);
document.getElementById('progress_percent').innerHTML = iPercentComplete.toString() + '%';
document.getElementById('progress').style.width = (iPercentComplete * 4).toString() + 'px';
document.getElementById('b_transfered').innerHTML = iBytesTransfered;
if (iPercentComplete == 100) {
var oUploadResponse = document.getElementById('upload_response');
oUploadResponse.innerHTML = '<h1>Please wait...processing</h1>';
}
} else {
document.getElementById('progress').innerHTML = 'unable to compute';
}
}
function uploadFinish(e) { // upload successfully finished
var oUploadResponse = document.getElementById('upload_response');
oUploadResponse.innerHTML = e.target.responseText;
document.getElementById('progress_percent').innerHTML = '100%';
document.getElementById('progress').style.width = '400px';
document.getElementById('filesize').innerHTML = sResultFileSize;
document.getElementById('remaining').innerHTML = '| 00:00:00';
clearInterval(oTimer);
}
function uploadError(e) { // upload error
$('#errormessage').slideUp('fast', function() {
$('#errormessage').html(uploadingcanceld);
$('#errormessage').slideDown('fast');
});
clearInterval(oTimer);
}
function uploadAbort(e) { // upload abort
clearInterval(oTimer);
}
XHR is a dynamic data call, it's not a document forwarding call, meaning the reason why we have XHR to begin with is so that we DON'T want to forward a client to another page to get new content into the page. So you might want to wait on the XHR to complete the process of sending the data, acquire the results of that transfer via XHR, and based on those results do as you want.
So in essence, you are creating a virtual document client/server transfer and handshake without having to forward the client, that of which is the role XHR was created to fulfill.