Expand my Community achievements bar.

Webcamera + Audio

Avatar

Level 2
I would like to get the webcamera and audio working well
together. What I have done is taken the example code for the
webcamera and added in AudioSubscriber and AudioPublisher. The
first problem is performance is terrible. I have quality on the
webcam publisher set to 70. Most of the time I cant even hear the
audio from the other end. Each of these components is within the
same ConnectSessionContainer. I am not doing anything differently
to the SharedProperty as found in the example code. I looked around
on this forum for help but didn't really find what I was looking
for. Does anyone know how to do this correctly/efficiently? It
would be nice if the webcamera example also had audio. It doesn't
do a whole lot to have video and no audio.

Thanks!
46 Replies

Avatar

Former Community Member
Hi dhavrda,



Sorry, most of this post was pretty hard to understand -
when you say "performance", what do you mean? Quality? If you run
the "Audio" example in the examples folder, does that work? I can
appreciate being frustrated when things don't work, but we need
more specific details of what's wrong, and less venting, in order
to help you.



thanks

nigel

Avatar

Level 2
When I say performance, I mean the video just freezes and
then plays back at super high speed etc.. Very erratic behavior.
The video quality looks OK. The audio example does work. But my
question was around how to use the audio with the webcam. Both of
the examples work individually. I just thought maybe I was doing
something wrong when using both of them together. As I have it now
it is really not very usable. The only changes I have made is by
not automatically putting everyone in the list to show. I let the
user select who he wants in his communication list/view. As stated
earlier, I just added the audioPub.publish and stop in the same
places as the video. Let me know if I can get you any other info
that may help.



Here is some code if that helps:



This is the same from the example:

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);



Here is my container declaration:



<session:ConnectSessionContainer id="cSession"
authenticator="{auth}"

roomURL="
myroomurl"

backgroundColor="#404040"

width="100%" height="100%">



<collaboration:WebcamPublisher id="webCamPub" width="10"
height="5" quality="70"/>

<collaboration:AudioPublisher id="audioPub" height="0"
useEchoSuppression="true"/>



<!-- only listen to the subscribers we have selected
-->

<collaboration:AudioSubscriber id="audioSub"
publisherIDs="{audioIds}"/>



<mx:Tile id="camTiles"

direction="horizontal"

height="100%"

width="100%"

alpha="0"

horizontalScrollPolicy="off"

verticalScrollPolicy="off"

creationComplete="onCreationComplete()"

horizontalGap="10" verticalGap="10">



<mx:Repeater id="rp" dataProvider="{selectedUsers}">



<components:ResizableCanvas id="rs" width="100%"
height="100%"

minHeight="200" minWidth="200"

backgroundAlpha=".5"

backgroundColor="gray"

cornerRadius="12"

borderStyle="solid"

horizontalScrollPolicy="off" verticalScrollPolicy="off">





<collaboration:WebcamSubscriber
webcamPublisher="{webCamPub}"

width="100%" height="100%"

publisherIDs="{[rp.currentItem.userID]}"
click="onClick(event)"

userBooted="onBooted(event)"
streamChange="onCameraPause(event)"/>

</components:ResizableCanvas>



</mx:Repeater>



</mx:Tile>



</session:ConnectSessionContainer>







I wasn't venting by the way. I just wanted to find out how to
do this the correct way :-) Sorry if my post came off as
venting.

Avatar

Level 2
hello i have too a bug for webcam + audio





I have video but I haven't sound , why?

see my source codes :



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

<!-- Ce programme va me servir à integrer les pods
à ma page web -->

<mx:Application layout="absolute"

xmlns:mx="
http://www.adobe.com/2006/mxml"

xmlns:rtc="AfcsNameSpace"

>

<mx:Script>

<![CDATA[

import mx.controls.Alert;



import com.adobe.rtc.events.SessionEvent;

import com.adobe.rtc.messaging.UserRoles;

import com.adobe.rtc.collaboration.AudioPublisher; //
AudioPublisher me sert pour la gestion du microphone

//import com.adobe.rtc.collaboration; // me sert pour la
gestion du microphone

//import com.adobe.rtc.clientManagers;// me sert pour la
gestion du microphone

import com.adobe.rtc.collaboration.AudioSubscriber ;





import mx.controls.Label;

import mx.core.UIComponent; // me sert pour la gestion du
microphone

import flash.events.EventDispatcher// me sert pour la
gestion du microphone



</mx:Script>





---end mx :script



<!-- Container Gestionnaire de session (le bon enfin
trouvé) -->

<rtc:ConnectSessionContainer id="sessionManager"

width="500" height="400" backgroundColor="#FFFFFF"

authenticator="{identificator}" autoLogin="false"

roomURL="
http://connectnow.acrobat.com/lionceau01/essai"

synchronizationChange="onSynchro( event )"



/>



<!-- PODS -->

<mx:VBox width="60%" height="100%"
horizontalAlign="center">

<rtc:WebCamera id="webcam" width="100%" height="100%"





/>



</mx:VBox>









<mx:VBox width="40%" height="100%" right="0">

<mx:Button label="Déconnexion" click="logout()"
/>

<rtc:AudioPublisher id="audio"

height="0"

useEchoSuppression="true"

gain="100"



/>











<mx:Button id="btnTalk"

label="{btnTalk.selected ? 'Stop Talking':'Start Talking'}"

toggle="true"

click="{btnTalk.selected ? audio.publish():audio.close()}"

/>



<!-- only listen to the subscribers we have selected
-->







<!-- what do ? how do ? i have many bug -->













<!--adel <mx:Button label="activer le son"
click="_creating(true)" />

<mx:Button label="+ volume" click="gain(2)" />

<mx:Button label="- volume" click="gain(-2)" />

-->

<rtc:Note id="notes" width="100%" height="40%" />

<rtc:FileShare id="fileManager" width="100%" height="20%"
/>



<!-- ligne à finir <rtc:SharedWhiteBoard
id="essai" width="50%" height="50%" /> -->

<rtc:SimpleChat id="chat" width="100%" height="40%" />


</mx:VBox>

















Many thanks for your help ,





Lionceau,









Avatar

Former Community Member
Hi,



I can't see you adding AudioSubscriber to your code. You need
to add <rtc:AudioSubscriber> to listen to the audio. You are
only publishing the audio using AudioPublisher but without the
subscriber you can't listen to it . See the example Audio.mxml or
DefaultPods.mxml which uses both AudioPublisher and
AudioSubscriber.



Hope this helps.



Thanks

Hironmay Basu



Avatar

Level 2
hi ,



Yes, thanks but where i find this ? " the example Audio.mxml
or DefaultPods.mxm"

Can you give this adress (web site) ?



many hanks ,



Lionceau,

Avatar

Former Community Member
Hi,



When you download the SDK and unzip it, they will be in
examples folder . For Audio.mxml, go to examples/Audio and for
Default Pods it is examples/DefaultPods folder.

All you need to do is add the Audiosubscriber class by adding
a line <rtc:AudioSubscriber> after you have added the
publisher.





Hope this helps.



Thanks

Hironmay Basu

Avatar

Level 2
hi,





Thanks i search , i find this , but why? i don't have sound
?????

see in my source code :



<mx:VBox width="40%" height="100%" right="0">

<mx:Button label="Déconnexion" click="logout()"
/>



<!-- scroll bar pourle volume -->

<mx:VBox paddingLeft="15" width="10%">

<mx:Label text="Gain" fontWeight="bold" />

<mx:HSlider id="gainSlider" minimum="0" maximum="100"
width="90%" value="{audio.gain}" labels="[0,50,100]"
change="onGainChange(event)" />

</mx:VBox>





<mx:VBox paddingLeft="15" fontWeight="bold"
width="70%">

<mx:Label text="UseEchoSuppression"/>

<mx:RadioButtonGroup id="echoGroup"
itemClick="onItemClick(event)" />

<mx:RadioButton label="Yes"
selected="{audio.useEchoSuppression}" groupName="echoGroup" />

<mx:RadioButton label="No"
selected="{!audio.useEchoSuppression}" groupName="echoGroup"/>

</mx:VBox>

<!--<mx:VBox paddingLeft="15" fontWeight="bold"
width="70%">

<mx:Label text="Microphone Volume"/>

<mx:ProgressBar id="activityProgress" minimum="0"
maximum="100" mode="manual" label="" />

</mx:VBox> -->



<rtc:AudioPublisher id="audio" height="0" />







<mx:HBox width="100%" horizontalAlign="center">

<mx:Button id="btn" label="Start My Audio"
click="onAudioClick(event)" toggle="true" />

</mx:HBox>







<mx:Button label="AudioButt"

toggle="true" id="audioButt" color="#000000"

click="(audioButt.selected) ? audio.publish() :
audio.stop()"/>



































/**

* When a click starts the audio, it publishes the audio
through AudioPublisher.

* Another click stops the audio.

*/

private function onAudioClick(p_evt:MouseEvent):void

{

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

audio.publish();

p_evt.currentTarget.label = "Stop My Audio" ;

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

audio.stop();

p_evt.currentTarget.label = "Start My Audio" ;

}

}



/**

* Changes the gain by changing the gain slider value.

*/

private function onGainChange(event:Event):void

{

audio.gain = gainSlider.value ;

}

/**

* * Controls echo suppression through the use of radio
buttons.

*/

private function onItemClick(p_evt:ItemClickEvent):void

{

if ( p_evt.currentTarget.selectedValue == "Yes" ) {

audio.useEchoSuppression = true ;

}else if ( p_evt.currentTarget.selectedValue == "No" ) {

audio.useEchoSuppression = false ;

}

}





Thanks,



lionceau,

Avatar

Former Community Member
Hi,



As I said earlier also, I can't see AudioSubscriber in your
code. AudioSubscriber is the class that listens to the audio
streams and plays it. Until you add AudioSubscriber, you won't hear
any sound.



Moreover, you can't hear your own sound. You need to open two
instances of your app and then the second user can hear the sound
of first user when the first user is playing the sound.



Thanks

Hironmay Basu



You use this code

<mx:VBox width="40%" height="100%" right="0">

<mx:Button label="Déconnexion" click="logout()" />



<!-- scroll bar pourle volume -->

<mx:VBox paddingLeft="15" width="10%">

<mx:Label text="Gain" fontWeight="bold" />

<mx:HSlider id="gainSlider" minimum="0" maximum="100"
width="90%" value="{audio.gain}" labels="[0,50,100]"
change="onGainChange(event)" />

</mx:VBox>





<mx:VBox paddingLeft="15" fontWeight="bold"
width="70%">

<mx:Label text="UseEchoSuppression"/>

<mx:RadioButtonGroup id="echoGroup"
itemClick="onItemClick(event)" />

<mx:RadioButton label="Yes"
selected="{audio.useEchoSuppression}" groupName="echoGroup" />

<mx:RadioButton label="No"
selected="{!audio.useEchoSuppression}" groupName="echoGroup"/>

</mx:VBox>

<!--<mx:VBox paddingLeft="15" fontWeight="bold"
width="70%">

<mx:Label text="Microphone Volume"/>

<mx:ProgressBar id="activityProgress" minimum="0"
maximum="100" mode="manual" label="" />

</mx:VBox> -->



<rtc:AudioPublisher id="audio" height="0" />

<rtc:AudioSubscriber/>





<mx:HBox width="100%" horizontalAlign="center">

<mx:Button id="btn" label="Start My Audio"
click="onAudioClick(event)" toggle="true" />

</mx:HBox>







<mx:Button label="AudioButt"

toggle="true" id="audioButt" color="#000000"

click="(audioButt.selected) ? audio.publish() :
audio.stop()"/>



































/**

* When a click starts the audio, it publishes the audio
through AudioPublisher.

* Another click stops the audio.

*/

private function onAudioClick(p_evt:MouseEvent):void

{

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

audio.publish();

p_evt.currentTarget.label = "Stop My Audio" ;

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

audio.stop();

p_evt.currentTarget.label = "Start My Audio" ;

}

}



/**

* Changes the gain by changing the gain slider value.

*/

private function onGainChange(event:Event):void

{

audio.gain = gainSlider.value ;

}

/**

* * Controls echo suppression through the use of radio
buttons.

*/

private function onItemClick(p_evt:ItemClickEvent):void

{

if ( p_evt.currentTarget.selectedValue == "Yes" ) {

audio.useEchoSuppression = true ;

}else if ( p_evt.currentTarget.selectedValue == "No" ) {

audio.useEchoSuppression = false ;

}

}

Avatar

Level 2
yes i forget this , i search more but your source have a bug
, i don(t have sound .with this code :



<mx:VBox width="40%" height="100%" right="0">

<mx:Button label="Déconnexion" click="logout()" />



<!-- scroll bar pourle volume -->

<mx:VBox paddingLeft="15" width="10%">

<mx:Label text="Gain" fontWeight="bold" />

<mx:HSlider id="gainSlider" minimum="0" maximum="100"
width="90%" value="{audio.gain}" labels="[0,50,100]"
change="onGainChange(event)" />

</mx:VBox>





<mx:VBox paddingLeft="15" fontWeight="bold"
width="70%">

<mx:Label text="UseEchoSuppression"/>

<mx:RadioButtonGroup id="echoGroup"
itemClick="onItemClick(event)" />

<mx:RadioButton label="Yes"
selected="{audio.useEchoSuppression}" groupName="echoGroup" />

<mx:RadioButton label="No"
selected="{!audio.useEchoSuppression}" groupName="echoGroup"/>

</mx:VBox>

<!--<mx:VBox paddingLeft="15" fontWeight="bold"
width="70%">

<mx:Label text="Microphone Volume"/>

<mx:ProgressBar id="activityProgress" minimum="0"
maximum="100" mode="manual" label="" />

</mx:VBox> -->



<rtc:AudioPublisher id="audio" height="0" />

<rtc:AudioSubscriber/>





<mx:HBox width="100%" horizontalAlign="center">

<mx:Button id="btn" label="Start My Audio"
click="onAudioClick(event)" toggle="true" />

</mx:HBox>







<mx:Button label="AudioButt"

toggle="true" id="audioButt" color="#000000"

click="(audioButt.selected) ? audio.publish() :
audio.stop()"/>



































/**

* When a click starts the audio, it publishes the audio
through AudioPublisher.

* Another click stops the audio.

*/

private function onAudioClick(p_evt:MouseEvent):void

{

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

audio.publish();

p_evt.currentTarget.label = "Stop My Audio" ;

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

audio.stop();

p_evt.currentTarget.label = "Start My Audio" ;

}

}



/**

* Changes the gain by changing the gain slider value.

*/

private function onGainChange(event:Event):void

{

audio.gain = gainSlider.value ;

}

/**

* * Controls echo suppression through the use of radio
buttons.

*/

private function onItemClick(p_evt:ItemClickEvent):void

{

if ( p_evt.currentTarget.selectedValue == "Yes" ) {

audio.useEchoSuppression = true ;

}else if ( p_evt.currentTarget.selectedValue == "No" ) {

audio.useEchoSuppression = false ;

}

}

Avatar

Level 2
sorry i understand , You are the best.



thanks "Moreover, you can't hear your own sound. You need to
open two instances of your app and then the second user can hear
the sound of first user when the first user is playing the sound.

"



I just do it for all work well .





Many thanks for your answer !

I have other bug , my fileshare don't work well !





it is my source :



<rtc:FileShare id="fileManager" width="100%" height="20%"
/>







i see this in example " filepublisherexample" then i do it or
not ?











Avatar

Level 2
This code works. Of course you will need to publish both your
audio and webcamera publishers. Hope this helps.



<authentication:AdobeHSAuthenticator

id="auth"

authenticationSuccess="handleAuthenticateSuccess(event)"

authenticationFailure="handleAuthenticateFailure(event)"

userName="{Application.application.user.userName}"

password="{Application.application.user.password}" />





<session:ConnectSessionContainer id="cSession"
authenticator="{auth}"

roomURL="
http://connectnow.acrobat.com/yourroom"

backgroundColor="#404040"

width="100%" height="100%">



<pods:SharedWhiteBoard id="whiteboard"
connectSession="{cSession}" sharedID="webcamShare2"

width="400" height="400" popupShapesToolBar="true"

horizontalCenter="0" verticalCenter="0"/>



<collaboration:WebcamPublisher id="webCamPub" width="10"
height="5" quality="70"/>

<collaboration:AudioPublisher id="audioPub" height="0"
useEchoSuppression="true"/>



<!-- only listen to the subscribers we have selected
-->

<collaboration:AudioSubscriber id="audioSub"
publisherIDs="{audioIds}"/>



<mx:Tile id="camTiles"

direction="horizontal"

height="100%"

width="100%"

alpha="0"

horizontalScrollPolicy="off"

verticalScrollPolicy="off"

creationComplete="onCreationComplete()"

horizontalGap="10" verticalGap="10">



<mx:Repeater id="rp" dataProvider="{selectedUsers}">



<components:ResizableCanvas id="rs" width="100%"
height="100%"

minHeight="200" minWidth="200"

backgroundAlpha=".5"

backgroundColor="gray"

cornerRadius="12"

borderStyle="solid"

horizontalScrollPolicy="off" verticalScrollPolicy="off">





<collaboration:WebcamSubscriber
webcamPublisher="{webCamPub}"

width="100%" height="100%"

publisherIDs="{[rp.currentItem.userID]}"
click="onClick(event)"

userBooted="onBooted(event)"
streamChange="onCameraPause(event)"/>

</components:ResizableCanvas>



</mx:Repeater>



</mx:Tile>



</session:ConnectSessionContainer>

Avatar

Level 2
yes i do it ,



but i have one bug , what? why?



this error :

Severity and Description Path Resource Location Creation Time
Id

The prefix "collaboration" for element
"collaboration:AudioSubscriber" is not bound.
videoconferencetest/src videoconferencetest.mxml line 203
1236014104440 13







lionceau,

Avatar

Level 2
but i do in my source this :

import com.adobe.rtc.collaboration.AudioSubscriber





then why i have always this bug?



Lionceau

Avatar

Former Community Member
Hi,



I am not sure running which code gives you the error. Can you
be more specific ?

Point to note is if you are not using our namespace
rtc:AudioSubscriber and instead using collaboration:AudioSubscriber
, you need to define in Application tag , xmlns:collaboration =
"com.adobe.rtc.collaboration.*"

And secondly , have you closed the tag for AudioSubscriber
correctly ? If with these , its not fixing, you can post what code
gives this error and I will take a look.

Avatar

Level 2
yes i use rtc:AudioSubscriber

Yes , it is right i forget this tags:

xmlns:collaboration = "com.adobe.rtc.collaboration.*" I





i have always a error ,



Severity and Description Path Resource Location Creation Time
Id

The prefix "components" for element
"components:ResizableCanvas" is not bound. videoconferencetest/src
videoconferencetest.mxml line 205 1236061436671 26









my source is :





<components:ResizableCanvas id="rs" width="100%"
height="100%"

minHeight="200" minWidth="200"

backgroundAlpha=".5"

backgroundColor="gray"

cornerRadius="12"

borderStyle="solid"

horizontalScrollPolicy="off" verticalScrollPolicy="off">





<collaboration:WebcamSubscriber
webcamPublisher="{webCamPub}"

width="100%" height="100%"

publisherIDs="{[rp.currentItem.userID]}"
click="onClick(event)"

userBooted="onBooted(event)"
streamChange="onCameraPause(event)"/>





</components:ResizableCanvas>











thanks,



Lionceau,



Avatar

Level 2
more over i have yet this :

import mx.core.UIComponent;



why i have this error ?



Lionceau,

Avatar

Former Community Member
Hi,



Have you added the components namespace in your application
tag like you did for collaboration. for e.g. if ResizableCanvas is
in the same directory as your source you should add in application
tag xmlns:components="*" and so on.



Hope this helps



Thanks

Hironmay Basu

Avatar

Level 2
hi ,



yes , good but i have another error why? :



Severity and Description Path Resource Location Creation Time
Id

Could not resolve <components:ResizableCanvas> to a
component implementation. videoconferencetest/src
videoconferencetest.mxml Unknown 1236066263500 61











thanks ,



lionceau,

Avatar

Former Community Member
Hi,



You are getting this error since it is not able to find the
ResizableCanvas class in the components namespace. What have you
defined the components namespace in application tag and is the file
ResizeableCanvas in the same folder components namespace points to
?



Thanks

Hironmay Basu

Avatar

Level 2
look it , this is my surce :

It is my déclaratin and tag :





<mx:Application layout="absolute"

xmlns:mx="
http://www.adobe.com/2006/mxml"

xmlns:rtc="AfcsNameSpace"

xmlns:collaboration = "com.adobe.rtc.collaboration.*"

xmlns:components="*"

>

<!-- cette partie du code es là plus interessante
car elle sert à capter le moment où notre application est
connectée et synchronisée, nous pouvons ajouter un
écouteur d’événement
SessionEvent.SYNCHRONIZATION_CHANGE sur le container, et surveiller
sa propriété ‘isSynchronized‘. Nous
reviendrons prochainement sur les différents aspects et
acteurs en jeu lors de cette synchronisation. -->



<mx:Script>

<![CDATA[

import mx.controls.Alert;



import com.adobe.rtc.events.SessionEvent; //utilisé
pour les trois blocs

import com.adobe.rtc.messaging.UserRoles; //utilisé
pour les trois blocs

import com.adobe.rtc.collaboration.AudioPublisher; //
AudioPublisher me sert pour la gestion du microphone

import com.adobe.rtc.collaboration.AudioSubscriber; // me
sert pour choisr l' aboné écouté

//import com.adobe.rtc.collaboration; // me sert pour la
gestion du microphone

//import com.adobe.rtc.clientManagers;// me sert pour la
gestion du microphone





import com.adobe.rtc.events.StreamEvent;// pour le son
(audio xml)







import mx.events.ItemClickEvent; //pour le son ( audio xml)

import mx.controls.Label;

import mx.core.UIComponent; // me sert pour la gestion du
microphone

import flash.events.EventDispatcher;// me sert pour la
gestion du microphone

// import com.adobe.rtc.components:ResizableCanvas; amettre?






//debut bloc share

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

import mx.utils.UIDUtil;

import mx.collections.ArrayCollection;

import com.adobe.rtc.collaboration.FileSubscriber;

import com.adobe.rtc.sharedManagers.UserManager;

import com.adobe.rtc.messaging.NodeConfiguration;

import com.adobe.rtc.events.CollectionNodeEvent;

import com.adobe.rtc.collaboration.FilePublisher;

import com.adobe.rtc.sharedManagers.FileManager;



[Bindable]

private var applicationTitle:String = "File Publisher
Example";



// list of managers

private var _fileManager:FileManager;

private var _filePublisher:FilePublisher;

private var _fileSubscriber:FileSubscriber;

private var _userManager:UserManager;



// our datagrid dataprovider will use this collection

[Bindable]

private var _fileDescriptors:ArrayCollection = new
ArrayCollection();



// file sharing group id, it is similiar to that of folder
concept

private var _groupid:String = "_filePublisherExample";

//fin bloc share



// état de la session

private var isConnected:Boolean = false;

private var activityTimer:Timer = new Timer(30,1);







what i forget?



Lionceau,