Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Publishing a stream using librtmp in C/C++

Tags:

rtmp

How to publish a stream using librtmp library? I read the librtmp man page and for publishing , RTMP_Write() is used.

I am doing like this.

//Code
//Init RTMP code
RTMP *r;
char uri[]="rtmp://localhost:1935/live/desktop";
r= RTMP_Alloc();
RTMP_Init(r);
RTMP_SetupURL(r, (char*)uri);
RTMP_EnableWrite(r);
RTMP_Connect(r, NULL);
RTMP_ConnectStream(r,0);

Then to respond to ping/other messages from server, I am using a thread to respond like following:

//Thread
While (ThreadIsRunning && RTMP_IsConnected(r) && RTMP_ReadPacket(r, &packet))
{
   if (RTMPPacket_IsReady(&packet))
   {
 if (!packet.m_nBodySize)
         continue;
    RTMP_ClientPacket(r, &packet); //This takes care of handling ping/other messages
    RTMPPacket_Free(&packet);
   }
}

After this I am stuck at how to use RTMP_Write() to publish a file to Wowza media server?

like image 446
dhruva Avatar asked Dec 24 '10 06:12

dhruva


1 Answers

In my own experience, streaming video data to an RTMP server is actually pretty simple on the librtmp side. The tricky part is to correctly packetize video/audio data and read it at the correct rate.

Assuming you are using FLV video files, as long as you can correctly isolate each tag in the file and send each one using one RTMP_Write call, you don't even need to handle incoming packets.

The tricky part is to understand how FLV files are made. The official specification is available here: http://www.adobe.com/devnet/f4v.html

First, there's a header, that is made of 9 bytes. This header must not be sent to the server, but only read through in order to make sure the file is really FLV.

Then there is a stream of tags. Each tag has a 11 bytes header that contains the tag type (video/audio/metadata), the body length, and the tag's timestamp, among other things.

The tag header can be described using this structure:

typedef struct __flv_tag {
  uint8       type;
  uint24_be   body_length; /* in bytes, total tag size minus 11 */
  uint24_be   timestamp; /* milli-seconds */
  uint8       timestamp_extended; /* timestamp extension */
  uint24_be   stream_id; /* reserved, must be "\0\0\0" */
  /* body comes next */
} flv_tag;

The body length and timestamp are presented as 24-bit big endian integers, with a supplementary byte to extend the timestamp to 32 bits if necessary (that's approximatively around the 4 hours mark).

Once you have read the tag header, you can read the body itself as you now know its length (body_length).

After that there is a 32-bit big endian integer value that contains the complete length of the tag (11 bytes + body_length).

You must write the tag header + body + previous tag size in one RTMP_Write call (else it won't play).

Also, be careful to send packets at the nominal frame rate of the video, else playback will suffer greatly.

I have written a complete FLV file demuxer as part of my GPL project FLVmeta that you can use as reference.

like image 73
SirDarius Avatar answered Sep 25 '22 20:09

SirDarius