You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by so...@apache.org on 2014/05/18 13:16:19 UTC

svn commit: r1595590 - in /openmeetings/trunk/singlewebapp/openmeetings-flash/src/main/flex: Main.mxml assets/ assets/error.png assets/info.png assets/level_meter.png main.mxml

Author: solomax
Date: Sun May 18 11:16:19 2014
New Revision: 1595590

URL: http://svn.apache.org/r1595590
Log:
[OPENMEETINGS-1003] Video setup window is partially implemented

Added:
    openmeetings/trunk/singlewebapp/openmeetings-flash/src/main/flex/assets/
    openmeetings/trunk/singlewebapp/openmeetings-flash/src/main/flex/assets/error.png   (with props)
    openmeetings/trunk/singlewebapp/openmeetings-flash/src/main/flex/assets/info.png   (with props)
    openmeetings/trunk/singlewebapp/openmeetings-flash/src/main/flex/assets/level_meter.png   (with props)
    openmeetings/trunk/singlewebapp/openmeetings-flash/src/main/flex/main.mxml
Removed:
    openmeetings/trunk/singlewebapp/openmeetings-flash/src/main/flex/Main.mxml

Added: openmeetings/trunk/singlewebapp/openmeetings-flash/src/main/flex/assets/error.png
URL: http://svn.apache.org/viewvc/openmeetings/trunk/singlewebapp/openmeetings-flash/src/main/flex/assets/error.png?rev=1595590&view=auto
==============================================================================
Binary file - no diff available.

Propchange: openmeetings/trunk/singlewebapp/openmeetings-flash/src/main/flex/assets/error.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: openmeetings/trunk/singlewebapp/openmeetings-flash/src/main/flex/assets/info.png
URL: http://svn.apache.org/viewvc/openmeetings/trunk/singlewebapp/openmeetings-flash/src/main/flex/assets/info.png?rev=1595590&view=auto
==============================================================================
Binary file - no diff available.

Propchange: openmeetings/trunk/singlewebapp/openmeetings-flash/src/main/flex/assets/info.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: openmeetings/trunk/singlewebapp/openmeetings-flash/src/main/flex/assets/level_meter.png
URL: http://svn.apache.org/viewvc/openmeetings/trunk/singlewebapp/openmeetings-flash/src/main/flex/assets/level_meter.png?rev=1595590&view=auto
==============================================================================
Binary file - no diff available.

Propchange: openmeetings/trunk/singlewebapp/openmeetings-flash/src/main/flex/assets/level_meter.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: openmeetings/trunk/singlewebapp/openmeetings-flash/src/main/flex/main.mxml
URL: http://svn.apache.org/viewvc/openmeetings/trunk/singlewebapp/openmeetings-flash/src/main/flex/main.mxml?rev=1595590&view=auto
==============================================================================
--- openmeetings/trunk/singlewebapp/openmeetings-flash/src/main/flex/main.mxml (added)
+++ openmeetings/trunk/singlewebapp/openmeetings-flash/src/main/flex/main.mxml Sun May 18 11:16:19 2014
@@ -0,0 +1,365 @@
+<?xml version="1.0"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+
+-->
+<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
+			   xmlns:s="library://ns.adobe.com/flex/spark"
+			   xmlns:mx="library://ns.adobe.com/flex/mx" width="570" height="900" pageTitle="Openmeetings"
+			   preinitialize="init()" fontSize="12" applicationComplete="appInit()">
+	<fx:Declarations>
+		<!-- Place non-visual elements (e.g., services, value objects) here -->
+		<mx:TraceTarget/>
+	</fx:Declarations>
+	<fx:Script><![CDATA[
+		import mx.collections.ArrayCollection;
+		import mx.core.FlexGlobals;
+
+		private static const APP_WIDTH:int = 540;
+		private static const LEFT_WIDTH:int = 280;
+		private static const RIGHT_WIDTH:int = 240;
+		private var debugEnabled:Boolean = true;
+		private var sid:String;
+		private var roomid:int;
+		private var audioOnly:Boolean = false;
+		private var labels:Object = new Object();
+		private var cam:Camera = null;
+		private var mic:Microphone = null;
+		private var FPS:int = 30;
+		[Bindable]
+		private var interview:Boolean = false;
+		[Bindable]
+		private var debugStr:String = "";
+
+		private function setDimensions(width:int, height:int):void {
+			mainSetupGroup.width = width;
+			//mainSetupGroup.height = height;
+		}
+
+		public function debug(str:String):void {
+			if (debugEnabled) {
+				debugStr += str + "\n";
+				trace(str + "\n");
+			}
+		}
+
+		private function store():void {
+			var t:SharedObject = SharedObject.getLocal('userdata');
+			var g:Object = t.data ? t.data : new Object();
+			g["cam"] = cams.selectedItem.data;
+			g["mic"] = mics.selectedItem.data;
+			g["avstored"] = modes.selectedItem.data;
+			g["savecamdata"] = remember.selected;
+			g["width"] = ress.selectedItem.width;
+			g["height"] = ress.selectedItem.height;
+			t.flush();
+		}
+
+		private function getStoredProp(prop:String):String {
+			//Initialize and get eventually stored property
+			var t:SharedObject = SharedObject.getLocal('userdata');
+			var g:Object = t.data;
+			return g != null ? "" + g[prop] : null;
+		}
+
+		private function init():void {
+			debug("init()");
+			var tla:Object = FlexGlobals.topLevelApplication;
+			sid = tla.parameters['sid'];
+			roomid = tla.parameters['roomid'];
+			audioOnly = 'true' == tla.parameters['audioOnly'];
+			interview = 'true' == tla.parameters['interview'];
+			var _fps:int = parseInt(tla.parameters['fps']);
+			FPS = interview ? 24 : (isNaN(_fps) ? 30 : _fps);
+		}
+
+		private function selectListItem(combo:ComboBox, selected:int):void {
+			combo.callLater(function ():void {
+				if (combo.dataProvider && combo.dataProvider.length > 0) {
+					combo.selectedItem = combo.dataProvider.getItemAt(selected > -1 ? selected : 0);
+				}
+			});
+		}
+
+		private function getItemIdx(combo:ComboBox, data:String):int {
+			var idx:int = -1;
+			for (var i:int = 0; i < combo.dataProvider.length; ++i) {
+				if (combo.dataProvider[i].data == data) {
+					idx = i;
+					break;
+				}
+			}
+			return idx;
+		}
+
+		private function fillDeviceList(list:Array, combo:ComboBox, prop:String):int {
+			//Initialize and get eventually stored property
+			var dev:int = parseInt(getStoredProp(prop));
+
+			var items:ArrayCollection = new ArrayCollection();
+			//Get all available devices
+			var foundStoredDev:int = -1;
+			for (var i:int = 0; i < list.length; ++i) {
+				items.addItem({label: list[i], data: i});
+				if (i == dev) {
+					foundStoredDev = i;
+				}
+			}
+			combo.dataProvider = items;
+			return foundStoredDev;
+		}
+
+		private function appInit():void {
+			var cameras:Array = Camera.names;
+			var foundedCam:int = fillDeviceList(cameras, cams, "cam");
+			selectListItem(cams, foundedCam);
+
+			var micros:Array = Microphone.names;
+			var foundedMic:int = fillDeviceList(micros, mics, "mic");
+			selectListItem(mics, foundedMic);
+
+			var addCams:Boolean = !audioOnly && cameras.length > 0;
+			var addMics:Boolean = micros.length > 0;
+			var modItems:ArrayCollection = new ArrayCollection();
+			if (addCams && addMics) {
+				modItems.addItem({label: getLabel(448), data: "av"});
+			}
+			if (addMics) {
+				modItems.addItem({label: getLabel(449), data: "a"});
+			}
+			if (addCams) {
+				modItems.addItem({label: getLabel(450), data: "v"});
+			}
+			modItems.addItem({label: getLabel(451), data: "n"});
+			modes.dataProvider = modItems;
+
+			var idx:int = getItemIdx(modes, getStoredProp("avstored"));
+			debug("selected idx::" + idx);
+			selectListItem(modes, idx);
+			setMode(modes.dataProvider.getItemAt(idx > -1 ? idx : 0).data);
+
+			var tla:Object = FlexGlobals.topLevelApplication;
+			var resolutions:Array = JSON.parse(tla.parameters['resolutions']) as Array;
+			var resItems:ArrayCollection = new ArrayCollection();
+			idx = -1;
+			var storedWidth:int = parseInt(getStoredProp("width"));
+			var storedHeight:int = parseInt(getStoredProp("height"));
+			for (var i:int = 0; i < resolutions.length; ++i) {
+				var r:Object = resolutions[i];
+				resItems.addItem({label: r.width + 'x' + r.height + ' [' + r.label + ']', width: r.width, height: r.height});
+				if (!isNaN(storedWidth) && storedWidth > 0 && !isNaN(storedHeight) && storedHeight > 0) {
+					if (r.width == storedWidth && r.height == storedHeight) {
+						idx = i;
+					}
+				} else if (r.default) {
+					idx = i;
+				}
+			}
+			ress.dataProvider = resItems;
+			selectListItem(ress, idx);
+			var resI:Object = ress.dataProvider.getItemAt(idx > -1 ? idx : 0);
+			setResolution(resI.width, resI.height);
+
+			var lbls:Array = JSON.parse(tla.parameters['labels']) as Array;
+			for (i = 0; i < lbls.length; ++i) {
+				labels[lbls[i].id] = lbls.value;
+			}
+			remember.selected = true == getStoredProp("savecamdata");
+
+		}
+
+		public function getLabel(id:int):String {
+			return labels.hasOwnProperty("" + id) ? labels[id] : (debugEnabled ? "[Missing " + id + "]" : "");
+		}
+
+		private function setMode(mode:String):void {
+			var camVisible:Boolean = true;
+			var micVisible:Boolean = true;
+			var textVisible:Boolean = false;
+			switch (mode) {
+				case "av":
+					break;
+				case "a":
+					camVisible = false;
+					break;
+				case "v":
+					micVisible = false;
+					break;
+				case "n":
+					camVisible = false;
+					micVisible = false;
+					textVisible = true;
+					break;
+				default:
+					debug("no valid device Setup chosen");
+					break;
+			}
+			camGroup.visible = camVisible;
+			micGroup.visible = micVisible;
+			noAv.visible = textVisible;
+			startTest.visible = !textVisible;
+			videoGroup.visible = !textVisible;
+			resGroup.visible = interview ? false : camVisible;
+			attachCamera();
+		}
+
+		private function modeChanged(e:Event):void {
+			setMode(e.target.selectedItem.data);
+		}
+
+		private function cameraStatusHandler(event:StatusEvent):void {
+			debug("cameraStatusHandler! " + event);
+			if (cam.muted) {
+				debug("Unable to connect to active camera.");
+			} else {
+				_attachCamera();
+			}
+			cam.removeEventListener(StatusEvent.STATUS, cameraStatusHandler);
+		}
+
+		private function attachCamera():void {
+			if (!videoDisplay.visible) {
+				return;
+			}
+			debug("Camera selected:: " + cams.selectedItem.data);
+			cam = Camera.getCamera(cams.selectedItem.data);
+			debug("Camera selected:: " + cam);
+			mic = Microphone.getMicrophone(mics.selectedItem.data);
+			if (cam.muted) {
+				debug("Camera Muted");
+				videoDisplay.attachCamera(cam);
+				cam.addEventListener(StatusEvent.STATUS, cameraStatusHandler);
+			} else {
+				_attachCamera();
+			}
+		}
+
+		private function _attachCamera():void {
+			cam = Camera.getCamera(cams.selectedItem.data);
+			debug("_attachCamera():: muted ? " + cam.muted);
+			if (cam.muted) {
+				debug("Unable to connect to active camera.");
+			} else {
+				try {
+					//videoDisplay.stop();
+					//videoDisplay.attachCamera(null);
+					cam.setMode(videoDisplay.width, videoDisplay.height, FPS);
+					videoDisplay.attachCamera(cam);
+					debug("_attachCamera()::done");
+				} catch (error:Error) {
+					debug("_attach:: " + error.message + "\n" + error.getStackTrace());
+				}
+			}
+		}
+
+		private function setResolution(width:int, height:int):void {
+			if (!interview) {
+				debug("onselect WxH :: " + width + "x" + height);
+
+				videoScroller.width = Math.min(width, RIGHT_WIDTH);
+				videoScroller.height = Math.min(height, 200);
+				var newWidth:int = Math.max(APP_WIDTH, APP_WIDTH + videoScroller.width - RIGHT_WIDTH);
+				var newHeight:int = Math.max(500, 500 + videoScroller.height - 180);
+
+				var yPos:int = (startTest as DisplayObject).localToGlobal(new Point()).y;
+				debug("GLOBAL Y:: " + yPos);
+				playGroup.y = Math.max(yPos, videoScroller.height);
+				setDimensions(newWidth, newHeight);
+				videoDisplay.width = width;
+				videoDisplay.height = height;
+
+				attachCamera();
+			}
+		}
+
+		private function resChanged(e:Event):void {
+			setResolution(e.target.selectedItem.width, e.target.selectedItem.height);
+		}
+
+		private function camChanged(e:Event):void {
+			attachCamera();
+		}
+
+		private function startConf(e:Event):void {
+			store();
+		}
+		]]></fx:Script>
+
+	<s:Group id="mainSetupGroup" width="{APP_WIDTH}">
+		<s:layout>
+			<s:VerticalLayout/>
+		</s:layout>
+		<mx:Text width="100%" fontWeight="bold" text="{getLabel(758)}"/>
+		<s:HGroup>
+			<s:VGroup>
+				<mx:Text text="{getLabel(447)}"/>
+				<mx:ComboBox id="modes" width="{LEFT_WIDTH}" change="modeChanged(event)"/>
+				<s:VGroup id="av">
+					<s:VGroup id="camGroup">
+						<mx:Text text="{getLabel(52)}"/>
+						<mx:ComboBox id="cams" width="{LEFT_WIDTH}" change="camChanged(event)"/>
+					</s:VGroup>
+					<s:VGroup id="micGroup">
+						<mx:Text text="{getLabel(53)}"/>
+						<mx:ComboBox id="mics" width="{LEFT_WIDTH}"/>
+					</s:VGroup>
+					<s:VGroup id="resGroup">
+						<s:Group><mx:Text text="{getLabel(1429)}"/><mx:Image x="260" source="assets/error.png" toolTip="{getLabel(1430)}"/></s:Group>
+						<mx:ComboBox id="ress" width="{LEFT_WIDTH}" change="resChanged(event)"/>
+					</s:VGroup>
+					<s:Group width="100%">
+						<s:layout><s:HorizontalLayout horizontalAlign="right"/></s:layout>
+						<s:Button id="startTest" label="{getLabel(775)}"/>
+					</s:Group>
+				</s:VGroup>
+				<mx:Text text="{getLabel(452)}" id="noAv" visible="false"/>
+			</s:VGroup>
+			<s:Group id="videoGroup">
+				<s:Scroller id="videoScroller">
+					<s:Group id="videoScrollGroup">
+						<mx:VideoDisplay id="videoDisplay" width="0" height="0"/>
+					</s:Group>
+				</s:Scroller>
+				<s:VGroup id="playGroup">
+					<s:Group>
+						<s:Graphic x="0" z="1">
+							<s:Rect width="{RIGHT_WIDTH}" height="20">
+								<s:fill><s:SolidColor color="white"/></s:fill>
+								<s:stroke><s:SolidColorStroke color="black" weight="2"/></s:stroke>
+							</s:Rect>
+						</s:Graphic>
+						<mx:Image id="fill" source="assets/level_meter.png" x="2" y="1" z="3" width="0"/>
+						<mx:Text text="{getLabel(767)}" x="0" z="5"/>
+					</s:Group>
+					<s:Group width="100%">
+						<s:layout><s:HorizontalLayout horizontalAlign="right"/></s:layout>
+						<s:Button id="play" label="{getLabel(764)}" enabled="false"/>
+					</s:Group>
+				</s:VGroup>
+			</s:Group>
+		</s:HGroup>
+		<s:HGroup><mx:Image source="assets/info.png"/><mx:Text text="{getLabel(765)}"/></s:HGroup>
+		<s:Group width="100%">
+			<s:layout><s:HorizontalLayout horizontalAlign="right"/></s:layout>
+			<s:Button id="cancel" label="{getLabel(918)}"/>
+			<s:Button id="start" label="{getLabel(interview ? 54 : 761)}" click="startConf(event)"/>
+		</s:Group>
+		<s:CheckBox id="remember" label="{getLabel(762)}" />
+	</s:Group>
+	<s:TextArea id="traceArea" y="450" width="400" height="400" text="{debugStr}"/>
+</s:Application>