onMetaData是FLV文件中的第一个Tag, 用来表示当前文件的一些基本信息: 比如视音频的编码类型id、视频的宽和高、文件大小、视频长度、创建日期等。
onMetaData基本信息
***onMetaData in Adobe Flash Video File Format Specification Version 10.1***
可以看出onMetaData是一个SCRIPTDATA类型的Tag.
用于表示视音频编码的两个属性: audiocodecid
和videocodecid
。
-
audiocodecid
音频的编码类型的id
,如AAC
的audiocodecid=10
***audiocodecid list***
-
videocodecid
视频的编码类型的id
,如AVC
的videocodecid=7
***videocodecid list***
SCRIPTDATA
SCRIPTDATA
可以看出在没有加密的情况下,SCRIPTDATA
由ScriptTagBody
组成, 主要包括Name
和Value
两部分:
Name
一个String
类型的SCRIPTDATAVALUE
。Value
一个ECMA Array
类型的SCRIPTDATAVALUE
。
SCRIPTDATA
SCRIPTDATAVALUE
***Part 1 of SCRIPTDATAVALUE***
***Part 2 of SCRIPTDATAVALUE***
- SCRIPTDATASTRING
SCRIPTDATASTRING
- SCRIPTDATAECMAARRAY
SCRIPTDATAECMAARRAY
-
ECMAArrayLength
数组中的元素个数。 -
Variables
SCRIPTDATAOBJECTPROPERTY
的数组。
***SCRIPTDATAOBJECTPROPERTY***
***属性的格式***
-
List Terminator
标志着SCRIPTDATAOBJECTPROPERTY
数组的结束。
***SCRIPTDATAOBJECTEND***
示意代码
// CPxFLVMuxer.h
enum ePxAMFDataType
{
AMF_NUMBER = 0, AMF_BOOLEAN, AMF_STRING, AMF_OBJECT,
AMF_MOVIECLIP, /* reserved, not used */
AMF_NULL, AMF_UNDEFINED, AMF_REFERENCE, AMF_ECMA_ARRAY, AMF_OBJECT_END,
AMF_STRICT_ARRAY, AMF_DATE, AMF_LONG_STRING, AMF_UNSUPPORTED,
AMF_RECORDSET, /* reserved, not used */
AMF_XML_DOC, AMF_TYPED_OBJECT,
AMF_AVMPLUS, /* switch to AMF3 */
AMF_INVALID = 0xff
};
char inline *put_byte( char *out_chPut, unsigned char in_uchVal )
{
out_chPut[0] = in_uchVal;
return out_chPut+1;
}
char inline *put_be16(char *out_chPut, unsigned short in_usVal )
{
out_chPut[1] = in_usVal & 0xff;
out_chPut[0] = in_usVal >> 8;
return out_chPut+2;
}
char inline *put_be32(char *out_chPut, unsigned int in_unVal )
{
out_chPut[3] = in_unVal & 0xff;
out_chPut[2] = in_unVal >> 8;
out_chPut[1] = in_unVal >> 16;
out_chPut[0] = in_unVal >> 24;
return out_chPut+4;
}
char inline *put_amf_string( char *out_chPut, const char *in_chBuf )
{
uint16_t len = (uint16_t)strlen( in_chBuf );
out_chPut=put_be16( out_chPut, len );
memcpy(out_chPut,in_chBuf,len);
return out_chPut+len;
}
char inline *put_amf_double( char *out_chPut, double in_dBuf )
{
*out_chPut++ = AMF_NUMBER; // type: Number
{
unsigned char *ci, *co;
ci = (unsigned char *)&in_dBuf;
co = (unsigned char *)out_chPut;
co[0] = ci[7];
co[1] = ci[6];
co[2] = ci[5];
co[3] = ci[4];
co[4] = ci[3];
co[5] = ci[2];
co[6] = ci[1];
co[7] = ci[0];
}
return out_chPut+8;
}
const int g_nMetaData = 1024 * 320;
// CPxFLVMuxer.cpp:
HRESULT CPxFLVMuxer::WriteOnMetaData()
{
HRESULT hr = NS_NOERROR;
...
//char chMetaData[g_nMetaData];
char *chMetaData = new char[g_nMetaData];
if (chMetaData == NULL)
{
...
}
char *chMetaDataTemp = (char *)chMetaData;
// SCRIPTDATASTRING
chMetaDataTemp = put_byte(chMetaDataTemp, AMF_STRING);
chMetaDataTemp = put_amf_string(chMetaDataTemp, "onMetaData");
// SCRIPTDATAECMAARRAY
chMetaDataTemp = put_byte(chMetaDataTemp, AMF_ECMA_ARRAY);
// ECMAArrayLength : UI32 属性数组长度
chMetaDataTemp = put_be32(chMetaDataTemp, 21);
// PropertyName
chMetaDataTemp = put_amf_string(chMetaDataTemp, "MetaDataCreator");
// Type:UI8 数据类型
chMetaDataTemp = put_byte(chMetaDataTemp, AMF_STRING);
// ScriptDataValue: 数据
chMetaDataTemp = put_amf_string(chMetaDataTemp, "created by ZL Guo @2016");
// PropertyName
chMetaDataTemp = put_amf_string(chMetaDataTemp, "hasKeyFrames");
// Type:UI8 数据类型
chMetaDataTemp = put_byte(chMetaDataTemp, AMF_BOOLEAN);
// ScriptDataValue: 数据
chMetaDataTemp = put_byte(chMetaDataTemp, 0);
chMetaDataTemp = put_amf_string(chMetaDataTemp, "hasVideo");
chMetaDataTemp = put_byte(chMetaDataTemp, AMF_BOOLEAN);
chMetaDataTemp = put_byte(chMetaDataTemp, 1);
chMetaDataTemp = put_amf_string(chMetaDataTemp, "hasAudio");
chMetaDataTemp = put_byte(chMetaDataTemp, AMF_BOOLEAN);
chMetaDataTemp = put_byte(chMetaDataTemp, 1);
chMetaDataTemp = put_amf_string(chMetaDataTemp, "hasMatadata");
chMetaDataTemp = put_byte(chMetaDataTemp, AMF_BOOLEAN);
chMetaDataTemp = put_byte(chMetaDataTemp, 1);
chMetaDataTemp = put_amf_string(chMetaDataTemp, "canSeekToEnd");
chMetaDataTemp = put_byte(chMetaDataTemp, AMF_BOOLEAN);
chMetaDataTemp = put_byte(chMetaDataTemp, 0);
// PropertyName
chMetaDataTemp = put_amf_string( chMetaDataTemp, "duration");
// Type:UI8 数据类型 + ScriptDataValue: 数据
chMetaDataTemp = put_amf_double( chMetaDataTemp, (double)0.0);
chMetaDataTemp = put_amf_string( chMetaDataTemp, "width");
chMetaDataTemp = put_amf_double( chMetaDataTemp, (double)m_sPxRecordFileProperty.aStreamProperty[m_nVideoStreamNum].nVideoWidth);
chMetaDataTemp = put_amf_string( chMetaDataTemp, "height");
chMetaDataTemp = put_amf_double( chMetaDataTemp, (double)m_sPxRecordFileProperty.aStreamProperty[m_nVideoStreamNum].nVideoHeight);
chMetaDataTemp = put_amf_string( chMetaDataTemp, "videodatarate");
chMetaDataTemp = put_amf_double( chMetaDataTemp, (double)m_sPxRecordFileProperty.aStreamProperty[m_nVideoStreamNum].nVideoBitrate);
chMetaDataTemp = put_amf_string( chMetaDataTemp, "framerate");
chMetaDataTemp = put_amf_double( chMetaDataTemp, (double)m_sPxRecordFileProperty.aStreamProperty[m_nVideoStreamNum].fVideoFrameRate);
chMetaDataTemp = put_amf_string( chMetaDataTemp, "videocodecid");
chMetaDataTemp = put_amf_double( chMetaDataTemp, (double)7.0);
chMetaDataTemp = put_amf_string( chMetaDataTemp, "audiosamplerate");
chMetaDataTemp = put_amf_double( chMetaDataTemp, (double)m_sPxRecordFileProperty.aStreamProperty[m_nVideoStreamNum].eAudioSamplesPerSecond);
chMetaDataTemp = put_amf_string( chMetaDataTemp, "audiosamplesize");
chMetaDataTemp = put_amf_double( chMetaDataTemp, (double)m_sPxRecordFileProperty.aStreamProperty[m_nVideoStreamNum].nAudioBitsPerSampleint);
chMetaDataTemp = put_amf_string(chMetaDataTemp, "stereo");
chMetaDataTemp = put_byte(chMetaDataTemp, AMF_BOOLEAN);
chMetaDataTemp = put_byte(chMetaDataTemp, 1);
chMetaDataTemp = put_amf_string( chMetaDataTemp, "audiocodecid");
chMetaDataTemp = put_amf_double( chMetaDataTemp, (double)10.0);
chMetaDataTemp = put_amf_string( chMetaDataTemp, "filesize");
chMetaDataTemp = put_amf_double( chMetaDataTemp, (double)0.0);
// List Terminator: SCRIPTDATAOBJECTEND 表示属性数组的结束
// SCRIPTDATAOBJECTEND 即 0x00 0x00 0x09
chMetaDataTemp = put_be24( chMetaDataTemp, 9);
...
}
References:
Adobe Flash Video File Format Specification Version 10.1