7 Replies Latest reply on Jan 14, 2011 3:48 AM by xiaojing chai

    How to detect corrupt FLV Video?

    ApolloX2

      I'm having serious issues detecting whether a FLV video is corrupt in Flex/Flash/Air.  If the FLV video file is missing or unavailable I can use the common technique to detect this:

       

      var video:VideoDisplay = ...

      video.addEventListener(VideoEvent.STATE_CHANGE,videoErrorHandler);

       

      ...

       

      private function videoErrorHandler(inEvent:VideoEvent):void {

           if(inEvent.state == VideoEvent.CONNECTION_ERROR) {

                ...

           }

      }

       

      Surprisingly, this handler *DOES NOT* get called when the video file is corrupted.  In fact, in my test application, the video player window just turns black and the player sits there indefinitely not firing any messages to indicate that there is an error or the file is complete.  I've tried adding other handlers and also checking all inEvent.state value but no handler seems to exist that lets the application know Flash is stuck.  Anyone have a solution to this issue?

        • 1. Re: How to detect corrupt FLV Video?
          ApolloX2 Level 1

          I've uploaded a corrupted video (just opened in text editor and mucked with components of a real video) here:  http://www.selikoffsolutions.com/BadVideo.flv

           

          Even the Adobe Media Player doesn't throw an error when opening or reading this file.  I'd really like to know what listener, if any, is thrown a VideoDisplay object tries to play such a video.

          • 2. Re: How to detect corrupt FLV Video?
            xjchai

            W e can't expect some error event to be thrown to playback a tempered file. In most of the cases, one can look at the playhead counter. If that counter gets stuck on a value, one can conclude the content is bad.

            Such as the following---

            ***********************************

            PlaybackAction Netstatus Event NetConnection.Connect.Success
            PlaybackAction NetStream.play():http://www.selikoffsolutions.com/BadVideo.flv
            PlaybackAction NetStream.play() returns. Waiting for event...
            PlaybackAction Netstatus Event NetStream.Play.Start
            PlaybackAction time to play: 10
            PlaybackAction Playhead time (s)  0
            PlaybackAction Playhead time (s)  0
            PlaybackAction Netstatus Event NetStream.Buffer.Flush
            PlaybackAction Netstatus Event NetStream.Play.Stop
            PlaybackAction Playhead time (s)  0
            PlaybackAction Playhead time (s)  0
            PlaybackAction Playhead time (s)  0
            ...
            playhead always  0

            • 3. Re: How to detect corrupt FLV Video?
              ApolloX2 Level 1

              >  We can't expect some error event to be thrown to playback a tempered file.

               

              Yes, we can, and we should.  In this example, the file was manually distorted but in the real example that this came from, file was corrupted from a bad transmission.  Sitting there with a black screen doing nothing is never an acceptable solution and the flash video play should recognize this and throw an error to the user.

              • 4. Re: How to detect corrupt FLV Video?
                rtalton Level 4

                Have you looked in to the fl.video.VideoError class?

                Are you using streaming or progressive download?

                • 5. Re: How to detect corrupt FLV Video?
                  XiaojingChai

                  Would you please share with me your code in which you encounted this trouble? Please send the code to xiaojing@gmail.com if you don't mind.

                  • 6. Re: How to detect corrupt FLV Video?
                    ApolloX2 Level 1

                    The code is the standard VideoDisplay loading code.

                    • 7. Re: How to detect corrupt FLV Video?
                      xiaojing chai

                      Generally, the corrupted audio/video packages will be silently dropped. That’s the behavior of FlashPlayer. In this perticuler case, http://www.selikoffsolutions.com/BadVideo.flv, the metadata can be retrieved by listening MetadataEvent.METADATA_RECEIVED. But it falls to the "stopped" state very fast. There is no picture played; and no error event dispatched. In some other cases, the video can go to some point then get stuck there, even without the state event turning to "stopped".

                       

                      If we look at the VideoEvent.PLAYHEAD_UPDATE event, the time value will always get stuck at a fixed value under these circumstances. So one workaround would be to observe this event. We fail the playback if this playhead time value doesn't advance for a tolerable time interval. Here is code sample:

                       

                      ...

                       

                      <mx:VideoDisplay x="142" y="116" width="704" height="386" id="player" rewind="false" source="http://www.selikoffsolutions.com/BadVideo.flv"/>


                          <fx:Script>

                              <![CDATA[


                                import mx.events.*;
                                 


                                private var lastPlayHead :Number; // remember the playhead time from the last polling
                                private var timeoutTimer :Timer = null;



                                 private function registerListener() :void
                                 {
                                   
                                    player.addEventListener(VideoEvent.PLAYHEAD_UPDATE, onPlayheadUpdate);
                                    //...
                                     
                                 }



                                  private function onPlayheadUpdate(e :VideoEvent) :void

                                  {


                                      var currentHead :Number = e.playheadTime;

                                      if (currentHead > lastPlayHead)
                                      {
                                          // restart a timeout timer
                                          if(timeoutTimer != null)
                                          {
                                              timeoutTimer.stop();
                                          }
                                          timeoutTimer = new Timer(60000, 0); // if the playhead not increment for 1 minute, then timeout this action
                                          timeoutTimer.addEventListener(TimerEvent.TIMER, timeoutHandler);
                                          timeoutTimer.start();
                                         
                                      }
                                      lastPlayHead = currentHead;


                                    }



                                   private function timeoutHandler (e :TimerEvent) :void
                                   {
                                      // fail the playback
                                   }


                      ...

                       

                      ]]>
                          </fx:Script>