FileBufferReader.js / Demo / Watch a YouTube video
All released versions: https://github.com/muaz-khan/FileBufferReader/releases
Using FileBufferReader.js, you can:
- Get list of array-buffers with each specific chunkSize
- Chunks can be step-by-step shared with remote peers, or instantly shared using for-loop
You can easily implement retransmission of chunks as well. You need to set binaryType
to arraybuffer
:
WebRTC_Data_ChannelbinaryType = 'arraybuffer';
A few points:
- FileBufferReader itself doesn't do anything except reading the file(s)
- You need to manually share chunks using your preferred medium or gateway
- FileBufferReader currently uses memory to store chunks; which has storage limits. So, you may not be able to use FileBufferReader to read/share file with 1GB size or more.
- FileBufferReader is added to support controlled-buffers transmissions whilst following Skype's file sharing style.
It is MIT Licenced, which means that you can use it in any commercial/non-commercial product, free of cost.
npm install fbr --production # or using bower bower install fbr
To use it:
<!-- or CDN --> <!-- or rawgit -->
Or run localhost server:
node server.js
Then open: http://localhost:9001/
or http://127.0.0.1:9001/
.
fbr-client
You can even try socket.io file sharing client:
npm install fbr-client
Then run the server:
cd ./node_modules/fbr-clientnode server.js port=9001
Then open: http://localhost:9001/
or http://127.0.0.1:9001/
.
You can modify development files from the
dev
directory; and usegrunt
tool to recompile intoFileBufferReader.js
.
FileBufferReader API
chunks
object. It contains multiple files' chunks. Even if you received chunks from remote peer, and invokedaddChunk
method; all chunks will be stored in samechunks
object.var fileChunks = fileBufferReader.chunks['file-uuid']
.readAsArrayBuffer
method. It reads entire file and stores chunkified buffers inchunks
object.getNextChunk
method. It simply readslast-position
and returns next available array-buffer chunk.onBegin
,onEnd
andonProgress
events. These are added only to support file progress bars.addChunk
method. It allows you store all received chunks in an array until entire file is received.convertToObject
method. FileBufferReader assumes that you're sending ArrayBuffer using WebRTC data channels. It means that you'll be getting ArrayBuffer type in theonmessage
event.convertToObject
method allows you convert ArrayBuffer into JavaScript object type, which is helpful to check type of message.convertToArrayBuffer
method. You can pass javascript object or any data-type, and this method will returnArrayBuffer
.
1. Link The Library
https://cdn.webrtc-experiment.com/FileBufferReader.js
# or
https://cdn.rawgit.com/muaz-khan/FileBufferReader/master/FileBufferReader.js
2. Select File (optional step)
You can use input[type=file].onchange
instead, which is strongly recommended over using FileSelecter
because FileSelector
object is incapable to handle failures or situations where browser doesn't fires onchange
event.
var fileSelector = ; // *.png, *.jpeg, *.mp4, etc.fileSelectoraccept = '*.*'; var btnSelectFile = document;btnSelectFile { fileSelector;};
3. Read Buffers
var fileBufferReader = ; fileBufferReader;
readAsArrayBuffer
takes 3rd argument as well; where you can pass chunkSize
, and your custom data.
var extra = chunkSize: 15 * 1000 // Firefox' receiving limit is 16k userid: 'sender-userid' // MOST USEFUL object; fileBufferReader;
4. When remote peer receives a chunk
datachannel { var chunk = eventdata; if chunk instanceof ArrayBuffer || chunk instanceof DataView // array buffers are passed using WebRTC data channels // need to convert data back into JavaScript objects fileBufferReader; return; // if you passed "extra-data", you can access it here: // chunk.extra.senderUserName or whatever else // if target peer requested next chunk ifchunkreadyForNextChunk fileBufferReader; return; // if chunk is received fileBufferReader;};
5. File progress helpers
Link this script:
https://cdn.webrtc-experiment.com/FileProgressBarHandler.js
# or
https://cdn.rawgit.com/muaz-khan/FileBufferReader/master/fbr.0/dev/FileProgressBarHandler.js
Add a files-div:
Add following code:
// this line is optional// however it allows you set the <DIV> for progress-bars and files-previewfileBufferReaderfilesContainer = document; // this line sets "onFileStart", "onFileProgress" and "onFileEnd" events (see below lines)FileProgressBarHandler; fileBufferReaderonBegin = fileBufferReaderonFileStart;fileBufferReaderonProgress = fileBufferReaderonFileProgress;fileBufferReaderonEnd = fileBufferReaderonFileEnd;
Above snippet can be written as following:
var options = {}; // this line is optional// however it allows you set the <DIV> for progress-bars and files-previewoptionsfilesContainer = document; // this line sets "onFileStart", "onFileProgress" and "onFileEnd" events (see below lines)FileProgressBarHandler; fileBufferReaderonBegin = optionsonFileStart;fileBufferReaderonProgress = optionsonFileProgress;fileBufferReaderonEnd = optionsonFileEnd;
If you're NOT interested in above FileProgressBarHandler.js
:
var progressHelper = {};var outputPanel = documentbody; var FileHelper = { // if you passed "extra-data", you can access it here: // file.extra.senderUserName or whatever else var li = document; lititle = filename; liinnerHTML = '<label>0%</label> <progress></progress>'; outputPanel; progressHelperfileuuid = li: li progress: li label: li ; progressHelperfileuuidprogressmax = filemaxChunks; } { // if you passed "extra-data", you can access it here: // file.extra.senderUserName or whatever else progressHelperfileuuidliinnerHTML = '<a href="' + fileurl + '" target="_blank" download="' + filename + '">' + filename + '</a>'; } { // if you passed "extra-data", you can access it here: // chunk.extra.senderUserName or whatever else var helper = progressHelperchunkuuid; helperprogressvalue = chunkcurrentPosition || chunkmaxChunks || helperprogressmax; ; }; { if progressposition == -1 return; var position = +progressposition1 || 100; labelinnerHTML = position + '%';} fileBufferReaderonBegin = FileHelperonBegin;fileBufferReaderonProgress = FileHelperonProgress;fileBufferReaderonEnd = FileHelperonEnd;
Sharing with multiple users?
fbr; datachannel { fbr;};
Pass specific-userid as 3rd argument over
getNextChunk
method.
To uniquely identify progress-bars for each user, watch for remoteUserId
object:
FileHelper { iffileremoteUserId // file is being shared with multiple users }; FileHelper { iffileremoteUserId // file is being shared with multiple users }; FileHelper { ifchunkremoteUserId // file is being shared with multiple users };
Advance Usages
var fbr = ;fbr;
The structure of fileBufferReader.chunks
object looks like this:
fileBufferReaderchunks = // "4152661527041346" is file-uuid "4152661527041346": // "0" index helps firing "onStart" event. "0": "currentPosition":0 "uuid":"4152661527041346" "maxChunks":20 "size":298540 "name":"WebRTC.png" "type":"image/png" "lastModifiedDate":"Wed Oct 14 2015 15:51:26 GMT+0500 (PKT)" "start":true "userid":0 "extra": "userid":0 // index "1" to "maxChunks" are the real file-chunks "1": "uuid":"4152661527041346" // this is the real ArrayBuffer object "buffer":{} "currentPosition":1 "maxChunks":20 "size":298540 "name":"WebRTC.png" "lastModifiedDate":"Wed Oct 14 2015 15:51:26 GMT+0500 (PKT)" "type":"image/png" "userid":0 "extra": "userid":0 ... ... // this is the last file-chunk // here "currentPosition===maxChunks" "20": "uuid":"4152661527041346" "buffer":{} "currentPosition":20 "maxChunks":20 "size":298540 "name":"WebRTC.png" "lastModifiedDate":"Wed Oct 14 2015 15:51:26 GMT+0500 (PKT)" "type":"image/png" "userid":0 "extra": "userid":0 // this one helps firing "onEnd" event "21": "currentPosition":21 "uuid":"4152661527041346" "maxChunks":20 "size":298540 "name":"WebRTC.png" "lastModifiedDate":"Wed Oct 14 2015 15:51:26 GMT+0500 (PKT)" "url":"blob:http%3A//domain/fe5a20d0-cdb4-4f4e-9de7-1a14340fc402" "type":"image/png" "end":true "userid":0 "extra": "userid":0 // this is optionally used to detect which chunk is being shared // you should skip it. "currentPosition":0
You can see that real file-chunks starts from 1
and ends before length-1
.
E.g.
var fileChunks = fbrchunks'file-uuid';var allFileIndices = Object; var allFileBuffers = ;forvar chunkIndex = 1; chunkIndex < allFileIndiceslength; i++ var chunk = fileChunkschunkIndex; allFileBuffers;
FileSelector
Provides methods to select single file, multiple files or entire directory.
Select single file:
var selector = ;selectoraccept = '*.png';selector;
Select multiple files:
var selector = ;selectoraccept = '*.png';selector;
Select entire directory:
var selector = ;selectoraccept = '*.png';selector;
FileConverter
This global object exposes two methods:
ConvertToArrayBuffer
ConvertToObject
Here is how to use these methods:
var yourObject = x: 0 y: 1 str: 'string' bool: true; FileConverter;
When you call getNextChunk
, the FileBufferReader
instance checks for currentPosition
and returns buffer using following snippet:
// this method explains insights of FileBufferReaderfbr { var fileChunks = fbrchunksfileUUID; var currentPosition = fileChunkscurrentPosition; var nextChunk = fileChunkscurrentPosition; FileConverter;}; // and your code calls above method as following;fbr;
Applications using FileBufferReader
RTCMultiConnection FileBufferReader Demos
- https://rtcmulticonnection.herokuapp.com/demos/Audio+Video+TextChat+FileSharing.html
- https://rtcmulticonnection.herokuapp.com/demos/TextChat+FileSharing.html
More demos here: https://rtcmulticonnection.herokuapp.com/demos/
License
FileBufferReader.js is released under MIT licence . Copyright (c) Muaz Khan.