For work stuff, I’ve been needing to set up a script to convert videos from whatever form they come in as to SWF (or, really, FLV embedded in SWF). The best thing for this that I found was FFmpeg. It does just about anything. One thing it doesn’t seem to do however is produce SWF files with the right frame count. It always writes the header with a count of 15,000, no matter the length of the incoming video. 15,000 is the maximum number of frames that the flash player can handle, and is used as a placeholder value when the file is created.
I tracked the problem down to the output not being correctly flushed, and the following patch fixes it:
Index: libavformat/swf.c =================================================================== --- libavformat/swf.c (revision 7093) +++ libavformat/swf.c (working copy) @@ -689,7 +689,6 @@ put_swf_tag(s, TAG_END); put_swf_end_tag(s); - put_flush_packet(&s->pb); /* patch file size and number of frames if not streamed */ if (!url_is_streamed(&s->pb) && video_enc) { @@ -699,7 +698,7 @@ url_fseek(pb, swf->duration_pos, SEEK_SET); put_le16(pb, video_enc->frame_number); } - + put_flush_packet(&s->pb); av_free(swf->audio_fifo); return 0;
In case you’re working on a substantially different version of swf.c
, this goes towards the end of static int swf_write_trailer(AVFormatContext *s)
, and is just moving the put_flush_packet
call to after where the frame number is written into the file, rather than before.
Pretty simple eh? I mentioned this on the ffmpeg-users list, but noone seems interested. No matter, I don’t mind too much keeping a custom build with this change. I need to do it anyway, the Ubuntu FFmpeg version doesn’t have MP3 encoding support, and that’s a must for creating FLV.
Thanks for that patch. It makes quite a difference!