Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.
SOLVED

Video with 4.5.1 on iOS

Avatar

Level 3

Has anyone been able to get video feeds to work on 4.5.1 pre-release build on iOS?  I had this working with the 4.5 version, but, no changes in the app, and, it doesn't display in 4.5.1 on iOS. 

Publishing video with 4.5.1 on iOS works fine.

Thanks,

David

1 Accepted Solution

Avatar

Correct answer by
Former Community Member

Wow, interesting, and thanks for the update David. What makes this

especially poignant/spooky is that VideoComponent was actually the class

that had the one-line change that fixes the "ratcheting" issue described

here : http://forums.adobe.com/thread/855843?tstart=0 . It's literally the

first time the class has been touched in 2 years, and it's been in the

middle of 2 weird issues over the same 3 days. Next I suppose we'll discover

it's somehow involved in the issues some folks are reporting with Echo

Cancellation ;-).

thanks again for the diligent reporting - all information helps. And I'll

take you up on that offer at MAX, provided I get to buy the 2nd round =).

cheers,

nigel

View solution in original post

22 Replies

Avatar

Level 3

Here's my view code, if anyone's interested.  The connection session is passed on the open, i.e.

navigator.pushView(VideoAFCSMobile, cSession)

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


<s:View


xmlns:fx="http://ns.adobe.com/mxml/2009"

xmlns:s="library://ns.adobe.com/flex/spark"

xmlns:rtc="http://ns.adobe.com/rtc"

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

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

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

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

xmlns:afcs="com.ssc.components.thirdparty.afcs.*"

viewActivate="onViewActivate()"

creationComplete="view2_creationCompleteHandler(event)"

viewDeactivate="view2_viewDeactivateHandler(event)"

tabBarVisible="false">


<fx:Declarations>

<session:ConnectSession id="connectSession" />

<collaboration:AudioPublisher id="audioPub" connectSession="{this.data}" useEchoSuppression="true"/>

<collaboration:AudioSubscriber id="audioSub" connectSession="{this.data}" />

</fx:Declarations>

<fx:Script>

<![CDATA[

import com.adobe.coreUI.controls.VideoComponent;

import com.adobe.rtc.collaboration.WebcamPublisher;

import com.adobe.rtc.collaboration.WebcamSubscriber;

import com.adobe.rtc.events.SessionEvent;

import com.adobe.rtc.session.ConnectSession;

import com.adobe.rtc.session.IConnectSession;

import com.adobe.rtc.sharedManagers.UserManager;

import com.ssc.components.generic.events.*;

import com.ssc.model.AppModel;


import flash.media.Camera;


import mx.core.IVisualElement;

import mx.events.FlexEvent;


import spark.events.ViewNavigatorEvent;

import spark.transitions.SlideViewTransition;

[


Bindable]

public var model:AppModel = AppModel.getInstance();

[Bindable]

override public function set data(obj:Object):void{

model.logger.debug("VideoAFCSMobile: setting data");

if (obj is IConnectSession) {

model.logger.debug("VideoAFCSMobile: setting data to IConnectSession.");

connectSession = obj as ConnectSession;//super.data = obj;

}

}

override public function get data():Object{

return connectSession;

}

private function broadcastSync(event:SessionEvent):void{

this.dispatchEvent(event);


}


private function recordVideo(event:Event):void{

var evt:CollaborationEvent = new CollaborationEvent(CollaborationEvent.RECORD_VIDEO);

this.dispatchEvent(evt);

}


protected function view1_creationCompleteHandler(event:FlexEvent):void

{


}


protected function onViewActivate():void

{

model.logger.debug(


"VideoAFCSMobile: onViewActivate");

connectSession.addEventListener(SessionEvent.SYNCHRONIZATION_CHANGE, onSynchronizationChange);

tranLeft.direction="right";


}


protected function onSynchronizationChange(event:SessionEvent):void

{


model.logger.debug("VideoAFCSMobile: onSynchronizationChange");


if (connectSession.isSynchronized) {


webcamSub.subscribe();

audioSub.subscribe();


webcamSub.width = width;

webcamSub.height = height

webcamSub.webcamPublisher = webcamPub;

camera.addChild(webcamSub);

if (!webcamPub.isPublishing) {

frontCameraBtn.enabled=true;

backCameraBtn.enabled=true;

} else {

frontCameraBtn.enabled=false;

backCameraBtn.enabled=false;

}

} else {

connectSession.removeEventListener(SessionEvent.SYNCHRONIZATION_CHANGE, onSynchronizationChange);

}

}


protected function logout(event:MouseEvent):void

{

//Stop video

if (webcamPub.isPublishing) {

webcamPub.stop();

//webcamPub.close();

}

// Stop audio

if (audioPub.isPublishing) {

audioPub.stop();

}

frontCameraBtn.enabled=true;

backCameraBtn.enabled=true;

}


protected function login(cameraIdx:String):void

{

var l:int = Camera.names.length;

for (var i:int=0; i<l; i++) {

model.logger.debug("Camera (" + i + ") found:" + Camera.names[i]);

}


if (!webcamPub.isPublishing) {

webcamPub.cameraNameIndex=cameraIdx;

model.logger.debug("Using Camera:" + cameraIdx );// + webcamPub.camera.name);

webcamPub.subscribe();

webcamPub.publish();

webcamSub.width= width;

webcamSub.height= height;

//webcamSub.webcamPublisher = webcamPub;

camera.addChild(webcamSub);

//camera.setLayoutBoundsSize(camera.width,camera.height);


if (!audioPub.isPublishing) {

audioPub.subscribe();

audioPub.publish();

}

}

frontCameraBtn.enabled=false;

backCameraBtn.enabled=false;


}


protected function view2_creationCompleteHandler(event:FlexEvent):void

{

systemManager.stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGE, orientationChangeHandler);

webcamPub = new WebcamPublisher();

webcamSub = new WebcamSubscriber();

webcamPub.connectSession = this.connectSession;

webcamSub.connectSession = this.connectSession;

onSynchronizationChange(null);

}


public function orientationChangeHandler(event:StageOrientationEvent):void {

if (camera && camera.getChildAt(0)) {

camera.removeChild(webcamSub);

camera.addChild(webcamSub);

}

}


protected function view2_viewDeactivateHandler(event:ViewNavigatorEvent):void

{

// TODO Auto-generated method stub


}


]]>

</fx:Script>


<s:states>

  <s:State name="portrait"/>

  <s:State name="landscape"/>
</s:states>

<s:Group id="cameraHolder" width="100%" height="100%">

  <s:SpriteVisualElement visible.landscape="true" visible.portrait="true" id="camera" x="0" y="0" width="100%" height="100%"

top="0" bottom="0" right="0" left="0" />


  <s:HGroup bottom="20" height="80" visible.landscape="false" visible.portrait="true" width="100%" horizontalAlign="center">

     <s:Button label="Front" id="frontCameraBtn" enabled="{webcamPub.isPublishing}" click="login('1')" width="33%" horizontalCenter="1"/>

     <s:Button label="Back" id="backCameraBtn" enabled="{webcamPub.isPublishing}" click="login('0')" width="33%" horizontalCenter="1"/>

     <s:Button label="End" id="endCameraBtn" click="logout(event)" enabled="{!(frontCameraBtn.enabled || backCameraBtn.enabled)}" width="33%" horizontalCenter="1"/>

  </s:HGroup>
</s:Group>


<s:titleContent>

  <s:Label width="100%" styleName="titleContentTextStyle" text="Video" maxDisplayedLines="2"/>

</s:titleContent>


<s:navigationContent>

  <s:Button id="logoButton" label="Back" click="this.navigator.popView(tranLeft)"/>
</s:navigationContent>

</s:View>

Avatar

Level 3

Just tested with the new 4.5.1 drop 2, no change, still doesn't work for me.

Can someone confirm this code is valid and doesn't work with the new FB 4.5.1 SDK?  I'm sure you guys have access to it.  If video doesn't work with 4.5.1, really would like to get a bug filed to fix it.

Thank you.

David

Avatar

Level 3

Does not work with 4.5.1 Drop 4 either.  This will be released soon...can someone PLEASE help with this?

Avatar

Employee

I have tied the camera (with a non LCCS app) and verified it works. Today I'll see if I can try an LCCS app.

Avatar

Former Community Member

Hi David,

Very sorry for keeping you hanging like this - I'm working my way to

someone on the Flex/AIR Packager/Runtime team right now to try to get some

answers on this.

Thanks again for your patience, and for bumping this up in the thread

(unfortunately, sometimes that's what it takes) - I'm on it.

nigel

Avatar

Former Community Member

Hi David,

Could you clarify where the video in question is coming from? A webcam,

clearly - but where? On a desktop, on a 2nd phone, or from the same phone?

thanks

nigel

Avatar

Level 3

I've tried broadcasting the video from a desktop and another phone, it doesn't display.

Also, it won't even display from the mobile iphone emulator from FlashBuilder (either the outgoing video or any incoming streams).

Avatar

Employee

Ok, I have tried and it works

I am currently using FlashBuilder with Flex 4.5.1 as following (Eclipse keeps telling me that is FlashBuilder 4.5 but the SDK is definitively 4.5.1).

<flex-sdk-description>

<name>Flex 4.5.1</name>
<version>4.5.1</version>
<build>21245</build>
</flex-sdk-description>
This is my test application (file attached). I tried with the latest LCCS SDK (1.5) and the FlashOnly SWC for Player 10.0 (actually I forgot to try with RTMFP, that I will try right now).
Please try this against one of your rooms and let us know what happens. If it still doesn't work for you at least we have a common place to start working on.

Avatar

Employee

And I have now also tested with FB 4.5.1 Prerelease Drop 2 (that should have a build number for the SDK of 4.5.1.21309) and it works there too.

My publisher is publishing from inside our firewall (so it's using RTMPS) but my iPhone was actually connected via RTMFP to the guest network, so that also excludes RTMFP as the source of the problem.

Again, please try my example and let me know how it works for you.

Avatar

Level 3

Raff:

That's awesome news that you got it working, I'll try with your code...can you try my simple View also?  It was posted earlier.  You just need to pass the connectsession on the open, i.e. navigator.pushView(VideoAFCSMobile, myCsession );

Thanks,

David

Avatar

Level 3

Raff:

I ran your code against my room, worked fine.

But, I copied your code into a new View component in my app (all of mine open View(s)), and did navigator.pushView(YourVideoCodeView) and it doesn't work.

The last few lines of the logs are:

19:26:07 GMT-0400    checkManagerSync:[object UserManager]
session synchronized
streamReceive: 390E31EF-F620-7607-5F29-7BE09375029B
streamReceive: 390E31EF-F620-7607-5F29-7BE09375029B
19:26:21 GMT-0400     Peer to peer connection failed and timed out in Camera for user iPhone

I'm sending the video stream from the same machine (using my desktop app for this room that works everywhere else and from where I tested your code successfully).

I'm not forcing p2p, so, not sure why it's trying and failing on p2p.  Seems it should at least fall back to non-p2p.  Anyway...not sure what else to do at this point, any suggestions?

I can send you my full source privately if you think this will help.

Did you get my View component to work in your project?

Thanks,

David

Avatar

Employee

Sorry, didn't had a chance to try your View component, but I will try that and/or change my app to use a view.

If that fails I think we'll have to pass the ball to the FlashPlayer team, but at least we will have some good information to give them.

Anyway, I am wondering if something is happening related to the view getting activated and/or deactivated. I have an application, that works on Android, where ended up doing my ConnectSession.login in the onViewActivate callback, but I also didn't try that on the iPhone.

I am not sure about the p2p message, but we'll look into it. In my case the iPhone was connecting via RTMFP but my Desktop was connected via RTMPS so for sure I didn't had any p2p message involved.

Avatar

Employee

David, I got a little overwelmed by your full app, and right now I really don't have time to figure out what is wrong with it.

As I said in another post (related to iOS front facing camera), there may be something related to the view activation code that somehow breaks netConnections but right now I don't have the time to investigate it (specially since I start suspecting is related to a FlashPlayer or Flex runtime bug).

My suggestion is to build a complete application with a view and the webcam (that is less than your full blown application but more than just the view ). If that reproduce the problem we can give it one more try here and pass it to the the appropriate team (or you can try posting on the other forums where they are discussing similar problems).

Avatar

Level 3

Raff:

I cannot reproduce the problem with a simple view and using the front camera.  It works fine.  That's the issue, I don't see why this isn't displaying any video because it's basically the same approach on both, as far as I can tell.

I know it's a large app, but, it still boils down to opening a View and displaying a video stream.  I thought you might have better debugging tools to see exactly what the stream is doing and why it's not displaying.

I certainly understand you have have limited amounts of time to concentrate on an issue, but, I'm not sure what I can do now.  I've posted this on the Pre-Release forum a couple of weeks ago (no response), what other options are there?

Sorry, a little frustrated,

David

Message was edited by: David_Welch (corrected:  "I know it's a large app, but, it still boils down to opening a View and displaying a video stream. "

Avatar

Employee

I tried one more thing: a simple app with a tabbed view, and I saw a couple of things:

- views seem to be disposed and recreated on viewDeactivate / viewActivate (if I print the view instance in the viewActivate handler I get different values every time). I think this is documented but it's easy to forget.

- when the view with the camera gets deactivated the webcamsubscriber component somehow gets deactivated too (maybe it "unsubscribe" from the stream when the SpriteVisualElement gets released

I got my application to work by doing a SpriteVisualElement.removeChild(webcamsub) on viewDeactivate and SpriteVisualElement.addChild(webcamerasub) AND webcamsub.subscribe() on viewActivate (again, all this while storing the ConnectSession in an external singleton, like your application does).

Not sure of what else needs to be done for the webcam publisher but you'll probably need to "re-establish" all the connections (same for audiopublisher and audiosubscriber)

Avatar

Former Community Member

To be clear, David - it's the Flex pre-release that you posted to with no

response?

nigel

Avatar

Level 3

Hi Nigel:

Yes, the Pre-Release 4.5 forums, sorry I wasn't clear...here's post, subject "Video using LCCS not displaying":

https://prerelease.adobe.com/project/forum/thread.html?cap=B4DD6EBA22D848AFBD7E0C95BD5EAE0C&forid={6...}

I'll try doing some re-establising the connection on ViewActivate, but, I'm pretty sure I'll get duplicate connections to LCCS.  Might be interesting if it displays the video though.

If I seem to be a pain about this, it's probably because I'm demoing my product for your partner channel folks tomorrow, I would really like to show them the video to mobile devices works in our product!  

Thanks,

David

Message was edited by: David_Welch  (changed "works" to "works in our product")

Avatar

Employee

I am attaching my View for the webcam subscriber. I tried to apply my changes to your application but I am not sure of when/how to get the webcam publisher to "publish" (in my app I actually have a completely separate desktop app that publish the camera stream so in the mobile app I concentrate only on the webcam subscriber).

All I am doing is to make sure that on viewActivate I add the webcam subscriber to the "sprite container" and subscribe. On viewDeactivate I remove the camera. I also add/remove a couple of events to display some debug messages.

Avatar

Level 3

Raff/Nigel:

Okay, I found the issue, and, it makes absolutely no sense to me...but, here goes...

My project contained a copy of the com.adobe.coreUI.controls.VideoComponent from the 10.1 source branch of LCCS.  It contained no changes, I suppose it was copied there with the intent of modifying it, but, it's exactly the same code as the one that is delivered in this months release source directory under Flash/10.1. 

When I remove this class from the project, my original code works fine and displays video, either from another source or from publishing.  It works in the emulator and on the iPhone.  Fairly numb right now, as I've spent way too many hours looking at this...

Thanks for all your assistance and time in helping me get to the bottom of this...maybe sometime I'll see why this caused an issue (or maybe you guys do), but, for now, all that's important now is that it's working.

Again, thanks for persisting with me on trying to find the solution...if I see you at Max I'm buying!

Thanks,

David

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] ----