11 Replies Latest reply on Jan 16, 2007 8:43 PM by weiwuliang

    Loading FLVs Dynamically in Flex

    rica_help
      Hi, All:

      Seven days on this problem, and I can't solve it.

      I'm trying to build a very rudimentary flex / fms video player with a selectable combobox (xml-driven is next). I have had some success with the code below. It works pretty well with either progressive or rtmp, but there are two big annoyances.

      First, when I push the play button on the videoDisplay without selecting an item from the combo box when the app first starts, I get a flex error 1000:no bitrate. Is there a way to trick the combo box into thinking the first item has been selected? Autoplay true or false on the videoDisplay has no effect on this problem (no surprise). I have tried everything that I can think of, from a custom combobox to the solution found here:

      selectComboValue(myComboBox, dataObj.fieldName.toUpperCase());
      ==
      public function selectComboValue(select: mx.controls.ComboBox, optionToSelect:String):void{
      for (var i:int = 0; i < select.dataProvider.length ; i++) {
      if (select.dataProvider.getItemAt().label == optionToSelect){
      select.selectedIndex = i;
      break;
      }
      }
      }

      Nothing seems to work for me.

      The second problem is with rtmp. Sometimes rtmp streams will play over one another or will not unload when I click the stop button. I've tried both stop() and close(). Nothing works. I can see on my FMS manager that the streams are not disconnecting. I've followed the information in the live docs, but I can't find the solution. Is this a bug??

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

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

      <mx:Script>
      <![CDATA[
      //start video array
      [Bindable]
      public var vids: Array =[
      {label:"Select Item", data:null},
      {label:"Video Two", data:2},
      {label:"Video Three", data:3},
      {label:"Video Four", data:4},
      {label:"Video Five", data:5},
      {label:"Video Six", data:6}
      ];
      //end video array
      [Bindable]
      public var selectedItem:Object;
      ]]>
      </mx:Script>


      <mx:Panel title="Select Video from List Below to Begin"
      height="95%" width="75%"
      layout="horizontal"
      paddingTop="10" paddingBottom="10"
      paddingLeft="10" paddingRight="10">

      <mx:ComboBox dataProvider="{vids}" width="250"
      close="selectedItem=ComboBox
      (event.target).selectedItem"/>

      <mx:HBox width="100%" height= "30">
      <mx:Text width="150" color="blue" text=""
      height="20"/>
      <mx:Label text="You selected:
      {selectedItem.label}"/>
      <mx:Label text="Trace: {selectedItem.data}.flv"/>
      </mx:HBox>

      </mx:Panel>



      <mx:Panel title="Video Player" height="75%" width="75%"
      layout="vertical"
      horizontalAlign="center"
      paddingTop="10" paddingLeft="10" paddingRight="10"
      paddingBottom="10">
      <mx:Text width="75%" color="blue"/>



      <mx:VideoDisplay id="myVid1" height="400" width="600"
      autoBandWidthDetection="false"
      source="videosource/{selectedItem.data}.flv"
      autoPlay="true" live="false"/>

      <mx:HBox>
      <mx:Button label="Play" click="myVid1.play();"/>
      <mx:Button label="Pause" click="myVid1.pause();"/>
      <mx:Button label="Stop" click="myVid1.stop();"/>
      </mx:HBox>



      </mx:Panel>
      </mx:Application>
        • 1. Re: Loading FLVs Dynamically in Flex
          Level 1
          if you want to have a default selection for your combo box, you can add the following parameters to your ComboBox:

          <mx:ComboBox
          id="videoChoice"
          dataProvider="{vids}"
          width="250"
          creationComplete="videoChoice.selectedIndex(1);" />

          However, I suspect you want to force the user to choose a selection from the combo box before they play a video. Use a Validator class (like a NumberValidator on the selectedIndex of the combo box) to check before playing the video. Also, the prompt property of the combo box would be best for your "select Item selection - just make sure to set the selectedIndex to -1, or the prompt will not show up.

          As for your rtmp stream. I've never used it before, but from the language reference ( http://livedocs.macromedia.com/flex/2/langref/index.html) it says that the stop() method of theVideoDisplay only stops the playback. Not the input stream. It appears that close() will stop the input stream - you may want to research this futher ( and tell us how it all goes).

          Good Luck!

          --Andy
          • 2. Loading FLVs Dynamically in Flex
            rica_help Level 1
            Thank you for the reply, Andy. Unfortunately, it throws this error:

            1195: Attempted access of inaccessible method selectedIndex through a reference with static type mx.controls:ComboBox.

            Was creationComplete removed from Flex 2.0 after the Beta?

            I must be doing something wrong. The agony.

            • 3. Re: Loading FLVs Dynamically in Flex
              Hugo_Core
              Hi Rica,

              This Help ? :

              <mx:ComboBox
              dataProvider="{vids}" width="250"
              selectedIndex="1"
              close="selectedItem=ComboBox
              (event.target).selectedItem"/>

              - I make the default item to your frist video, do you have some function to load the selected video Automatic on the initialize event ? Like a :

              <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" initialize="runDefaultVideo()">

              Regards, Core
              • 4. Loading FLVs Dynamically in Flex
                rica_help Level 1
                Hi, Core:

                The code almost helps. It "does" change the items in the combobox.

                However, I wasn't clear with my question/problem statement. Somehow, I have got to have the first video (1.flv) sent to source="videosource/{selectedItem.data}.flv" path in the videoDisplay when the application first starts up. Without it, the video player sends out bitrate errors. Selecting vids from the ComboBox works great when the user clicks an item, because everything is loaded and ready to go. But if the user presses play before selecting an item, then the errors ensue.

                Maybe your second option is the answer:

                <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" initialize="runDefaultVideo()">

                Problem? I don't know how to do an initialize event -- but that *does* sound like the right direction I would be grateful for instructions for setting it up.



                • 5. Re: Loading FLVs Dynamically in Flex
                  Level 1
                  To run a method in your mxml, just add some actionscript code:

                  <mx:Script>
                  <![CDATA[
                  private function runDefaultVideo():void
                  {
                  //do something here
                  }
                  ]]>
                  </mx:Script>

                  You'll need to add identifiers (i.e. id="objectname" ) to your mxml tags so that the actionscript can identify and use the mxml objects in your application.

                  as for the creationComplete, it does exist, but I think I was mixing up my terminology between the List and ComboBox.
                  so it should go like this:

                  creationComplete="selectedItem = ComboBox(event.target).selectedItem"

                  of course the language reference says the selectedItem is write only as well, so I'm completely confused (although I have successfully retrieved the selected data using selectedItem in a ComboBox before).

                  Anyway, this gives you a few avenues of possible to try.

                  --Andy
                  • 6. Re: Loading FLVs Dynamically in Flex
                    rica_help Level 1
                    Well, I am learning quite a bit. Now to display my ignorance:

                    1. Does this go in my current .mxml video file or is it a separate one?
                    <mx:Script>
                    <![CDATA[
                    private function runDefaultVideo():void
                    {
                    //do something here
                    }
                    ]]>
                    </mx:Script>

                    2. //do something here
                    Is there an easy way for me to feed 1.flv automatically to the videoDisplay ( id="myVid1") using the runDefaultVideo? Since the source is already source="videosource/{selectedItem.data}.flv", I'm clueless as to how I would get it into the videoDisplay.

                    3. You'll need to add identifiers (i.e. id="objectname" ) to your mxml tags so that the actionscript can identify and use the mxml objects in your application.

                    Wow, my knowledge is thin. I don't know how to set that up.

                    Andy, I *do* appreciate the help - can you please give me the last shove over the cliff?

                    • 7. Re: Loading FLVs Dynamically in Flex
                      Level 1
                      Happy to help, just hope I don't lead you off in the wrong direction. :-)

                      1. you can put the script tags anywhere between the application tags in the mxml file. I usually put them right after the leading tag.

                      2. you could try:

                      myVid1.source = "videosource/1.flv";
                      myVid1.play();

                      3. I didn't notice before, but you already have an identifier for your VideoDisplay (i.e. the id="myVid1" parameter):

                      <mx:VideoDisplay id="myVid1" height="400" width="600"
                      autoBandWidthDetection="false"
                      source="videosource/{selectedItem.data}.flv"
                      autoPlay="true" live="false"/>

                      if you want to access your other mxml objects in the actionscript, you'll have to give them id="name" parameters as well (and the ids should be unique).

                      Let us know how it goes.

                      --Andy
                      • 8. Loading FLVs Dynamically in Flex
                        rica_help Level 1
                        >> Happy to help, just hope I don't lead you off in the wrong direction. :-)

                        No worries there, man. I'm just happy that you and others are answering my posts. :) The help is encouraging and that's even more important than the solution is right now..

                        I give the solution a shot. In the mean time, will it look something like this?

                        1. Separate .mxml file called: runDefaultVideo.mxml
                        <mx:Script>
                        <![CDATA[
                        private function runDefaultVideo():void
                        {
                        myVid1.source = "videosource/1.flv";
                        myVid1.play();
                        }
                        ]]>
                        </mx:Script>

                        2. New header for the main.mxml file

                        <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" initialize="runDefaultVideo()">

                        I'll try it now - just want you to see what I'm trying. :)

                        =================================================
                        U P D A T E - I messed up something.
                        Well, what I tried threw this error from the separate runDefaultVideo.mxml file that I created:

                        Multiple constructor definitions found. Constructor may not be defined in <Script/> code.

                        Could you look at what I did and see where I messed up? I feel so darn close to the soution.


                        • 9. Re: Loading FLVs Dynamically in Flex
                          Level 1
                          My fault. you already have script tags in your original mxml. I didn't see that... need to start looking at things closer.

                          like this:

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

                          <mx:Script>
                          <![CDATA[
                          //start video array
                          [Bindable]
                          public var vids: Array =[
                          {label:"Select Item", data:null},
                          {label:"Video Two", data:2},
                          {label:"Video Three", data:3},
                          {label:"Video Four", data:4},
                          {label:"Video Five", data:5},
                          {label:"Video Six", data:6}
                          ];
                          //end video array
                          [Bindable]
                          public var selectedItem:Object;

                          private function runDefaultVideo():void
                          {
                          myVid1.source = "videosource/1.flv";
                          myVid1.play();
                          }
                          ]]>
                          </mx:Script>

                          .....

                          Theoritically, that should work.
                          • 10. Loading FLVs Dynamically in Flex
                            rica_help Level 1
                            Andy, I cannot thank you enough. That is the solution to the problem. This was a very frustrating situation - I am glad that it's over. HOORAY!!!!!

                            My next adventure will be the rtmp problem. I think it's a bug, since close() does not work.

                            I'm going to go outside now. :)
                            • 11. Re: Loading FLVs Dynamically in Flex
                              weiwuliang
                              is there anyway you can play the video file on the array list into the VideoDisplay in play the video 1 by 1??

                              OR

                              as in the code:
                              myVid1.source = "videosource/1.flv";
                              myVid1.play();
                              // which command can check the the 1.flv is finished playing
                              // i try a way like:
                              /*
                              if(myVid1.playheadTime == myVid1.totalTime){ // but this looks no working at all
                              myVid1.source = "videosource/2.flv";
                              myVid1.play();
                              }
                              */