7 Replies Latest reply on Mar 10, 2009 8:51 AM by yohann.martineau

    addChild in application ok, addChild in custom component ko

    yohann.martineau
      hello,

      well, I'm new to flex and flash applications...

      I'm trying to add a Video object to my flex application dynamically.

      I'm not using VideoDisplay object because I want to play a stream coming from a streaming server, not a flat flv file. Maybe this should also work with a streaming server? I've tried to set source property on VideoDisplay, but this gave no result.

      I've tried to do this with a Video object in a simple application and it worked almost perfectly. I only have one problem about layout: my video is added on the right side of the application. It seems that flash player takes the middle of the application to insert the video and then draws the video on the right. It's not centered. Actually it's not my main problem, I think I could fix it using styles or something like that.

      PlayerApplication.mxml


      <?xml version="1.0"?>
      <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml">
      <mx:Script source="testVideo.as"/>
      <mx:Label text="rtmp url"/>
      <mx:TextInput id="rtmpUrl" text="rtmp://localhost/nexpressoflash"/>
      <mx:Label text="video name"/>
      <mx:TextInput id="videoName" text="vid_"/>
      <mx:Button label="Start" click="testVideo()"/>
      <mx:Text id="debugText"/>
      </mx:Application>



      testVideo.as


      import flash.display.Sprite;
      import flash.events.*;
      import flash.media.Video;
      import flash.net.NetConnection;
      import flash.net.NetStream;
      import mx.core.UIComponent;

      private var netConnection:NetConnection;

      public function testVideo():void {
      log("testVideo");
      netConnection = new NetConnection();
      netConnection.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
      netConnection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
      netConnection.connect(rtmpUrl.text);
      }

      private function netStatusHandler(event:NetStatusEvent):void {
      log("netStatusHandler " + event.info.code + " " + event.info.level);
      switch (event.info.code) {
      case "NetConnection.Connect.Success":
      connectStream();
      break;
      case "NetStream.Play.StreamNotFound":
      log("Unable to locate video: " + videoName.text);
      break;
      }
      }

      private function connectStream():void {
      log("connectStream");
      var netStream:NetStream = new NetStream(netConnection);
      netStream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
      netStream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
      var video:Video = new Video();
      video.attachNetStream(netStream);
      netStream.play(videoName.text);
      var uiComponent:UIComponent = new UIComponent();
      uiComponent.addChild(video);
      addChild(uiComponent);
      }

      private function securityErrorHandler(event:SecurityErrorEvent):void {
      trace("securityErrorHandler: " + event);
      }

      private function asyncErrorHandler(event:AsyncErrorEvent):void {
      // ignore AsyncErrorEvent events.
      }

      private function log(message:String):void {
      var date:Date = new Date();
      debugText.text += "[" + date + " " + date.milliseconds + "] " + message + "\n";
      }



      Here, Video object is added to a UIComponent which is then added to main Application.

      I've tried to do this in my real application and it failed (I can't see my video). In my real application, I have a main Application which contains only one component MyCustomComponent. This custom component includes a "static" script which manages the Video and UIComponent (methods copied from testVideo.as). My custom component inherits Box (it's not an application itself) and uses view states. I think this problem may come from view states. I think application layout/render process is managed differently when view states are employed. In this case, Video is added to UIComponent and UIComponent is added to MyCustomComponent (i.e. Box) which is in application... but it doesn't work.

      I've tried to add my UIComponent directly in main Application using:

      mx.core.Application.application.addChild(uiComponent);

      but it didn't work.

      Honestly, I have no more ideas...

      maybe someone can help?

      Thank you,

      yohann
        • 1. Re: addChild in application ok, addChild in custom component ko
          Level 7

          "yohann.martineau" <webforumsuser@macromedia.com> wrote in message
          news:gorn2q$aqa$1@forums.macromedia.com...

          > I've tried to add my UIComponent directly in main Application using:
          >
          > mx.core.Application.application.addChild(uiComponent);
          >
          > but it didn't work.

          Two things:

          mx.core.Application.application is a Class, and thus you can't add things to
          it. The good news is, if you do this:

          addChild(myThing);

          from a script tag in your main Application mxml file, you will get that
          thing added to the instance of the Application class that you're trying to
          add to.

          Second, once you do add a UIComponent, it doesn't automatically lay itself
          out. Try

          myThing.setActualSize(myThing.measuredWidth, myThing.measuredHeight);

          HTH;

          Amy


          • 2. Re: addChild in application ok, addChild in custom component ko
            yohann.martineau Level 1
            oh my god... it works!

            let me tell you: you're a flash divinity!

            I should have subscribed to this forum earlier...

            Well, actually I still have one problem: my video is really small, maybe 10x10 or something like that. I thought it was due to a default value, but I've tried to set this "actual" size with hardcoded values of 160x120, but it was still small.

            When I display video size, it seems to be 0x0:

            video = new Video();
            video.attachNetStream(videoInputNetStream);
            videoInputNetStream.play(videoInputNetStreamName);
            var uiComponent:UIComponent = new UIComponent();
            uiComponent.addChild(video);
            log("videoWidth: " + video.videoWidth);
            log("videoHeight: " + video.videoHeight);
            uiComponent.setActualSize(uiComponent.measuredWidth,
            uiComponent.measuredHeight);
            myCustomComponent.addChild(uiComponent);

            gives:

            [Mon Mar 9 10:57:07 GMT+0100 2009 937] 0 videoWidth: 0
            [Mon Mar 9 10:57:07 GMT+0100 2009 937] 0 videoHeight: 0

            I've tried to provide a custom client object to my netstream to invoke onCuePoint, but it didn't work, my method was never invoked. I wanted to make my UIComponent bigger when the first keyframe was received or something like that.

            I've tried to display the size of my video regularly and it becomes 320x240, which seems more reasonable. The problem is that my video remains small (10x10). I've tried to use setActualSize. I've also tried to set width and height or minWidth and minHeight properties on my UIComponent, but without success.

            Actually I'm really new to custom components with flex, is there a place where I can find details about custom components implementation? I've tried adobe developer's guide and "create components" but it didn't help that much for this kind of activity...

            Thanks a lot,

            yohann
            • 3. Re: addChild in application ok, addChild in custom component ko
              Level 7

              "yohann.martineau" <webforumsuser@macromedia.com> wrote in message
              news:gp3621$kt8$1@forums.macromedia.com...
              > oh my god... it works!
              >
              > let me tell you: you're a flash divinity!
              >
              > I should have subscribed to this forum earlier...
              >
              > Well, actually I still have one problem: my video is really small, maybe
              > 10x10
              > or something like that. I thought it was due to a default value, but I've
              > tried
              > to set this "actual" size with hardcoded values of 160x120, but it was
              > still
              > small.
              >
              > When I display video size, it seems to be 0x0:
              >
              > video = new Video();
              > video.attachNetStream(videoInputNetStream);
              > videoInputNetStream.play(videoInputNetStreamName);
              > var uiComponent:UIComponent = new UIComponent();
              > uiComponent.addChild(video);
              > log("videoWidth: " + video.videoWidth);
              > log("videoHeight: " + video.videoHeight);
              > uiComponent.setActualSize(uiComponent.measuredWidth,
              > uiComponent.measuredHeight);
              > myCustomComponent.addChild(uiComponent);
              >
              > gives:
              >
              > [Mon Mar 9 10:57:07 GMT+0100 2009 937] 0 videoWidth: 0
              > [Mon Mar 9 10:57:07 GMT+0100 2009 937] 0 videoHeight: 0
              >
              > I've tried to provide a custom client object to my netstream to invoke
              > onCuePoint, but it didn't work, my method was never invoked. I wanted to
              > make
              > my UIComponent bigger when the first keyframe was received or something
              > like
              > that.
              >
              > I've tried to display the size of my video regularly and it becomes
              > 320x240,
              > which seems more reasonable. The problem is that my video remains small
              > (10x10). I've tried to use setActualSize. I've also tried to set width and
              > height or minWidth and minHeight properties on my UIComponent, but without
              > success.
              >
              > Actually I'm really new to custom components with flex, is there a place
              > where
              > I can find details about custom components implementation? I've tried
              > adobe
              > developer's guide and "create components" but it didn't help that much for
              > this
              > kind of activity...

              Wait until whatever event fires that tells you that component is loaded (for
              many this is updateComplete), then do the setActualSize.

              HTH;

              Amy


              • 4. Re: addChild in application ok, addChild in custom component ko
                yohann.martineau Level 1
                here is what I've tried in my action script class:

                private var videoContainer:UIComponent;

                public function startMedia():void {
                [...]
                var video:Video = new Video();
                video.attachNetStream(videoInputNetStream);
                videoInputNetStream.play(videoInputNetStreamName);
                videoContainer = new UIComponent();
                videoContainer.addEventListener(FlexEvent.UPDATE_COMPLETE, updateComplete);
                videoContainer.addChild(video);
                myCustomComponent.addChild(videoContainer);

                }

                public function updateComplete(flexEvent:FlexEvent):void {
                log("updateComplete");
                videoContainer.setActualSize(videoContainer.measuredWidth,
                videoContainer.measuredHeight);
                }


                but it didn't work. I've also tried several other combinations. Do you think I should add my event listener on my custom component instead of video container?

                Thank you,

                yohann
                • 5. Re: addChild in application ok, addChild in custom component ko
                  Level 7

                  "yohann.martineau" <webforumsuser@macromedia.com> wrote in message
                  news:gp3nin$cd7$1@forums.macromedia.com...
                  > here is what I've tried in my action script class:
                  >
                  > private var videoContainer:UIComponent;
                  >
                  > public function startMedia():void {
                  > [...]
                  > var video:Video = new Video();
                  > video.attachNetStream(videoInputNetStream);
                  > videoInputNetStream.play(videoInputNetStreamName);
                  > videoContainer = new UIComponent();
                  > videoContainer.addEventListener(FlexEvent.UPDATE_COMPLETE,
                  > updateComplete);
                  > videoContainer.addChild(video);
                  > myCustomComponent.addChild(videoContainer);
                  >
                  > }
                  >
                  > public function updateComplete(flexEvent:FlexEvent):void {
                  > log("updateComplete");
                  > videoContainer.setActualSize(videoContainer.measuredWidth,
                  > videoContainer.measuredHeight);
                  > }
                  >
                  >
                  > but it didn't work. I've also tried several other combinations. Do you
                  > think I
                  > should add my event listener on my custom component instead of video
                  > container?

                  I'd add it to the Video component. And I'd check the docs to see what event
                  this component dispatches once it's loaded. I was just suggesting
                  updateComplete off the top of my head, pending a check of the docs (which I
                  expected you to do).


                  • 6. Re: addChild in application ok, addChild in custom component ko
                    yohann.martineau Level 1
                    yes, actually that's what I've done first (that's right, I should have mentioned it in my previous post). I've been looking in flex reference, and it seems that Video object has no specific event. I've tried to use "added" event and setting width and height on Video object. Video object is not a UIComponent, it's just a DisplayObject, so setActualSize and measured{Width,Height} are not available.

                    Thank you for your support,

                    yoahnn
                    • 7. Re: addChild in application ok, addChild in custom component ko
                      yohann.martineau Level 1
                      I think I've almost fixed it:

                      I've added a listener on "added" event on my Video object, then when this event fires, I set width and height properties with hardcoded values (which corresponds to default video width and height): 320x240. Then I update the container with setActualSize(measuredWidth, meseauredHeight) and it works. My Video is not center aligned, but at least I can see it!!
                      The trick was to use a UIComponent which is already present in my custom component which is implemented with states. The videoContainer I've added is always present in all states, but that's working.

                      Thank you very much.