video profiles, save data, preview camera on mobile.

changed audio and video connection parameters
This commit is contained in:
LucasMFreire 2015-07-21 16:49:46 -03:00
parent dc0f81126e
commit 27a4e21f97
9 changed files with 517 additions and 0 deletions

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
styleName="cameraProfileItemStyle">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import mx.utils.ObjectUtil;
private var guestID:String;
override public function set data(obj:Object):void {
super.data = obj;
if (obj) {
quality.text = obj.name;
}
}
]]>
</fx:Script>
<s:Group width="100%"
height="{getStyle('itemHeight')}">
<s:Label id="quality"
styleName="contentFontSize"
width="100%"
height="100%" />
</s:Group>
<s:Line width="100%">
<s:stroke>
<s:SolidColorStroke color="{getStyle('lineColor')}"
weight="{getStyle('lineWeight')}" />
</s:stroke>
</s:Line>
</s:ItemRenderer>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<s:List xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
itemRenderer="org.bigbluebutton.air.settings.views.cameraprofiles.CameraProfileItemRenderer"
styleName="cameraProfilesListStyle">
<s:layout>
<s:VerticalLayout horizontalAlign="contentJustify"
gap="0"
verticalAlign="middle"
variableRowHeight="false" />
</s:layout>
<fx:Declarations>
</fx:Declarations>
</s:List>

View File

@ -0,0 +1,7 @@
package org.bigbluebutton.lib.common.models {
public interface ISaveData {
function save(name:String, obj:Object):void
function read(name:String):Object
}
}

View File

@ -0,0 +1,21 @@
package org.bigbluebutton.lib.common.models {
import flash.net.SharedObject;
public class SaveData implements ISaveData {
private var sharedObject:SharedObject;
public function SaveData() {
sharedObject = SharedObject.getLocal("mconf");
}
public function save(name:String, obj:Object):void {
sharedObject.data[name] = obj;
sharedObject.flush();
}
public function read(name:String):Object {
return sharedObject.data[name];
}
}
}

View File

@ -0,0 +1,91 @@
package org.bigbluebutton.lib.main.models
{
import org.osflash.signals.Signal;
public class LockSettings {
private var _disableCamSignal:Signal = new Signal();
private var _disableMicSignal:Signal = new Signal();
private var _disablePrivateChatSignal:Signal = new Signal();
private var _disablePublicChatSignal:Signal = new Signal();
private var _disableCam:Boolean;
private var _disableMic:Boolean;
private var _disablePrivateChat:Boolean;
private var _disablePublicChat:Boolean;
private var _lockedLayout:Boolean;
public function LockSettings() {
}
public function get disableCamSignal():Signal {
return _disableCamSignal;
}
public function get disableMicSignal():Signal {
return _disableMicSignal;
}
public function get disablePrivateChatSignal():Signal {
return _disablePrivateChatSignal;
}
public function get disablePublicChatSignal():Signal {
return _disablePublicChatSignal;
}
public function get disableCam():Boolean {
return _disableCam;
}
public function get lockedLayout():Boolean {
return _lockedLayout;
}
public function set disableCam(disable:Boolean):void {
if (_disableCam != disable) {
_disableCam = disable;
}
}
public function get disableMic():Boolean {
return _disableMic;
}
public function set disableMic(disable:Boolean):void {
if (_disableMic != disable) {
_disableMic = disable;
}
}
public function get disablePrivateChat():Boolean {
return _disablePrivateChat;
}
public function set disablePrivateChat(disable:Boolean):void {
if (_disablePrivateChat != disable) {
_disablePrivateChat = disable;
}
}
public function get disablePublicChat():Boolean {
return _disablePublicChat;
}
public function set disablePublicChat(disable:Boolean):void {
if (_disablePublicChat != disable) {
_disablePublicChat = disable;
}
}
public function set lockedLayout(disable:Boolean) {
_lockedLayout = disable;
}
}
}

View File

@ -0,0 +1,15 @@
package org.bigbluebutton.lib.video.models
{
import org.bigbluebutton.lib.user.models.User;
public class UserStreamName {
public var streamName:String;
public var user:org.bigbluebutton.lib.user.models.User;
public function UserStreamName(streamName:String, user:User) {
this.streamName = streamName;
this.user = user;
}
}
}

View File

@ -0,0 +1,157 @@
package org.bigbluebutton.lib.video.models
{
import flash.utils.Dictionary;
import mx.resources.ResourceManager;
public class VideoProfile {
private var _fallbackLanguage:String;
private static var _nextId:int = -1;
private var _id:String;
private var _default:Boolean = false;
private var _name:Dictionary = new Dictionary();
private var _width:int = 320;
private var _height:int = 240;
private var _keyFrameInterval:int = 30;
private var _modeFps:int = 10;
private var _qualityBandwidth:int = 0;
private var _qualityPicture:int = 90;
private var _enableH264:Boolean = true;
private var _h264Level:String = "2.1";
private var _h264Profile:String = "main";
public function VideoProfile(vxml:XML, fallbackLanguage:String) {
_fallbackLanguage = fallbackLanguage;
if (vxml.@id != undefined) {
_id = vxml.@id.toString();
} else {
_id = String(nextId());
}
if (vxml.@default != undefined) {
_default = ((vxml.@default).toString().toUpperCase() == "TRUE") ? true : false;
}
if (vxml.locale != undefined) {
for each (var locale:XML in vxml.locale.children()) {
_name[locale.localName()] = locale.toString();
}
}
if (vxml.width != undefined) {
_width = vxml.width;
}
if (vxml.height != undefined) {
_height = vxml.height;
}
if (vxml.keyFrameInterval != undefined) {
_keyFrameInterval = vxml.keyFrameInterval;
}
if (vxml.modeFps != undefined) {
_modeFps = vxml.modeFps;
}
if (vxml.qualityBandwidth != undefined) {
_qualityBandwidth = vxml.qualityBandwidth;
}
if (vxml.qualityPicture != undefined) {
_qualityPicture = vxml.qualityPicture;
}
if (vxml.enableH264 != undefined) {
_enableH264 = (vxml.enableH264.toString().toUpperCase() == "TRUE") ? true : false;
}
if (vxml.h264Level != undefined) {
_h264Level = vxml.h264Level.toString();
}
if (vxml.h264Profile != undefined) {
_h264Profile = vxml.h264Profile.toString();
}
trace("This is a new video profile");
trace(this.toString());
}
public function toString():String {
return "VideoProfile [ "
+ "id: " + this.id + ", "
+ "default: " + this.defaultProfile + ", "
+ "name: " + this.name + ", "
+ "width: " + this.width + ", "
+ "height: " + this.height + ", "
+ "keyFrameInterval: " + this.keyFrameInterval + ", "
+ "modeFps: " + this.modeFps + ", "
+ "qualityBandwidth: " + this.qualityBandwidth + ", "
+ "qualityPicture: " + this.qualityPicture + ", "
+ "enableH264: " + this.enableH264 + ", "
+ "h264Level: " + this.h264Level + ", "
+ "h264Profile: " + this.h264Profile + " ]";
}
private static function nextId():int {
_nextId++;
return _nextId;
}
public function get id():String {
return _id;
}
public function get defaultProfile():Boolean {
return _default;
}
public function get name():String {
var locale:String = ResourceManager.getInstance().localeChain[0]; //"en_US";//ResourceUtil.getInstance().getCurrentLanguageCode();
if (_name.hasOwnProperty(locale)) {
return _name[locale];
} else if (_name.hasOwnProperty(_fallbackLanguage)) {
return _name[_fallbackLanguage];
} else {
return "";
}
}
public function get width():int {
return _width;
}
public function get height():int {
return _height;
}
public function get keyFrameInterval():int {
return _keyFrameInterval;
}
public function get modeFps():int {
return _modeFps;
}
public function get qualityBandwidth():int {
return _qualityBandwidth;
}
public function get qualityPicture():int {
return _qualityPicture;
}
public function get enableH264():Boolean {
return _enableH264;
}
public function get h264Level():String {
return _h264Level;
}
public function get h264Profile():String {
return _h264Profile;
}
}
}

View File

@ -0,0 +1,126 @@
package org.bigbluebutton.lib.video.models
{
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.net.URLLoader;
import flash.net.URLRequest;
import mx.core.FlexGlobals;
import mx.utils.ObjectUtil;
import mx.utils.URLUtil;
public class VideoProfileManager extends EventDispatcher {
public static const PROFILES_XML:String = "client/conf/profiles.xml";
public static const DEFAULT_FALLBACK_LOCALE:String = "en_US";
private var _profiles:Array = new Array();
public function parseProfilesXml(profileXML:XML):void {
// first clear the array
_profiles.splice(0);
var fallbackLocale:String = profileXML.@fallbackLocale != undefined ? profileXML.@fallbackLocale.toString() : DEFAULT_FALLBACK_LOCALE;
for each (var profile:XML in profileXML.children()) {
_profiles.push(new VideoProfile(profile, fallbackLocale));
}
}
public function parseConfigXml(configXML:XML):void {
var resolutionsString:String = configXML.@resolutions;
var resolutions:Array = resolutionsString.split(",");
for (var resolution in resolutions) {
var profileXml:XML = <profile></profile>
profileXml.@['id'] = resolutions[resolution];
profileXml.locale.en_US = resolutions[resolution];
profileXml.width = resolutions[resolution].split("x")[0];
profileXml.height = resolutions[resolution].split("x")[1];
profileXml.keyFrameInterval = configXML.@camKeyFrameInterval;
profileXml.modeFps = configXML.@camModeFps;
profileXml.qualityBandwidth = configXML.@camQualityBandwidth;
profileXml.qualityPicture = configXML.@camQualityPicture;
profileXml.enableH264 = configXML.@enableH264;
profileXml.h264Level = configXML.@h264Level;
profileXml.h264Profile = configXML.@h264Profile;
var profile:VideoProfile = new VideoProfile(profileXml, DEFAULT_FALLBACK_LOCALE);
_profiles.push(profile);
}
}
public function get profiles():Array {
if (_profiles.length > 0) {
return _profiles;
} else {
return [fallbackVideoProfile];
}
}
public function getVideoProfileById(id:String):VideoProfile {
for each (var profile:VideoProfile in profiles) {
if (profile.id == id) {
return profile;
}
}
return null;
}
public function getVideoProfileByStreamName(streamName:String):VideoProfile {
trace("stream name: " + streamName);
var pattern:RegExp = new RegExp("([a-z0-9]+)-([A-Za-z0-9_]+)-\\d+", "");
if (pattern.test(streamName)) {
var profileID:String = pattern.exec(streamName)[1]
for each (var profile:VideoProfile in _profiles) {
if (profile.id == profileID) {
return profile;
}
}
return null;
} else {
return null;
}
}
public function get defaultVideoProfile():VideoProfile {
for each (var profile:VideoProfile in _profiles) {
if (profile.defaultProfile) {
return profile;
}
}
if (_profiles.length > 0) {
return _profiles[0];
} else {
return null;
}
}
public function get fallbackVideoProfile():VideoProfile {
return new VideoProfile(
<profile id="160x120" default="true">
<locale>
<en_US>Fallback profile</en_US>
</locale>
<width>160</width>
<height>120</height>
<keyFrameInterval>5</keyFrameInterval>
<modeFps>10</modeFps>
<qualityBandwidth>0</qualityBandwidth>
<qualityPicture>90</qualityPicture>
<enableH264>true</enableH264>
<h264Level>2.1</h264Level>
<h264Profile>main</h264Profile>
</profile>
, DEFAULT_FALLBACK_LOCALE);
}
public function getProfileWithLowerResolution():VideoProfile {
if (_profiles.lenth <= 0) {
return fallbackVideoProfile;
}
var lower:VideoProfile = _profiles[0];
for each (var profile:VideoProfile in _profiles) {
if (((profile.width) * (profile.height)) < ((lower.width) * (lower.height))) {
lower = profile;
}
}
return lower;
}
}
}

View File

@ -0,0 +1,49 @@
package org.bigbluebutton.lib.video.services
{
import flash.events.Event;
import flash.events.HTTPStatusEvent;
import flash.events.IOErrorEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLRequestHeader;
import flash.net.URLRequestMethod;
import mx.utils.ObjectUtil;
import org.bigbluebutton.lib.common.utils.URLParser;
import org.osflash.signals.ISignal;
import org.osflash.signals.Signal;
import org.bigbluebutton.lib.common.utils.URLFetcher;
public class ProfilesService {
protected var _successSignal:Signal = new Signal();
protected var _unsuccessSignal:Signal = new Signal();
public function get successSignal():ISignal {
return _successSignal;
}
public function get unsuccessSignal():ISignal {
return _unsuccessSignal;
}
public function getProfiles(serverUrl:String, urlRequest:URLRequest):void {
var ProfileUrl:String = serverUrl + "/client/conf/profiles.xml?a=" + new Date().time;
var fetcher:URLFetcher = new URLFetcher;
fetcher.successSignal.add(onSuccess);
fetcher.failureSignal.add(onUnsuccess);
fetcher.fetch(ProfileUrl, urlRequest);
}
protected function onSuccess(data:Object, responseUrl:String, urlRequest:URLRequest):void {
try {
successSignal.dispatch(new XML(data));
} catch (e:Error) {
onUnsuccess("invalidXml");
}
}
protected function onUnsuccess(reason:String):void {
unsuccessSignal.dispatch(reason);
}
}
}