RTP打包G711音频数据发送

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hiwubihe/article/details/84569152

前面博客讲过G711编码,有两种G711A/G711U,主要在安防中应用,是一帧波形编码的音频数据,只是将PCM压缩一半数据量。一般G711,采样率8000,通道数1。所以G711中1B就是一个样本数据。G711打包RTP非常简单,只要在G711数据前加上RTP头即可。G711没有想AAC那样,按照帧一帧一帧发送,而是设定一个打包频率,打包频率有10ms,20ms,30ms,40ms 等。如40ms的打包频率,1S打包25帧,1S需要发送8000个样本,所以一帧需要8000/25=320个样本,RTP时间戳增量绝对值是320/8000S,协议要求以采样率作为时钟频率,所以RTP时间戳为 (320/8000)*8000。

负载类型定义如下:

enum RTP_PAYLOAD_TYPE
{
	RTP_PAYLOAD_TYPE_PCMU    = 0,
	RTP_PAYLOAD_TYPE_PCMA    = 8,
	RTP_PAYLOAD_TYPE_JPEG    = 26,
	RTP_PAYLOAD_TYPE_H264    = 96,
	RTP_PAYLOAD_TYPE_H265    = 97,
	RTP_PAYLOAD_TYPE_OPUS    = 98,
	RTP_PAYLOAD_TYPE_AAC     = 99,
	RTP_PAYLOAD_TYPE_G726    = 100,
	RTP_PAYLOAD_TYPE_G726_16 = 101,
	RTP_PAYLOAD_TYPE_G726_24 = 102,
	RTP_PAYLOAD_TYPE_G726_32 = 103,
	RTP_PAYLOAD_TYPE_G726_40 = 104,
	RTP_PAYLOAD_TYPE_SPEEX   = 105,
};

RTP打包格式

12BRTP头

G711 负载

DEMO程序采用JRTPLIB实现 ,把G711音频数据打包成RTP发送到指定端口。


#include <rtpsession.h>
#include <rtpudpv4transmitter.h>
#include <rtpipv4address.h>
#include <rtpsessionparams.h>
#include <rtperrors.h>
#include <rtplibraryversion.h>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>


using namespace jrtplib;

uint16_t iLocalPort = 6666;
uint16_t iDestPort  = 12000;
uint8_t  szDestAddr[]={192, 168, 1, 108};

FILE *pG711File = NULL;




void checkerror(int rtperr)
{
	if (rtperr < 0)
	{
		std::cout << "ERROR: " << RTPGetErrorString(rtperr) << std::endl;
		exit(-1);
	}
}


void rtpPrintf(uint8_t *buf, uint16_t len)
{
	uint16_t i=0;

	printf("RTP len=%d : \n", len);

	for(i=0; i<len; i++)
	{
		printf(" %02X", buf[i]);
		if(i%32 == 31)
			printf("\n");
	}

	printf("\n");
}


int main(void)
{
	int status;

	RTPSession sess;



	RTPUDPv4TransmissionParams transparams;
	RTPSessionParams sessparams;

	/* set g711a param */
	sessparams.SetUsePredefinedSSRC(true);
	sessparams.SetOwnTimestampUnit(1.0/8000.0);
	sessparams.SetAcceptOwnPackets(true);

	transparams.SetPortbase(iLocalPort);
	status = sess.Create(sessparams,&transparams);
	checkerror(status);

	RTPIPv4Address addr(szDestAddr,iDestPort);
	status = sess.AddDestination(addr);
	checkerror(status);

	//时间戳
	sess.SetDefaultTimestampIncrement(320);
	//PCMA
	sess.SetDefaultPayloadType(8);
	sess.SetDefaultMark(true);


	pG711File = fopen("./test.g711", "rb");
	if(!pG711File)
	{
		printf("error: can not open file !\n");

		return 0;
	}

	uint16_t iReadLen = 0;
	uint8_t  szBuf[1024] = {0};

	while( !feof(pG711File) )
	{
		iReadLen = fread(szBuf, 1, 320, pG711File);
		//rtpPrintf(buf, read_len);

		status = sess.SendPacket(szBuf, iReadLen, 8, true, 320);
		checkerror(status);

		RTPTime::Wait(0.03);
	}
	fclose(pG711File);

	return 0;
}


编译环境 CentOs6.5,Debug目录运行“make clean;make”重新编译,”./run.sh“运行即可。

测试运行 RTP发送的目标机器上运行VLC,打开test.sdp即可播放G711音频数据。

播放器播放首先播放器要知道采用的接受协议,从哪个端口接受,是什么编码的数据,这些数据信息是通过SDP文件传递给VLC的。如果采用其他协议RTSP/SIP等,在播放之前会进行信令交互,这种情况是通过信令传递SDP信息的。SDP说明如下:

G711文件打开

G711文件不知道怎么播放,可以用audacity.exe打开,打开方式如下图即可播放。

CSDN下载地址:https://download.csdn.net/download/hiwubihe/10811502

猜你喜欢

转载自blog.csdn.net/hiwubihe/article/details/84569152