mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
supprt inject flv
This commit is contained in:
parent
4970664e37
commit
22968c85df
10 changed files with 313 additions and 184 deletions
|
@ -207,20 +207,36 @@ int SrsFlvEncoder::write_header()
|
|||
'F', 'L', 'V', // Signatures "FLV"
|
||||
(char)0x01, // File version (for example, 0x01 for FLV version 1)
|
||||
(char)0x00, // 4, audio; 1, video; 5 audio+video.
|
||||
(char)0x00, (char)0x00, (char)0x00, (char)0x09, // DataOffset UI32 The length of this header in bytes
|
||||
(char)0x00, (char)0x00, (char)0x00, (char)0x00// PreviousTagSize0 UI32 Always 0
|
||||
(char)0x00, (char)0x00, (char)0x00, (char)0x09 // DataOffset UI32 The length of this header in bytes
|
||||
};
|
||||
|
||||
// flv specification should set the audio and video flag,
|
||||
// actually in practise, application generally ignore this flag,
|
||||
// so we generally set the audio/video to 0.
|
||||
|
||||
// write 9bytes header.
|
||||
if ((ret = write_header(flv_header)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsFlvEncoder::write_header(char flv_header[9])
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
// write data.
|
||||
if ((ret = _fs->write(flv_header, sizeof(flv_header), NULL)) != ERROR_SUCCESS) {
|
||||
if ((ret = _fs->write(flv_header, 9, NULL)) != ERROR_SUCCESS) {
|
||||
srs_error("write flv header failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char pts[] = { 0x00, 0x00, 0x00, 0x00 };
|
||||
if ((ret = _fs->write(pts, 4, NULL)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -92,6 +92,7 @@ public:
|
|||
* that is, 9+4=13bytes.
|
||||
*/
|
||||
virtual int write_header();
|
||||
virtual int write_header(char flv_header[9]);
|
||||
/**
|
||||
* write flv metadata.
|
||||
* serialize from:
|
||||
|
|
|
@ -491,6 +491,34 @@ int srs_flv_read_tag_data(srs_flv_t flv, char* data, int32_t size)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int srs_flv_write_header(srs_flv_t flv, char header[9])
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
FlvContext* context = (FlvContext*)flv;
|
||||
if ((ret = context->enc.write_header(header)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int srs_flv_write_tag(srs_flv_t flv, char type, int32_t time, char* data, int size)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
FlvContext* context = (FlvContext*)flv;
|
||||
if (type == SRS_RTMP_TYPE_AUDIO) {
|
||||
return context->enc.write_audio(time, data, size);
|
||||
} else if (type == SRS_RTMP_TYPE_VIDEO) {
|
||||
return context->enc.write_video(time, data, size);
|
||||
} else {
|
||||
return context->enc.write_metadata(data, size);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t srs_flv_tellg(srs_flv_t flv)
|
||||
{
|
||||
FlvContext* context = (FlvContext*)flv;
|
||||
|
@ -508,6 +536,16 @@ flv_bool srs_flv_is_eof(int error_code)
|
|||
return error_code == ERROR_SYSTEM_FILE_EOF;
|
||||
}
|
||||
|
||||
flv_bool srs_flv_is_sequence_header(char* data, int32_t size)
|
||||
{
|
||||
return SrsCodec::video_is_sequence_header((int8_t*)data, (int)size);
|
||||
}
|
||||
|
||||
flv_bool srs_flv_is_keyframe(char* data, int32_t size)
|
||||
{
|
||||
return SrsCodec::video_is_keyframe((int8_t*)data, (int)size);
|
||||
}
|
||||
|
||||
srs_amf0_t srs_amf0_parse(char* data, int size, int* nparsed)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
@ -536,6 +574,21 @@ srs_amf0_t srs_amf0_parse(char* data, int size, int* nparsed)
|
|||
return amf0;
|
||||
}
|
||||
|
||||
srs_amf0_t srs_amf0_create_number(amf0_number value)
|
||||
{
|
||||
return SrsAmf0Any::number(value);
|
||||
}
|
||||
|
||||
srs_amf0_t srs_amf0_create_ecma_array()
|
||||
{
|
||||
return SrsAmf0Any::ecma_array();
|
||||
}
|
||||
|
||||
srs_amf0_t srs_amf0_create_strict_array()
|
||||
{
|
||||
return SrsAmf0Any::strict_array();
|
||||
}
|
||||
|
||||
void srs_amf0_free(srs_amf0_t amf0)
|
||||
{
|
||||
SrsAmf0Any* any = (SrsAmf0Any*)amf0;
|
||||
|
@ -547,6 +600,30 @@ void srs_amf0_free_bytes(char* data)
|
|||
srs_freep(data);
|
||||
}
|
||||
|
||||
int srs_amf0_size(srs_amf0_t amf0)
|
||||
{
|
||||
SrsAmf0Any* any = (SrsAmf0Any*)amf0;
|
||||
return any->total_size();
|
||||
}
|
||||
|
||||
int srs_amf0_serialize(srs_amf0_t amf0, char* data, int size)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
SrsAmf0Any* any = (SrsAmf0Any*)amf0;
|
||||
|
||||
SrsStream stream;
|
||||
if ((ret = stream.initialize(data, size)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = any->write(&stream)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
amf0_bool srs_amf0_is_string(srs_amf0_t amf0)
|
||||
{
|
||||
SrsAmf0Any* any = (SrsAmf0Any*)amf0;
|
||||
|
@ -625,6 +702,19 @@ srs_amf0_t srs_amf0_object_property_value_at(srs_amf0_t amf0, int index)
|
|||
return (srs_amf0_t)obj->value_at(index);
|
||||
}
|
||||
|
||||
srs_amf0_t srs_amf0_object_property(srs_amf0_t amf0, const char* name)
|
||||
{
|
||||
SrsAmf0Object* obj = (SrsAmf0Object*)amf0;
|
||||
return (srs_amf0_t)obj->get_property(name);
|
||||
}
|
||||
|
||||
void srs_amf0_object_property_set(srs_amf0_t amf0, const char* name, srs_amf0_t value)
|
||||
{
|
||||
SrsAmf0Object* obj = (SrsAmf0Object*)amf0;
|
||||
SrsAmf0Any* any = (SrsAmf0Any*)value;
|
||||
obj->set(name, any);
|
||||
}
|
||||
|
||||
int srs_amf0_ecma_array_property_count(srs_amf0_t amf0)
|
||||
{
|
||||
SrsAmf0EcmaArray * obj = (SrsAmf0EcmaArray*)amf0;
|
||||
|
@ -643,16 +733,36 @@ srs_amf0_t srs_amf0_ecma_array_property_value_at(srs_amf0_t amf0, int index)
|
|||
return (srs_amf0_t)obj->value_at(index);
|
||||
}
|
||||
|
||||
srs_amf0_t srs_amf0_ecma_array_property(srs_amf0_t amf0, const char* name)
|
||||
{
|
||||
SrsAmf0EcmaArray* obj = (SrsAmf0EcmaArray*)amf0;
|
||||
return (srs_amf0_t)obj->get_property(name);
|
||||
}
|
||||
|
||||
void srs_amf0_ecma_array_property_set(srs_amf0_t amf0, const char* name, srs_amf0_t value)
|
||||
{
|
||||
SrsAmf0EcmaArray* obj = (SrsAmf0EcmaArray*)amf0;
|
||||
SrsAmf0Any* any = (SrsAmf0Any*)value;
|
||||
obj->set(name, any);
|
||||
}
|
||||
|
||||
int srs_amf0_strict_array_property_count(srs_amf0_t amf0)
|
||||
{
|
||||
SrsAmf0EcmaArray * obj = (SrsAmf0EcmaArray*)amf0;
|
||||
SrsAmf0StrictArray * obj = (SrsAmf0StrictArray*)amf0;
|
||||
return obj->count();
|
||||
}
|
||||
|
||||
srs_amf0_t srs_amf0_strict_array_property_at(srs_amf0_t amf0, int index)
|
||||
{
|
||||
SrsAmf0EcmaArray* obj = (SrsAmf0EcmaArray*)amf0;
|
||||
return (srs_amf0_t)obj->value_at(index);
|
||||
SrsAmf0StrictArray* obj = (SrsAmf0StrictArray*)amf0;
|
||||
return (srs_amf0_t)obj->at(index);
|
||||
}
|
||||
|
||||
void srs_amf0_strict_array_append(srs_amf0_t amf0, srs_amf0_t value)
|
||||
{
|
||||
SrsAmf0StrictArray* obj = (SrsAmf0StrictArray*)amf0;
|
||||
SrsAmf0Any* any = (SrsAmf0Any*)value;
|
||||
obj->append(any);
|
||||
}
|
||||
|
||||
void __srs_fill_level_spaces(stringstream& ss, int level)
|
||||
|
@ -735,10 +845,14 @@ char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize)
|
|||
memcpy(data, str.data(), str.length());
|
||||
data[str.length()] = 0;
|
||||
|
||||
*pdata = data;
|
||||
*psize = str.length();
|
||||
if (pdata) {
|
||||
*pdata = data;
|
||||
}
|
||||
if (psize) {
|
||||
*psize = str.length();
|
||||
}
|
||||
|
||||
return *pdata;
|
||||
return data;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -165,12 +165,23 @@ int srs_flv_read_header(srs_flv_t flv, char header[9]);
|
|||
int srs_flv_read_tag_header(srs_flv_t flv, char* ptype, int32_t* pdata_size, u_int32_t* ptime);
|
||||
/* read the tag data. drop the 4bytes previous tag size */
|
||||
int srs_flv_read_tag_data(srs_flv_t flv, char* data, int32_t size);
|
||||
/* write flv header to file, auto write the 4bytes zero previous tag size. */
|
||||
int srs_flv_write_header(srs_flv_t flv, char header[9]);
|
||||
/* write flv tag to file, auto write the 4bytes previous tag size */
|
||||
int srs_flv_write_tag(srs_flv_t flv, char type, int32_t time, char* data, int size);
|
||||
/* file stream */
|
||||
/* file stream tellg to get offset */
|
||||
int64_t srs_flv_tellg(srs_flv_t flv);
|
||||
/* seek file stream, offset is form the start of file */
|
||||
void srs_flv_lseek(srs_flv_t flv, int64_t offset);
|
||||
/* error code */
|
||||
/* whether the error code indicates EOF */
|
||||
flv_bool srs_flv_is_eof(int error_code);
|
||||
/* media codec */
|
||||
/* whether the video body is sequence header */
|
||||
flv_bool srs_flv_is_sequence_header(char* data, int32_t size);
|
||||
/* whether the video body is keyframe */
|
||||
flv_bool srs_flv_is_keyframe(char* data, int32_t size);
|
||||
|
||||
/**
|
||||
* amf0 codec
|
||||
|
@ -180,8 +191,14 @@ typedef void* srs_amf0_t;
|
|||
typedef int amf0_bool;
|
||||
typedef double amf0_number;
|
||||
srs_amf0_t srs_amf0_parse(char* data, int size, int* nparsed);
|
||||
srs_amf0_t srs_amf0_create_number(amf0_number value);
|
||||
srs_amf0_t srs_amf0_create_ecma_array();
|
||||
srs_amf0_t srs_amf0_create_strict_array();
|
||||
void srs_amf0_free(srs_amf0_t amf0);
|
||||
void srs_amf0_free_bytes(char* data);
|
||||
/* size and to bytes */
|
||||
int srs_amf0_size(srs_amf0_t amf0);
|
||||
int srs_amf0_serialize(srs_amf0_t amf0, char* data, int size);
|
||||
/* type detecter */
|
||||
amf0_bool srs_amf0_is_string(srs_amf0_t amf0);
|
||||
amf0_bool srs_amf0_is_boolean(srs_amf0_t amf0);
|
||||
|
@ -198,13 +215,18 @@ amf0_number srs_amf0_to_number(srs_amf0_t amf0);
|
|||
int srs_amf0_object_property_count(srs_amf0_t amf0);
|
||||
const char* srs_amf0_object_property_name_at(srs_amf0_t amf0, int index);
|
||||
srs_amf0_t srs_amf0_object_property_value_at(srs_amf0_t amf0, int index);
|
||||
srs_amf0_t srs_amf0_object_property(srs_amf0_t amf0, const char* name);
|
||||
void srs_amf0_object_property_set(srs_amf0_t amf0, const char* name, srs_amf0_t value);
|
||||
/* ecma array value converter */
|
||||
int srs_amf0_ecma_array_property_count(srs_amf0_t amf0);
|
||||
const char* srs_amf0_ecma_array_property_name_at(srs_amf0_t amf0, int index);
|
||||
srs_amf0_t srs_amf0_ecma_array_property_value_at(srs_amf0_t amf0, int index);
|
||||
srs_amf0_t srs_amf0_ecma_array_property(srs_amf0_t amf0, const char* name);
|
||||
void srs_amf0_ecma_array_property_set(srs_amf0_t amf0, const char* name, srs_amf0_t value);
|
||||
/* strict array value converter */
|
||||
int srs_amf0_strict_array_property_count(srs_amf0_t amf0);
|
||||
srs_amf0_t srs_amf0_strict_array_property_at(srs_amf0_t amf0, int index);
|
||||
void srs_amf0_strict_array_append(srs_amf0_t amf0, srs_amf0_t value);
|
||||
/**
|
||||
* human readable print
|
||||
* @param pdata, output the heap data,
|
||||
|
|
|
@ -1113,6 +1113,11 @@ SrsAmf0Any* SrsAmf0StrictArray::at(int index)
|
|||
return properties.at(index);
|
||||
}
|
||||
|
||||
void SrsAmf0StrictArray::append(SrsAmf0Any* any)
|
||||
{
|
||||
properties.push_back(any);
|
||||
}
|
||||
|
||||
int SrsAmf0Size::utf8(string value)
|
||||
{
|
||||
return 2 + value.length();
|
||||
|
|
|
@ -260,6 +260,7 @@ public:
|
|||
virtual int count();
|
||||
// @remark: max index is count().
|
||||
virtual SrsAmf0Any* at(int index);
|
||||
virtual void append(SrsAmf0Any* any);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue