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.
 
 
 
 
 
 

252 lines
7.4 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(['jquery', 'underscore', 'moment'], function($, _, moment) {
return ["fileData", "fileUpload", "fileDownload", "mediaStream", "$window", "alertify", "translation", function(fileData, fileUpload, fileDownload, mediaStream, $window, alertify, translation) {
var controller = ['$scope', '$element', '$attrs', function($scope, $element, $attrs) {
var ctrl = this;
console.log("file-info", $scope, $element);
$scope.complete = false;
$scope.downloader = false;
$scope.downloadcomplete = false;
$scope.downloading = false;
$scope.downloadspeed = false;
$scope.uploading = false;
$scope.uploader = false;
$scope.cancelled = false;
$scope.error = false;
$scope.progress = 0;
$scope.progressDownload = 0;
$scope.bytesPerSecond = 0;
$scope.eta = "";
$scope.url = null;
var progressBars = $element.find(".file-info-size > div");
var progressBar = progressBars[0];
var progressBarDownload = progressBars[1];
$scope.$watch("progress", function() {
progressBar.style.width = ($scope.progress) + "%";
});
$scope.$watch("progressDownload", function() {
progressBarDownload.style.width = ($scope.progressDownload) + "%";
});
$scope.$watch("error", function() {
// TODO(longsleep): Show some feedback?
});
var chunk = 0;
var handler = null;
var token = $scope.info.id;
var bytesIn = [];
var bytesPerSecond = [];
var bytesPerSecondInterval = null;
ctrl.bytesPerSecond = function() {
if ($scope.downloadcomplete || $scope.cancelled || $scope.error) {
$window.clearInterval(bytesPerSecondInterval);
$scope.$apply(function(scope) {
$scope.downloadspeed = false;
$scope.eta = "";
});
return;
}
var bpsIn = 0;
if (bytesIn.length) {
bpsIn = _.reduce(bytesIn, function(memo, num) {
return memo + num;
}, 0);
bytesIn = [];
}
bytesPerSecond.push(bpsIn);
if (bytesPerSecond.length > 3) {
bytesPerSecond.shift();
}
// Compute left bytes for eta.
var bytesLeft = $scope.info.size - ($scope.info.size * ($scope.progress / 100));
$scope.$apply(function(scope) {
scope.bytesPerSecond = _.reduce(bytesPerSecond, function(memo, num) {
return memo + num;
}, 0) / bytesPerSecond.length;
if (scope.downloader && (scope.bytesPerSecond || scope.eta)) {
if (scope.bytesPerSecond > 0) {
var etaSeconds = bytesLeft / scope.bytesPerSecond;
scope.eta = moment.duration(etaSeconds, "seconds").humanize();
} else {
scope.eta = "";
}
}
if (!scope.downloadspeed && scope.bytesPerSecond > 0) {
scope.downloadspeed = true;
} else if (!scope.downloader && scope.bytesPerSecond === 0) {
scope.downloadspeed = false;
}
});
};
$scope.reset = function() {
chunk = 0;
bytesIn = [];
bytesPerSecond = [];
$window.clearInterval(bytesPerSecondInterval);
bytesPerSecondInterval = null;
$scope.complete = false;
$scope.downloading = false;
$scope.downloadcomplete = false;
$scope.downloadspeed = false;
$scope.progress = 0;
$scope.progressDownload = 0;
$scope.bytesPerSecond = 0;
$scope.eta = "";
$scope.error = false;
$scope.url = null;
};
$scope.download = function() {
if (!fileDownload.supported) {
alertify.dialog.alert(translation._("Your browser does not support file transfer."));
return;
}
if ($scope.error && $scope.downloading) {
// Crude retry support.
$scope.reset();
}
console.log("Download", $scope.info, $scope);
if (!$scope.complete && !$scope.downloading) {
$scope.downloading = true;
$scope.cancelled = false;
bytesPerSecondInterval = $window.setInterval(ctrl.bytesPerSecond, 1000);
$scope.$emit("download", $scope.from, $scope.info.id);
} else {
if ($scope.url) {
$window.open($scope.url, "_blank");
} else {
console.error("Download of already completed files not implemented yet.");
}
}
};
$scope.cancel = function() {
console.log("Download cancel", $scope.downloading, $scope);
$scope.cancelled = true;
if ($scope.downloading) {
$scope.$emit("cancelDownload");
}
if ($scope.uploader) {
console.log("Removing upload handler");
if (handler) {
mediaStream.tokens.off(token, handler);
$scope.uploader = false;
}
$scope.$emit("cancelUpload");
}
$scope.reset();
};
$scope.$on("downloadedWritten", function(event, written, queue) {
event.stopPropagation();
if ($scope.cancelled) {
return;
}
$scope.progress = Math.ceil((written / ($scope.info.chunks - 1)) * 100);
if (written >= $scope.info.chunks - 1) {
$scope.progress = 100;
}
});
$scope.$on("downloadedChunk", function(event, idx, bytesLength) {
event.stopPropagation();
if ($scope.cancelled) {
return;
}
bytesIn.push(bytesLength);
$scope.progressDownload = Math.ceil((chunk / ($scope.info.chunks - 1)) * 100);
chunk++;
});
$scope.$on("writeComplete", function(event, url) {
event.stopPropagation();
$scope.complete = true;
$scope.url = url;
$scope.progress = 100;
});
$scope.$on("downloadComplete", function(event) {
event.stopPropagation();
$scope.downloadcomplete = true;
$scope.progressDownload = 100;
});
$scope.$on("uploadedChunk", function(event, idx, bytesLength) {
event.stopPropagation();
//console.log("Uploaded chunk", idx, bytesLength);
if ($scope.cancelled) {
return;
}
bytesIn.push(bytesLength);
});
// Register as token handler when we are sending.
var file = fileData.getFile($scope.info.id);
if (file) {
$scope.uploader = true;
console.log("File-info has file on create", file);
var session = fileUpload.startUpload($scope, $scope.info.id);
// This binds the token to transfer and ui.
handler = mediaStream.tokens.on(token, function(event, currenttoken, to, data, type, to2, from, xfer) {
//console.log("File token request", currenttoken, data, type);
session.handleRequest($scope, xfer, data);
}, "xfer");
bytesPerSecondInterval = $window.setInterval(ctrl.bytesPerSecond, 1000);
} else {
$scope.downloader = true;
// This binds the token to transfer and ui.
handler = mediaStream.tokens.on(token, function(event, currenttoken, to, data, type, to2, from, xfer) {
//console.log("File token request", currenttoken, data, type);
fileDownload.handleRequest($scope, xfer, data);
}, "xfer");
}
}];
return {
scope: true,
restrict: 'EAC',
controller: controller,
replace: false
}
}];
});