[FFmpeg-devel] [PATCH] libavfromat/flvenc.c: Preserve the 'amf0' data stream written by Adobe Flash Media Servers while doing a data stream copy

Benedict Endemann bendemann at make.tv
Sat Mar 9 10:10:45 CET 2013

From: Benedict Endemann <bendemann at make.tv>

The Adobe Flash Media Server is able to record incoming rtmp streams form connected Adobe Flash Players to disk. It is also able to add an amf0 data stream to these files.
Incoming Streams containing a h.264 video track are recorded to Quicktime/Mpeg4 containers (f4v) and streams with other video codecs are recorded to FLV containers.
The problem is, that availabel audio codecs on the encoder (the Adobe Flash Player) are non-standard for Mpeg4 containers. Due to this, the Adobe Flash Player isn't able to playback f4v files recorded by the Adobe Flash Media Server with audio playback without conversion!

With this patch it is possible to preserve the amf0 data stream while doing a container conversion from Mpeg4 to FLV containers while preserving the data stream that is lost otherwise.
 libavformat/flvenc.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c
index 502da0f..8c8e524 100644
--- a/libavformat/flvenc.c
+++ b/libavformat/flvenc.c
@@ -225,7 +225,8 @@ static int flv_write_header(AVFormatContext *s)
                 return AVERROR_INVALIDDATA;
         case AVMEDIA_TYPE_DATA:
-            if (enc->codec_id != AV_CODEC_ID_TEXT) {
+            // 'amf0' is the codec_tag used by the Adobe Flash Media Server for the 'amf0' data packets
+            if (enc->codec_id != AV_CODEC_ID_TEXT && enc->codec_tag != MKTAG('a','m','f','0')) {
                 av_log(s, AV_LOG_ERROR, "Data codec '%s' for stream %d is not compatible with FLV\n",
                        avcodec_get_name(enc->codec_id), i);
                 return AVERROR_INVALIDDATA;
@@ -527,6 +528,7 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
     if (enc->codec_type == AVMEDIA_TYPE_DATA) {
         int data_size;
         int metadata_size_pos = avio_tell(pb);
+        if (enc->codec_id == AV_CODEC_ID_TEXT) {
         avio_w8(pb, AMF_DATA_TYPE_STRING);
         put_amf_string(pb, "onTextData");
         avio_w8(pb, AMF_DATA_TYPE_MIXEDARRAY);
@@ -539,6 +541,10 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
         put_amf_string(pb, pkt->data);
         put_amf_string(pb, "");
         avio_w8(pb, AMF_END_OF_OBJECT);
+        }
+        if (enc->codec_tag == MKTAG('a','m','f','0')) {
+                   avio_write(pb, pkt->data, pkt->size);
+        }
         /* write total size of tag */
         data_size = avio_tell(pb) - metadata_size_pos;
         avio_seek(pb, metadata_size_pos - 10, SEEK_SET);

More information about the ffmpeg-devel mailing list