Expand my Community achievements bar.

SOLVED

how to change the videochat layout in FP 10?

Avatar

Level 2

Hello!

I´m developing an app that display the video screens in random positions on the stage. I already made some changes on the FP9 source code to achieve that and worked pretty well. but to be able to use p2p and speex, I need to move on to FP10, where I only have the FP10 swc.

Is there a way to change the layout for FP10?

more than glad for any (positive ) answer

Bruno

1 Accepted Solution

Avatar

Correct answer by
Former Community Member

Hi,

There is a way to display the video screens with the layout you want. You need to use WebcamSubscriber for each of the display with one person/group of persons in a subscriber. You need to set those user ids to WebcamSubscriber's publisherIDs property.

This property lets you set an user/a set of users for that subscriber instead of showing all user streams in one subscriber(the current default).

We don't provide the player 10 source yet, but we believe you should ideally use combination of subscribers according to your need for various layouts.

Examples like zoomLayout or WebCamera kind of shows that. I can provide with more ideas based on the layout you want.

Thanks

Hironmay Basu

View solution in original post

9 Replies

Avatar

Correct answer by
Former Community Member

Hi,

There is a way to display the video screens with the layout you want. You need to use WebcamSubscriber for each of the display with one person/group of persons in a subscriber. You need to set those user ids to WebcamSubscriber's publisherIDs property.

This property lets you set an user/a set of users for that subscriber instead of showing all user streams in one subscriber(the current default).

We don't provide the player 10 source yet, but we believe you should ideally use combination of subscribers according to your need for various layouts.

Examples like zoomLayout or WebCamera kind of shows that. I can provide with more ideas based on the layout you want.

Thanks

Hironmay Basu

Avatar

Level 2

Hello Hironmay!

Thanks for the answer! I´ll definitely take a look on what you said!

makes a lot of sense...

I´ll come back in case of new questions...

The only issue I still have without an available solution is the AEC for communication... almost all users will interact from laptops and in our case headsets are not an option...

but thank you a lot again!

I´ll post the results here as soon I have any...

Bruno

Avatar

Level 2

Hello Hironmay!

I checked the webcam example and it seems the right way for me but every time I run the project I receive this warning:

warning: unable to bind to property 'userID' on class 'com.adobe.rtc.sharedManagers.descriptors::UserDescriptor' (class is not an IEventDispatcher)

The camera(Isight) shows that is capturing, but doesn´t display anything... I must be missing something really basic here... I just used my credentials and room url as usual, didn´t modify anything in the code... I´m using the FP10 swc and flash builder 4, flex 4.0 sdk. Any Idea?

thanks in advance!

bruno

Avatar

Former Community Member

I will run the example and let you know. In the meanwhile, you can refer to the code of using Multiple webcam subscribers for different layouts.

Thanks

Hironmay Basu

Avatar

Level 2

Hello Hironmay!

For some weird reason I can´t get the webcam example to run, no mather what I do I get the folowing warnings:

warning: unable to bind to property 'userManager' on class 'com.adobe.rtc.session::ConnectSessionContainer'
warning: unable to bind to property 'myUserID' on class 'com.adobe.rtc.sharedManagers::UserManager'

right before the app even request the fms. And then after the connection I get these ones:

warning: unable to bind to property 'userID' on class 'com.adobe.rtc.sharedManagers.descriptors::UserDescriptor' (class is not an IEventDispatcher)

several times...

In fact, it does run in the other app´s I build, but the webcam example doesn´t show the videos...

Do I need two specific swf´s? one for the publisher and one for the subscribers?

any help would be wonderful!!! if there would be any other place on the net I could also ask...

I´ll will upload the debug log so you can take a look...
anyway, thanks for your great help on the forums!!

bruno

Avatar

Former Community Member

Hi ,

Sorry for the delay, as the thanksgiving holidays are on these days. I got a chance to look at your problem and there are two issues

a) You need to specify some width and height to WebcamSubscriber . This was not required earlier, but due to some of our recent changes , it is needed but the subsequent example was not updated for the check on our part.

b) The UserDescriptor warning doesnot do any harm and all you need to do is some type casting.

I am attaching the updated WebCamera code here. The code is just for some reference. You might hit some exception in VideoComponent but in case you are using player 9 source I can give you the fix for that source file also. These changes will be updated in the next SDK version releasing very soon. Thanks for pointing out the fix needed for the example.

Instead of using repeaters , you can design your own layout, this code just points how to use multiple subscribers.

Hope this helps.

Thanks

Hironmay Basu

WebCamera.mxml

<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"

xmlns:rtc="AfcsNameSpace">

<mx:Script>

<![CDATA[

import com.adobe.rtc.sharedManagers.descriptors.UserDescriptor;

import com.adobe.rtc.messaging.UserRoles;

import com.adobe.rtc.events.ConnectSessionEvent;

import mx.controls.Button;

import com.adobe.coreUI.controls.CameraUserBar;

import mx.core.UITextField;

import mx.controls.LinkButton;

import com.adobe.rtc.events.SharedPropertyEvent;

import com.adobe.rtc.sharedModel.SharedProperty;

import com.adobe.rtc.collaboration.WebcamSubscriber;

import mx.containers.VBox;

import com.adobe.rtc.events.UserEvent;

import com.adobe.rtc.sharedManagers.StreamManager ;

import com.adobe.rtc.sharedManagers.descriptors.StreamDescriptor ;

private var currentSubscriber:WebcamSubscriber ;

private var sharedProperty:SharedProperty ;

/**********************************************************

  • This example shows how the camera component can be used with a publisher and a

  • number of subscribers. The publisher has a big view while subscribers have a small view.

  • A shared property is used to pass the stream to the publisher's user interface.

  • Every user is provided with play and pause handlers.

  • *********************************/

private function onCreationComplete():void

{

cSession.roomManager.autoPromote = true ;

cSession.roomManager.guestsHaveToKnock = false ;

sharedProperty = new SharedProperty();

sharedProperty.isSessionDependent = true ;

sharedProperty.sharedID = "webcamShare2" ;

sharedProperty.connectSession = cSession ;

sharedProperty.subscribe();

sharedProperty.addEventListener(SharedPropertyEvent.CHANGE,onChange);

cSession.userManager.addEventListener(UserEvent.USER_REMOVE,onUserRemove)

}

/**

  • @private

*/

protected function onUserRemove(p_event:UserEvent):void

{

if ( sharedProperty.value && p_event.userDescriptor.userID == sharedProperty.value[0]) {

sharedProperty.value = [] ;

}

}

/**************

  • When the main big stream changes, all users can view it via the sharedProperty.

*********************/

private function onChange(p_evt:SharedPropertyEvent):void

{

if ( currentSubscriber != null ) {

clickedContainer.removeChild(currentSubscriber);

currentSubscriber.close();

currentSubscriber = null ;

}

if ( sharedProperty.value == null || sharedProperty.value.length == 0 ) {

return ;

}

currentSubscriber = new WebcamSubscriber();

currentSubscriber.connectSession = cSession ;

currentSubscriber.subscribe();

currentSubscriber.webcamPublisher = webCamPub ;

currentSubscriber.publisherIDs = sharedProperty.value ;

currentSubscriber.addEventListener(UserEvent.USER_BOOTED,onCleared);

currentSubscriber.addEventListener(UserEvent.STREAM_CHANGE,onCameraPause);

clickedContainer.addChild(currentSubscriber);

invalidateDisplayList();

}

/************************

  • If the big image is stopped, clear it.

********/

private function onCleared(p_evt:UserEvent):void

{

if ( cSession.userManager.myUserRole == UserRoles.OWNER ) {

sharedProperty.value = [] ;

}

}

/***********

  • Clicking on the small image below makes it large.

*****/

private function onClick(p_evt:MouseEvent):void

{

if ( (p_evt.currentTarget is WebcamSubscriber) && !(p_evt.target.parent is CameraUserBar)) {

sharedProperty.value = (p_evt.currentTarget as WebcamSubscriber).publisherIDs;

}

}

override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void

{

super.updateDisplayList(unscaledWidth,unscaledHeight);

if ( currentSubscriber ) {

currentSubscriber.percentWidth = 100 ;

currentSubscriber.percentHeight = 100 ;

}

}

/****

  • Handler for a user stopping the camera.

*/

private function onBooted(p_evt:UserEvent):void

{

if ( (p_evt.currentTarget is WebcamSubscriber) && (p_evt.userDescriptor.userID == cSession.userManager.myUserID || cSession.userManager.myUserRole == UserRoles.OWNER)) {

webCamPub.stop();

if ( (p_evt.currentTarget.parent as VBox).getChildAt(1) is Button ){

((p_evt.currentTarget.parent as VBox).getChildAt(1) as Button).label = "Start" ;

}

if ( sharedProperty.value && (sharedProperty.value as Array)[0] == p_evt.userDescriptor.userID ) {

sharedProperty.value = [] ;

}

}

}

/**

  • Handler for a user pausing the camera.

*/

protected function onCameraPause(p_evt:UserEvent):void

{

var userStreams:Array = cSession.streamManager.getStreamsForPublisher(p_evt.userDescriptor.userID,StreamManager.CAMERA_STREAM);

if (userStreams.length == 0) {

trace("onCameraPause: no userStreams");

return;

}

for (var i:int = 0; i< userStreams.length ; i++ ) {

if (userStreams[i].type == StreamManager.CAMERA_STREAM ) {

break;

}

}

var streamDescriptor:StreamDescriptor = userStreams[i];

if ( streamDescriptor.streamPublisherID == cSession.userManager.myUserID ) {

cSession.streamManager.pauseStream(StreamManager.CAMERA_STREAM,!streamDescriptor.pause,streamDescriptor.streamPublisherID);

}

}

/*****

  • Handler for the stop and start buttons.

*******/

private function onBtnClick(p_evt:MouseEvent):void

{

if ( p_evt.currentTarget.label == "Start" ) {

webCamPub.publish();

p_evt.currentTarget.label = "Stop" ;

}else if (p_evt.currentTarget.label == "Stop" ){

webCamPub.stop();

p_evt.currentTarget.label = "Start" ;

}

}

]]>

</mx:Script>

<!--

You would likely use external authentication here for a deployed application;

you would certainly not hard code Adobe IDs here.

-->

<rtc:AdobeHSAuthenticator

id="auth"

userName="AdobeIDusername"

password="AdobeIDpassword" />

<rtc:ConnectSessionContainer id="cSession" authenticator="" width="100%"

height="100%" roomURL="YourPersonalRoomUrl" >

<mx:Panel title="Webcam Example" width="100%" height="100%"

paddingTop="10" paddingLeft="10" paddingRight="10" paddingBottom="10" creationComplete="onCreationComplete()">

<rtc:WebcamPublisher id="webCamPub" width="10" height="5"/>

<mx:VBox width="100%" height="100%" id="clickedContainer"/>

<mx:HBox horizontalGap="10" verticalGap="15" paddingLeft="10" paddingTop="10" paddingBottom="10" paddingRight="10" width="100%" height="25%">

<mx:Repeater id="rp" dataProvider="{cSession.userManager.userCollection}" width="100%" height="100%" >

<mx:VBox width="100%" height="15%" horizontalAlign="center" horizontalGap="5">

<rtc:WebcamSubscriber webcamPublisher="" width="100%" height="100%" publisherIDs="{[(rp.currentItem as UserDescriptor).userID]}" click="onClick(event)" userBooted="onBooted(event)" streamChange="onCameraPause(event)"/>

<mx:Button label="Start" click="onBtnClick(event)" visible="{(rp.currentItem as UserDescriptor).userID==cSession.userManager.myUserID}" />

</mx:VBox>

</mx:Repeater>

</mx:HBox>

</mx:Panel>

</rtc:ConnectSessionContainer>

</mx:Application

Avatar

Level 2

Hello Hironmay!

Thanks again for your help!!

How you guys manage to answer all the threads on this forum?!?

the code you send me works perfectly ´till I start my second camera, then it throws the video component exception. Currently I´m trying both FP9 and 10 so, if there´s a solution for FP9, I´m more than happy to hear about it

do you have a release date for the next update?  We will make an public beta of our app on the 14, and this is the last part to finish before it goes live, I´ll post the link as soon as it´s up and running.

thanks!

bruno

Avatar

Former Community Member

Hi,

Yes I have your fix ready. What you need to do in the code, go to VideoComponent file in com.adobe.rtc.coreUI.controls and replace the existing updateDispayList function with this below. Basically I am adding a null check.

Hopefully it will work fine for you then

Thanks

Hironmay Basu

/**

*

*/

override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void

{

var g:Graphics = _hitArea.graphics;

g.clear();

g.beginFill(0x00000, 0);

if ( !isNaN(unscaledWidth) && !isNaN(unscaledHeight) ) {

g.drawRect(0, 0, unscaledWidth, unscaledHeight);

_video.width = unscaledWidth;

_video.height = unscaledHeight;

super.updateDisplayList(unscaledWidth, unscaledHeight);

}

}

Avatar

Level 2

Hironmay, you are my hero!!

thanks a lot!!!

wish you nice week!

thanks,

bruno

The following has evaluated to null or missing: ==> liqladmin("SELECT id, value FROM metrics WHERE id = 'net_accepted_solutions' and user.id = '${acceptedAnswer.author.id}'").data.items [in template "analytics-container" at line 83, column 41] ---- Tip: It's the step after the last dot that caused this error, not those before it. ---- Tip: If the failing expression is known to be legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)?? ---- ---- FTL stack trace ("~" means nesting-related): - Failed at: #assign answerAuthorNetSolutions = li... [in template "analytics-container" at line 83, column 5] ----