WebRTC audio/video call and conferencing server.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

153 lines
4.5 KiB

/*
* Spreed WebRTC.
* Copyright (C) 2013-2015 struktur AG
*
* This file is part of Spreed WebRTC.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
"use strict";
define(["mediastream/webrtc", "webrtc.adapter"], function() {
// Simple array buffer join function, to create a third array buffer
// NOTE(longsleep): This acutally copies the data in memory.
var arrayBufferJoin = function(one, two) {
var three = new Uint8Array(one.byteLength + two.byteLength);
three.set(new Uint8Array(one), 0);
three.set(new Uint8Array(two), one.byteLength);
return three.buffer;
}
// Simple fast crc32 implementation for ArrayBuffers.
var makeCRCTable = function() {
var c;
var crcTable = [];
for (var n = 0; n < 256; n++) {
c = n;
for (var k = 0; k < 8; k++) {
c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1));
}
crcTable[n] = c;
}
return crcTable;
};
var crcTable = makeCRCTable();
var crc32 = function(view) {
// Pass a Uint8Array.
var crc = 0 ^ (-1);
for (var i = 0; i < view.length; i++) {
crc = (crc >>> 8) ^ crcTable[(crc ^ view[i]) & 0xFF];
}
return (crc ^ (-1)) >>> 0;
};
var FileChunkV0 = function(buffer, id, data) {
// 1 byte version (0 as of now)
// 3 byte reserved for further use
// 4 byte chunk id
// 4 byte crc32
// rest is payload data
this.version = 0;
if (buffer) {
this._open(buffer);
} else if (typeof id !== "undefined" && data) {
this._set(id, data);
}
};
FileChunkV0.prototype._open = function(buffer, create) {
this._v = new Uint8Array(buffer, 0, 1);
// 3 bytes reserved here
this._c = new Uint32Array(buffer, 4, 1);
this._crc32 = new Uint32Array(buffer, 8, 1);
this._buffer = buffer;
this._data = new Uint8Array(this._buffer, 12, this._buffer.byteLength - 12);
if (!create) {
// Validate.
if (this._v[0] !== this.version) {
throw new TypeError("Data version mismatch.");
}
var c = crc32(this._data);
//console.log("block", this._c[0], c, this._crc32[0]);
if (this._crc32[0] !== c) {
console.warn("Data crc32 error.", this._c[0], c, this._crc32[0]);
throw new TypeError("Data crc32 error.", this._c[0], c, this._crc32[0]);
}
}
};
FileChunkV0.prototype._set = function(id, data) {
var control = new ArrayBuffer(12);
this._open(arrayBufferJoin(control, data), true);
this._v[0] = this.version;
this._c[0] = id;
this._crc32[0] = crc32(new Uint8Array(data));
//console.log("block", id, this._crc32[0], [this._buffer]);
};
FileChunkV0.prototype.data = function() {
//console.log("data", [this._buffer, this._buffer.byteLength-12]);
return this._data;
};
FileChunkV0.prototype.index = function() {
return this._c[0];
};
FileChunkV0.prototype.raw = function() {
return this._buffer;
};
FileChunkV0.prototype.size = function() {
return this._data.length;
};
return ["$window", function($window) {
// SCTP does not work properly in Chrome 31 when used with other Chrome versions.
// Thus we require Chrome 32 for now. Firefox 28 can interop with Chrome 32 data channels - yay.
var supported = ($window.webrtcDetectedBrowser === "chrome" && $window.webrtcDetectedVersion >= 32 && !$window.webrtcDetectedAndroid) || ($window.webrtcDetectedBrowser === "firefox" && $window.webrtcDetectedVersion >= 28 && !$window.webrtcDetectedAndroid);
if (!supported) {
console.warn("Browser support for binary file transfers not found.");
}
return {
supported: supported,
arrayBufferJoin: arrayBufferJoin,
crc32: crc32,
parseChunk: function(data, cb) {
var version = new Uint8Array(data, 0, 1)[0];
switch (version) {
case 0:
var filechunk = new FileChunkV0(data);
if (cb) {
cb(filechunk.index(), filechunk.data(), filechunk.size());
}
return filechunk;
default:
console.warn("Unknow data version.");
break;
}
},
makeChunk: function(idx, data) {
return new FileChunkV0(null, idx, data);
}
}
}];
});