7 Replies Latest reply on Feb 19, 2010 1:58 AM by jcastelain

    Video synchronisation

    jcastelain

      Hi all,

       

      I've been developing a vide player with OSMF that displays 2 videos, 1 is a screen recording and the other is the web cam recording ...  however, I didn't develop the "recorder part", but while developing the player, I noticed that the two videos never have the same length, (there's always a 1 or 2 minutes difference between the two videos) . I'm using a parallel element to manage those two videos displayed in video elements ...


      With all that said, I was wondering if it possible to plays those videos "in sync" (knowing they have different lengths, one has audio the other doesn't) etc...? For me it seems quite logical that these videos can't be always synchronised, but I have a feeling some of my co workers think it's my actionscript code

       

      Thanks for your comments, feedback, thoughts

       

      Julien

        • 1. Re: Video synchronisation
          Edwin van Rijkom Level 2

          Hi Julien,

           

          If 'play in sync' means that both videos should be paused when one of them is in a buffering state (assuming that is the cause for them not to be sync at a given moment in time?) than doing that should probably be feasible to do by creating a ParallelElement subclass that listens for its BufferTrait.buffering property, and toggling the pause state accordingly.

           

          Cheers,

          Edwin

          1 person found this helpful
          • 2. Re: Video synchronisation
            jcastelain Level 1

            Hi Edwin,

             

            Thanks again for the explanation, I was just wondering if in my ParallelElement subclass should I had an event listener to the "BufferTrait" of the ParallelElement, or I should add an event listener to the buffer trait of each "child"

             

            Here's the code I have right now,

             

            package
            {
                import org.osmf.composition.ParallelElement;
                import org.osmf.events.BufferEvent;
                import org.osmf.events.MediaElementEvent;
                import org.osmf.traits.BufferTrait;
                import org.osmf.traits.MediaTraitType;
            
                public class SynchronizedElement extends ParallelElement
                {
                    private var _bufferTrait:BufferTrait;
                    
                    public function SynchronizedElement()
                    {
                        super();
                        addEventListener(MediaElementEvent.TRAIT_ADD, mediaElement_traitAddHandler);
                    }
                    
                    protected function mediaElement_traitAddHandler(event:MediaElementEvent):void
                    {
                        if(event.traitType == MediaTraitType.BUFFER) {
                            _bufferTrait = getTrait(MediaTraitType.BUFFER) as BufferTrait;
                            _bufferTrait.addEventListener(BufferEvent.BUFFERING_CHANGE, bufferTrait_bufferingChangeHandler);
                        }
                        
                    }
                            
                    protected function bufferTrait_bufferingChangeHandler(event:BufferEvent):void 
                    {    
                        // ... do something here, but what?
                        
                    }
                }
            }
            

             

            Thanks,

            Julien

            • 3. Re: Video synchronisation
              Edwin van Rijkom Level 2

              Adding listeners to the parallel trait itself should do the trick, I think  - for the buffering traits of the children should appear as an aggregate on the parallel element. Perhaps the class could look something like this:

               

              package
              {
                  import org.osmf.elements.ParallelElement;
                  import org.osmf.events.BufferEvent;
                  import org.osmf.events.MediaElementEvent;
                  import org.osmf.traits.BufferTrait;
                  import org.osmf.traits.MediaTraitType;
                  import org.osmf.traits.PlayState;
                  import org.osmf.traits.PlayTrait;


                  public class SynchronizedParallelElement extends ParallelElement
                  {
                      public function SynchronizedParallelElement()
                      {
                          addEventListener(MediaElementEvent.TRAIT_ADD, onTraitAdd);
                          addEventListener(MediaElementEvent.TRAIT_REMOVE, onTraitRemove);
                         
                          super();
                      }
                     
                      // Internals
                      //
                     
                      private var bufferable:BufferTrait;
                      private var playable:PlayTrait;
                      private var paused:Boolean;
                     
                      private function onTraitAdd(event:MediaElementEvent):void
                      {
                          switch (event.traitType)
                          {
                              case MediaTraitType.BUFFER:
                                  bufferable = BufferTrait(getTrait(event.traitType));
                                  bufferable.addEventListener(BufferEvent.BUFFER_TIME_CHANGE, updatePlayState);
                                  updatePlayState();
                                  break;
                                 
                              case MediaTraitType.PLAY:
                                  playable = PlayTrait(getTrait(event.traitType));
                                  updatePlayState();
                                  break;
                          }
                      }
                     
                      private function onTraitRemove(event:MediaElementEvent):void
                      {
                          switch (event.traitType)
                          {
                              case MediaTraitType.BUFFER:
                                  bufferable.removeEventListener(BufferEvent.BUFFER_TIME_CHANGE, updatePlayState);
                                  bufferable = null;
                                  updatePlayState();
                                  break;
                                 
                              case MediaTraitType.PLAY:
                                  playable = null;
                                  updatePlayState();
                                  break;
                          }
                      }
                     
                      private function updatePlayState(..._):void
                      {
                          if (playable && playable.canPause && bufferable)
                          {
                              if     (    paused == true
                                  &&    playable.playState == PlayState.PAUSED
                                  &&     bufferable.bufferTime >= bufferable.bufferLength
                                  )
                              {
                                  paused = false;
                                  playable.play();
                              }
                              else if
                                  (    paused == false
                                  &&    playable.playState != PlayState.PAUSED
                                  &&     bufferable.bufferTime < bufferable.bufferLength
                                  )
                              {
                                  paused = true;
                                  playable.pause();
                              }
                          }
                      }
                  }
              }

              • 4. Re: Video synchronisation
                jcastelain Level 1

                Thanks Edwin,

                 

                You're the man

                Exactly what I was looking for

                 

                Cheers,

                Julien

                • 5. Re: Video synchronisation
                  Edwin van Rijkom Level 2

                  Great to hear that it is helpful!

                   

                  The class is now part of the ExamplePlayer sample app (on the trunk). I've been adding some fixes there.

                   

                  Cheers,

                  Edwin

                  • 6. Re: Video synchronisation
                    jcastelain Level 1

                    Great Idea thanks, I'll check that in the trunk

                     

                    Julien

                    • 7. Re: Video synchronisation
                      jcastelain Level 1

                      Hi again Edwin,


                      This might be slightly off topic, but I thought you might be able to help.
                      I'm now using the SynchronizedParallelElement, and I'm happy with the result, however sometimes, if I seek backwards or forwards, my "video elements" are not prefectly "synced".
                      This is probably logical since the 2 videos I'm playing, have been created with two different technologies, and their framerates and length are totally different.
                      So actually my question is "is it possible to syncrhonise two videos  that have a different framerates and lengths?"


                      Thanks again for your help

                      Julien

                       

                      Nevermind,
                      Found the issue, our "video recording app" (that uses Red5) is the one causing errors, the SynchronizedParallelElement works exactly like I expected it too.

                      Go OSMF!


                      Cheers,
                      Julien