283 lines
11 KiB
XML
Executable File
283 lines
11 KiB
XML
Executable File
<?xml version="1.0" encoding="utf-8"?>
|
|
|
|
<!--
|
|
|
|
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
|
|
|
Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
|
|
|
This program is free software; you can redistribute it and/or modify it under the
|
|
terms of the GNU Lesser General Public License as published by the Free Software
|
|
Foundation; either version 3.0 of the License, or (at your option) any later
|
|
version.
|
|
|
|
BigBlueButton 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 Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License along
|
|
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
|
|
|
-->
|
|
|
|
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
|
|
creationComplete="onCreationComplete()"
|
|
pageTitle="WebcamPreview" layout="absolute">
|
|
<mx:Script>
|
|
<![CDATA[
|
|
import mx.core.UIComponent;
|
|
import mx.utils.URLUtil;
|
|
|
|
[Bindable] private var defaultWidth:Number = 320;
|
|
[Bindable] private var defaultHeight:Number = 240;
|
|
|
|
private var _video:Video;
|
|
private var _videoHolder:UIComponent;
|
|
private var camIndex:int = 0;
|
|
private var camWidth:Number = 320;
|
|
private var camHeight:Number = 240;
|
|
private var _camera:Camera = null;
|
|
private var quality:Number = 0;
|
|
private var PADDING_HORIZONTAL:Number = 6;
|
|
private var PADDING_VERTICAL:Number = 29;
|
|
private var _minWidth:int = 160 + PADDING_HORIZONTAL;
|
|
private var _minHeight:int = 120 + PADDING_VERTICAL;
|
|
private var aspectRatio:Number = 1;
|
|
|
|
private function onCreationComplete():void{
|
|
_videoHolder = new UIComponent();
|
|
_videoHolder.width = this.width;
|
|
_videoHolder.height = this.height;
|
|
this.addChild(_videoHolder);
|
|
|
|
_videoHolder.addChild(loader);
|
|
|
|
this.minWidth = _minWidth;
|
|
this.minHeight = _minHeight;
|
|
|
|
trace('WebcamPreviewSA::onCreationComplete');
|
|
Security.allowDomain(determineHTMLURL());
|
|
trace("WebcamPreviewSA:: Security.allowDomain(" + determineHTMLURL() + ");");
|
|
|
|
initExternalInterface();
|
|
callWebcamPreviewStandaloneReady();
|
|
}
|
|
|
|
private function determineHTMLURL():String {
|
|
var serverName:String = "*";
|
|
if(ExternalInterface.available) {
|
|
try {
|
|
var htmlURL:String = String(ExternalInterface.call("window.location.href.toString"));
|
|
serverName = URLUtil.getServerName(htmlURL);
|
|
trace("WebcamPreviewSA::determineHTMLURL HTML URL [" + htmlURL + "]");
|
|
} catch(s:Error) {
|
|
trace("WebcamPreviewSA::determineHTMLURL Cannot determine HTML URL");
|
|
}
|
|
}
|
|
|
|
return serverName;
|
|
}
|
|
|
|
private function initExternalInterface():void {
|
|
trace('WebcamPreviewSA::initExternalInterface');
|
|
if (ExternalInterface.available) {
|
|
ExternalInterface.addCallback("startPreviewCamera", handleStartPreviewCameraRequest);
|
|
ExternalInterface.addCallback("stopPreviewCamera", handleStopPreviewCamera);
|
|
}
|
|
}
|
|
|
|
private function callWebcamPreviewStandaloneReady():void {
|
|
if (ExternalInterface.available) {
|
|
ExternalInterface.call("webcamPreviewStandaloneAppReady");
|
|
}
|
|
}
|
|
|
|
private var _avatarURL:String;
|
|
private var displayAvatar:Boolean = false;
|
|
|
|
private function handleStartPreviewCameraRequest(camIndex:String, camWidth:int, camHeight:int,
|
|
camKeyFrameInterval:int, camModeFps:Number,
|
|
camQualityBandwidth:int, camQualityPicture:int, avatarURL:String):void {
|
|
displayAvatar = false;
|
|
_avatarURL = avatarURL;
|
|
|
|
trace("WebcamPreviewSA::handleStartPreviewCameraRequest avatar=[" + _avatarURL + "]");
|
|
|
|
displayCamera(camIndex, camWidth, camHeight, camKeyFrameInterval, camModeFps, camQualityBandwidth, camQualityPicture);
|
|
}
|
|
|
|
private function handleStopPreviewCamera(avatarURL:String):void {
|
|
displayAvatar = true;
|
|
_avatarURL = avatarURL;
|
|
|
|
trace("WebcamPreviewSA::handleStopPreviewCamera avatar=[" + _avatarURL + "]");
|
|
|
|
stopCamera();
|
|
|
|
loadAvatar();
|
|
}
|
|
|
|
private var loader:Loader = new Loader();
|
|
private var request:URLRequest;
|
|
|
|
private function loadAvatar():void {
|
|
request = new URLRequest(_avatarURL);
|
|
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadingComplete);
|
|
loader.load(request);
|
|
}
|
|
|
|
private var avatarWidth:Number = 320;
|
|
private var avatarHeight:Number = 240;
|
|
|
|
private function onLoadingComplete(event:Event):void {
|
|
|
|
if (!displayAvatar) {
|
|
// The user might have started sharing webcam again.
|
|
return;
|
|
}
|
|
|
|
if (_video != null) _videoHolder.removeChild(_video);
|
|
_videoHolder.addChild(loader);
|
|
|
|
// Save the size of the avatar image.
|
|
avatarWidth = loader.content.width;
|
|
avatarHeight = loader.content.height;
|
|
|
|
onResizeAvatar();
|
|
}
|
|
|
|
private function onResizeAvatar():void {
|
|
|
|
if (loader != null && _videoHolder != null) {
|
|
if (avatarIsSmallerThanWindow()) {
|
|
// The avatar image is smaller than the window. Just center the image.
|
|
_videoHolder.width = loader.width = avatarWidth;
|
|
_videoHolder.height = loader.height = avatarHeight;
|
|
|
|
} else {
|
|
// The avatar is bigger than the window. Fit into the window maintaining aspect ratio.
|
|
fitAvatarToWindow();
|
|
}
|
|
|
|
_videoHolder.x = (this.width - loader.width) / 2;
|
|
_videoHolder.y = (this.height - loader.height) / 2;
|
|
|
|
}
|
|
}
|
|
|
|
private function fitAvatarToWindow():void {
|
|
if (_videoHolder.width < _videoHolder.height) {
|
|
fitAvatarToHeightAndAdjustWidthToMaintainAspectRatio();
|
|
} else {
|
|
fitAvatarToWidthAndAdjustHeightToMaintainAspectRatio();
|
|
}
|
|
}
|
|
|
|
private function avatarIsSmallerThanWindow():Boolean {
|
|
return (avatarWidth < _videoHolder.width) && (avatarHeight < _videoHolder.height);
|
|
}
|
|
|
|
private function fitAvatarToWidthAndAdjustHeightToMaintainAspectRatio():void {
|
|
var aspect:Number = avatarHeight / avatarWidth;
|
|
loader.width = _videoHolder.width = this.width;
|
|
|
|
// Maintain aspect-ratio
|
|
_videoHolder.height= loader.height = loader.width * aspect;
|
|
|
|
}
|
|
|
|
private function fitAvatarToHeightAndAdjustWidthToMaintainAspectRatio():void {
|
|
var aspect:Number = avatarWidth / avatarHeight;
|
|
loader.height = _videoHolder.height = this.height;
|
|
|
|
// Maintain aspect-ratio
|
|
_videoHolder.width = loader.width = loader.height * aspect;
|
|
|
|
}
|
|
|
|
private function resetVideoHolder():void {
|
|
loader.width = _videoHolder.width = this.width;
|
|
loader.height = _videoHolder.height = this.height;
|
|
_videoHolder.x = _videoHolder.y = 0;
|
|
}
|
|
|
|
public function displayCamera(camIndex:String, camWidth:int, camHeight:int, camKeyFrameInterval:int,
|
|
camModeFps:Number, camQualityBandwidth:int,
|
|
camQualityPicture:int):void {
|
|
trace('WebcamPreviewSA::displayCamera');
|
|
// Rest the videoHolder's dimensions
|
|
resetVideoHolder();
|
|
|
|
stopCamera();
|
|
|
|
if (Camera.names.length == 0) {
|
|
trace('WebcamPreviewSA::bbb.video.publish.hint.noCamera');
|
|
return;
|
|
}
|
|
|
|
_camera = Camera.getCamera(camIndex);
|
|
if (_camera == null) {
|
|
trace('WebcamPreviewSA::bbb.video.publish.hint.cantOpenCamera');
|
|
return;
|
|
}
|
|
|
|
setResolution(camWidth, camHeight);
|
|
|
|
_camera.setMotionLevel(5, 1000);
|
|
|
|
_camera.setKeyFrameInterval(camKeyFrameInterval);
|
|
_camera.setMode(camWidth, camHeight, camModeFps);
|
|
_camera.setQuality(camQualityBandwidth, camQualityPicture);
|
|
|
|
if (_camera.width != camWidth || _camera.height != camHeight) {
|
|
trace("WebcamPreviewSA::Resolution " + camWidth + "x" + camHeight + " is not supported, using " + _camera.width + "x" + _camera.height + " instead");
|
|
setResolution(_camera.width, _camera.height);
|
|
}
|
|
|
|
_video = new Video();
|
|
_video.attachCamera(_camera);
|
|
|
|
if (aspectRatio > _videoHolder.width / _videoHolder.height) {
|
|
_video.width = _videoHolder.width;
|
|
_video.height = _videoHolder.width / aspectRatio;
|
|
_video.x = 0;
|
|
_video.y = (_videoHolder.height - _video.height) / 2;
|
|
} else {
|
|
_video.width = _videoHolder.height * aspectRatio;
|
|
_video.height = _videoHolder.height;
|
|
_video.x = (_videoHolder.width - _video.width) / 2;
|
|
_video.y = 0;
|
|
}
|
|
|
|
_videoHolder.removeChild(loader);
|
|
_videoHolder.addChild(_video);
|
|
}
|
|
|
|
private function stopCamera():void {
|
|
resetVideoHolder();
|
|
_camera = null;
|
|
if (_video != null) {
|
|
_videoHolder.removeChild(_video);
|
|
_video.attachCamera(null);
|
|
_video.clear();
|
|
_video = null;
|
|
}
|
|
}
|
|
|
|
private function setResolution(width:int, height:int):void {
|
|
camWidth = width;
|
|
camHeight = height;
|
|
setAspectRatio(camWidth, camHeight);
|
|
}
|
|
|
|
private function setAspectRatio(width:int, height:int):void {
|
|
aspectRatio = (width/height);
|
|
this.minHeight = Math.floor((this.minWidth - PADDING_HORIZONTAL) / aspectRatio) + PADDING_VERTICAL;
|
|
}
|
|
|
|
|
|
]]>
|
|
</mx:Script>
|
|
|
|
</mx:Application>
|