13 Replies Latest reply on Jun 17, 2010 6:27 PM by box86rowh

    Proper Method to clear SerialElement

    box86rowh Level 1

      Hello,

      If I have a player that is meant to be played multiple times with multiple videos, and I am playing them in a serialElement, what is th ebest way to stop playback and reset the serialElement so that it is fresh and ready to start again.

      RIght now when I stop the video, swap the video out by rebuilding the serialElement, and start playing, i get both videos at the same time!

      Has anyone else seen this?

      Thanks

        • 1. Re: Proper Method to clear SerialElement
          bringrags Level 4

          I'd probably need to see the code to provide a diagnosis, but if I were trying to solve this problem I wouldn't use a SerialElement (though perhaps you have reason to do so).  Instead, I would wait until the MediaPlayer dispatched the "complete" event, and then I would assign a new VideoElement to the MediaPlayer (first making sure that MediaPlayer.autoRewind is false so that you don't waste timing rewinding something that doesn't need to be rewound).

           

          If you have good reason to use a SerialElement, the same approach would probably apply:  when you get the "complete" event, construct a new SerialElement to assign to MediaPlayer.media.

          1 person found this helpful
          • 2. Re: Proper Method to clear SerialElement
            box86rowh Level 1

            I am using the serial element as it seemed the perfect way to easily get a pre and/or post roll ad or some other message into my video product.

            Here is the code I am using to initialize the player (runs once at the beginning)

             

                            parentApplication.addEventListener(AdEvent.AD_CHANGE, changeAd);
                            player = new MediaPlayer();
                            player.volume = vol.value / 10;
                            player.addEventListener(TimeEvent.CURRENT_TIME_CHANGE, updateTime);
                            player.addEventListener(TimeEvent.COMPLETE, onDone);
                            player.addEventListener(MediaErrorEvent.MEDIA_ERROR, onError);
                            player.addEventListener(BufferEvent.BUFFERING_CHANGE, buffering);
                            player.addEventListener(DisplayObjectEvent.MEDIA_SIZE_CHANGE, sizeChange);
                            container = new MediaContainer();
                            container.width = width;
                            container.height = height;
                            par.addChild(container);

             

            Here is the code that runs when play is requested:

             

                        public function play():void{
                            unloadMedia();
                            // prepare our playlist
                            comp = new SerialElement();
                            //setup preloader
                            if(preRoll != null){
                                comp.addChild(preRoll);
                            }
                            comp.addChild(getVideo(videoXml[videoIndex]));
                            if(postRoll != null){
                                comp.addChild(postRoll);
                            }
                            setMediaElement(comp);
                        }
                        private function setMediaElement(value:MediaElement):void
                        {
                            if (player.media != null)
                            {
                                container.removeMediaElement(player.media);
                            }
                           
                            if (value != null)
                            {
                                container.addMediaElement(value);
                            }
                           
                            player.media = value;
                        }
                        private function unloadMedia():void
                        {
                            setMediaElement(null);
                            comp = null;
                        }

             

            And here is the code that runs when someone hits stop, or plays to the end of the sequence

             

                        public function stop():void{
                            player.stop();
                        }

             

            My getVideo function returns a dynamic streaming videoElement.  In the play function, I check if there are any pre and/or post rolls as I am building my serialElement (comp).  If they are set, then they are added to the comp.  They are very simple objects extending MediaElement using the display object trait.  Just a single line of text in the middle of the stage.

             

            If you need more code let me know, but I think this should do it as it covers the logic steps in my video product.

             

            Thanks for any help!

            Jason

            • 3. Re: Proper Method to clear SerialElement
              box86rowh Level 1

              One more note, If I do not pass in my pre-roller and the composition is just the video and post roll, it works fine without any overlapping video playback.  As soon as I add a mediaElement before the video, it acts up on the second play thru and on (first play is fine)

              • 4. Re: Proper Method to clear SerialElement
                bringrags Level 4

                Does your initial preroll have any traits other than the DisplayObjectTrait?  Or are you wrapping it in a DurationElement to give it a fixed duration?  I assume so, as the SerialElement wouldn't be able to play otherwise.

                 

                In any case, the code looks fine.  One possibile cause might be that the SerialElement will be rewound (if MediaPlayer.autoRewind is true) and replayed (if MediaPlayer.loop is true).  Not sure whether this is the case in your player (seems unlikely).  You might want to set autoRewind to false, so that it won't be rewound when playback completes.

                • 5. Re: Proper Method to clear SerialElement
                  box86rowh Level 1

                  here is the code for my pre/post roll element

                   

                  package classes
                  {
                      import flash.display.Graphics;
                      import flash.display.Sprite;
                      import flash.events.MouseEvent;
                      import flash.text.TextField;
                      import flash.text.TextFormat;
                      import flash.text.TextFormatAlign;
                      import org.osmf.media.MediaElement;
                      import org.osmf.metadata.Metadata;
                      import org.osmf.traits.DisplayObjectTrait;
                      import org.osmf.traits.MediaTraitType;
                      import com.greensock.TimelineMax;
                      import com.greensock.TweenMax;
                      import org.osmf.media.MediaElement;
                     
                      public class CompNameRoller extends MediaElement
                      {
                          public var displayObject:Sprite;
                          public function CompNameRoller(compName:String, w:Number, h:Number)
                          {
                              super();
                              removeTrait(MediaTraitType.SEEK);
                              var format:TextFormat = new TextFormat();
                              format.font = "Arial";
                              format.color = 0xFFFFFF;
                              format.size = 18;
                              format.align = TextFormatAlign.CENTER;
                             
                              var textField:TextField = new TextField();
                              textField.defaultTextFormat = format;
                              textField.text = compName;
                              textField.y = 10;
                              textField.width = w;
                              textField.height = h;
                              textField.selectable = false;
                              textField.alpha = .7;
                             
                              displayObject = new Sprite();
                             
                              displayObject.addChild(textField);
                             
                              //var tl:TimelineMax = new TimelineMax();
                              //tl.append(new TweenMax(textField,1,{alpha: .7}));
                              //tl.insert(new TweenMax(textField,1,{alpha: 0}), 4);
                              //tl.play();
                             
                              var displayObjectTrait:DisplayObjectTrait = new DisplayObjectTrait(displayObject, w, h);
                              addTrait(MediaTraitType.DISPLAY_OBJECT, displayObjectTrait);
                          }
                      }
                  }

                   

                  I am indeed wrapping this in a 2 second durationElement, I set autoRewind to false and loop to false on the mediaPlayer object and I am still getting the same result.

                  • 6. Re: Proper Method to clear SerialElement
                    bringrags Level 4

                    Hmm, looks fine.  Nothing jumps out at me.

                     

                    Some other thoughts... Does getVideo always return a new VideoElement?  Or does it return the old VideoElement with a new resource?  I can't imagine that that would be the problem.  One thing to try would be to clear the resource on the VideoElement prior to switching to the new SerialElement.  (This would obviously not be the ideal solution, but it might give us an indication of whether the original VideoElement is being played.  Last, you could try adding event listeners (e.g. for playStateChange) to the SerialElement and/or its children, to get an idea of whether the old SerialElement or its children are still active even after you've cleared the SerialElement.

                     

                    If none of the above works, feel free to send me the full source (briggs at you know where).

                    • 7. Re: Proper Method to clear SerialElement
                      box86rowh Level 1

                      I will try the event listener idea now, but here is my getVideo function:

                       

                                  public function getVideo(vid:XML):MediaElement{
                                      var bitrates:XMLList = vid.videoEncodes.videoEncode;
                                          var resource:DynamicStreamingResource = new DynamicStreamingResource(vid.@server + "_definst_");
                                          var vector:Vector.<DynamicStreamingItem> = new Vector.<DynamicStreamingItem> (bitrates.length());
                                          for(var i:Number = 0; i < bitrates.length(); i++){
                                              vector[i] = (new DynamicStreamingItem("MP4:" + String(bitrates[i].@fileName).substring(0, String(bitrates[i].@fileName).length - 4), Number(bitrates[i].@bitRate)));
                                          }
                                          resource.streamItems = vector;   
                                          var videoElement:VideoElement = new VideoElement(resource);
                                          videoElement.smoothing = true;
                                          return videoElement;
                                  }

                      • 8. Re: Proper Method to clear SerialElement
                        box86rowh Level 1

                        Brian,

                        I modified the unloadMedia function like this as per your suggestion on clearing the resource and now it works great!

                         

                                    private function unloadMedia():void
                                    {
                                        if(comp != null){
                                            for(var i:Number = 0; i < comp.numChildren; i++){
                                                var me:MediaElement = comp.getChildAt(i);
                                                if(me is VideoElement){
                                                    me.resource = null;
                                                }
                                            }
                                            setMediaElement(null);
                                            comp = null;
                                        }
                                    }

                         

                        Is this the best way to do this?  Thanks for your help in this issue.

                         

                        Jason

                        • 9. Re: Proper Method to clear SerialElement
                          bringrags Level 4

                          That's good to know.  I don't think it's the right solution, however it does point to the fact that something is still attempting to use the old VideoElement after you've assigned the new SerialElement to the MediaPlayer.  I would recommend adding a listener to that VideoElement to see what's causing it to get played after you clear the SerialElement.

                          • 10. Re: Proper Method to clear SerialElement
                            box86rowh Level 1

                            Good point, I will do that and let you know,

                             

                            One more question for now, on my preroller that uses the displayObjectTrait, in that object, how can I trigger an animation when that element is displayed and kill it when it is off the stage?

                             

                            Date: Thu, 17 Jun 2010 13:01:52 -0600

                            From: forums@adobe.com

                            To: jasonatsmtc@hotmail.com

                            Subject: Proper Method to clear SerialElement

                             

                            That's good to know.  I don't think it's the right solution, however it does point to the fact that something is still attempting to use the old VideoElement after you've assigned the new SerialElement to the MediaPlayer.  I would recommend adding a listener to that VideoElement to see what's causing it to get played after you clear the SerialElement.

                            >

                            • 11. Re: Proper Method to clear SerialElement
                              bringrags Level 4

                              You could try keying off of Event.ADDED_TO_STAGE and Event.REMOVED_FROM_STAGE.

                              1 person found this helpful
                              • 12. Re: Proper Method to clear SerialElement
                                box86rowh Level 1

                                I tried adding the lsuteners in the constructor on my preroller mediaelement :

                                 

                                            addEventListener(Event.ADDED_TO_STAGE, startIt);
                                            addEventListener(Event.REMOVED_FROM_STAGE, stopIt);

                                 

                                But the events never get triggered?

                                • 13. Re: Proper Method to clear SerialElement
                                  box86rowh Level 1

                                  OK, fixed this, I added a listener at the player level :

                                  player.addEventListener(DisplayObjectEvent.DISPLAY_OBJECT_CHANGE, onChange);

                                  and in that listener, I am checking the value of the currentChild in the serialElement, if it is a pre or post roll, i trigger my animation. works great.

                                  Thanks again for the help.

                                  Jason