[MPlayer-users] Mplayer can't find video in (.flv) file

Reimar Döffinger Reimar.Doeffinger at stud.uni-karlsruhe.de
Sun Apr 13 18:14:53 CEST 2008


On Sun, Apr 13, 2008 at 08:30:14AM -0700, Need Help wrote:
> I found a site with a series of videos that mplayer thinks
> are audio only files. When I try to play one, I get:

[...]

> http://eurovision.tv/upload/video/2008/WELCOMETOBELGRADE.flv
> 
> Can someone explain the problem (let me know if you need any
> more information)?

Byte 4 of this file is 4, which indicates an audio-only file (0
means older/broken format, 1 means video-only, 5 means audio and
video), so this is just a broken file (as far as such a thing exists
with and undocumented format).
You can use e.g. attached patch though.
-------------- next part --------------
Index: libavformat/flvdec.c
===================================================================
--- libavformat/flvdec.c	(revision 12797)
+++ libavformat/flvdec.c	(working copy)
@@ -101,7 +101,9 @@
     return length;
 }
 
-static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vstream, const char *key, unsigned int max_pos, int depth) {
+static AVStream *create_stream(AVFormatContext *s, int is_audio);
+
+static int amf_parse_object(AVFormatContext *s, AVStream **astream, AVStream **vstream, const char *key, unsigned int max_pos, int depth) {
     AVCodecContext *acodec, *vcodec;
     ByteIOContext *ioc;
     AMFDataType amf_type;
@@ -166,8 +168,13 @@
     }
 
     if(depth == 1 && key) { //only look for metadata values when we are not nested and key != NULL
-        acodec = astream ? astream->codec : NULL;
-        vcodec = vstream ? vstream->codec : NULL;
+        // HACK: create extra streams if it looks like there are more streams than the header indicates
+        if(vstream && !*vstream && !strncmp(key, "video", 5))
+            *vstream = create_stream(s, 0);
+        if(astream && !*astream && !strncmp(key, "audio", 5))
+            *astream = create_stream(s, 1);
+        acodec = *astream ? (*astream)->codec : NULL;
+        vcodec = *vstream ? (*vstream)->codec : NULL;
 
         if(amf_type == AMF_DATA_TYPE_BOOL) {
             if(!strcmp(key, "stereo") && acodec) acodec->channels = num_val > 0 ? 2 : 1;
@@ -176,9 +183,9 @@
 //            else if(!strcmp(key, "width")  && vcodec && num_val > 0) vcodec->width  = num_val;
 //            else if(!strcmp(key, "height") && vcodec && num_val > 0) vcodec->height = num_val;
             else if(!strcmp(key, "audiocodecid") && acodec && 0 <= (int)num_val)
-                flv_set_audio_codec(s, astream, (int)num_val << FLV_AUDIO_CODECID_OFFSET);
+                flv_set_audio_codec(s, *astream, (int)num_val << FLV_AUDIO_CODECID_OFFSET);
             else if(!strcmp(key, "videocodecid") && vcodec && 0 <= (int)num_val)
-                flv_set_video_codec(s, vstream, (int)num_val);
+                flv_set_video_codec(s, *vstream, (int)num_val);
             else if(!strcmp(key, "audiosamplesize") && acodec && 0 < (int)num_val) {
                 acodec->bits_per_sample = num_val;
                 //we may have to rewrite a previously read codecid because FLV only marks PCM endianness.
@@ -228,7 +235,7 @@
     }
 
     //parse the second object (we want a mixed array)
-    if(amf_parse_object(s, astream, vstream, buffer, next_pos, 0) < 0)
+    if(amf_parse_object(s, &astream, &vstream, buffer, next_pos, 0) < 0)
         return -1;
 
     return 0;


More information about the MPlayer-users mailing list