- Preview video before it is uploaded
- Upload video file in small chunks
- Display a progress bar
For choosing a video file we will use the standard input element
<input type="file" id="uploadVideoFile" accept="video/*" />So to access the chosen file we will call
var fileInput = document.getElementById("uploadVideoFile");To display video we need a video element
div id="videoSourceWrapper"> <video style="width: 100%;" controls> <source id="videoSource"/> </video> </div>The following snippet displays the video after it is chosen in the video element for preview
$('#uploadVideoFile').on('change', function() { var fileInput = document.getElementById("uploadVideoFile"); console.log('Trying to upload the video file: %O', fileInput); if ('files' in fileInput) { if (fileInput.files.length === 0) { alert("Select a file to upload"); } else { var $source = $('#videoSource'); $source[0].src = URL.createObjectURL(this.files[0]); $source.parent()[0].load(); $("#videoSourceWrapper").show(); } } else { console.log('No found "files" property'); } } );
As you can see, you can watch any video file having all necessary controls in the video player. Now let's have a look how to upload the video on your server.
For this purpose I have implemented the UploadVideo function
function UploadVideo(file) { var loaded = 0; var chunkSize = 500000; var total = file.size; var reader = new FileReader(); var slice = file.slice(0, chunkSize); // Reading a chunk to invoke the 'onload' event reader.readAsBinaryString(slice); console.log('Started uploading file "' + file.name + '"'); reader.onload = function (e) { //Send the sliced chunk to the REST API $.ajax({ url: "http://api/url/etc", type: "POST", data: slice, processData: false, contentType: false, error: (function (errorData) { console.log(errorData); alert("Video Upload Failed"); }) }).done(function (e){ loaded += chunkSize; var percentLoaded = Math.min((loaded / total) * 100, 100); console.log('Uploaded ' + Math.floor(percentLoaded) + '% of file "' + file.name + '"'); //Read the next chunk and call 'onload' event again if (loaded <= total) { slice = file.slice(loaded, loaded + chunkSize); reader.readAsBinaryString(slice); } else { loaded = total; console.log('File "' + file.name + '" uploaded successfully!'); } } } }It does literally the following:
- Take the first chunk from the file
- Call the API using AJAX
- When the call is done take the next chunk
- Iterate to step 2
function UploadVideo(file) { var loaded = 0; var chunkSize = 500000; var total = file.size; var reader = new FileReader(); var slice = file.slice(0, chunkSize); // Reading a chunk to invoke the 'onload' event reader.readAsBinaryString(slice); console.log('Started uploading file "' + file.name + '"'); reader.onload = function (e) { //Just simulate API setTimeout(function(){ loaded += chunkSize; var percentLoaded = Math.min((loaded / total) * 100, 100); console.log('Uploaded ' + Math.floor(percentLoaded) + '% of file "' + file.name + '"'); //Read the next chunk and call 'onload' event again if (loaded <= total) { slice = file.slice(loaded, loaded + chunkSize); reader.readAsBinaryString(slice); } else { loaded = total; console.log('File "' + file.name + '" uploaded successfully!'); } }, 250); } }it 'sends' chunks every 250 milliseconds.
Finally, the simpest part is a progress bar. we just add another div beneath the video element
<div id="uploadVideoProgressBar" style="height: 5px; width: 1%; background: #2781e9; margin-top: -5px;"></div>and update its width while sending chunks
$('#uploadVideoProgressBar').width(percentLoaded + "%");
You can try the complete example on JSFiddler:
https://jsfiddle.net/AndrewBuntsev/47dx86sr/
Hi,
ReplyDeleteWould you have an example of php code that could handle the backend of this?
Thanks!
Hi,
DeleteUnfortunately, I cannot help you with it, I implemented backend for the function with JavaScript.