8814
- 收藏
- 点赞
- 分享
- 举报
rtmp推流到服务器
大家好,我用rtmp推送H.264+AAC数据到服务器,然后登录客服端看视频的时候发现没声音,然后视频播放延时了十几秒吧,播放速度加快了,就好像快进一样。不知道什么问题。下面是程序
#define AAC_ADTS_HEADER_SIZE 7
static uint32_t find_start_code(uint8_t *buf, uint32_t zeros_in_startcode)
{
uint32_t info;
uint32_t i;
info = 1;
if ((info = (buf[zeros_in_startcode] != 1)? 0: 1) == 0)
return 0;
for (i = 0; i < zeros_in_startcode; i++)
if (buf != 0)
{
info = 0;
break;
};
return info;
}
uint8_t * get_nal(uint32_t *len, uint8_t **offset, uint8_t *start, uint32_t total)
{
uint32_t info;
uint8_t *q ;
uint8_t *p = *offset;
*len = 0;
while(1) {
info = find_start_code(p, 3);
if (info == 1)
break;
p++;
if ((p - start) >= total)
return NULL;
}
q = p + 4;
p = q;
while(1) {
info = find_start_code(p, 3);
if (info == 1)
break;
p++;
if ((p - start) >= total)
return NULL;
}
*len = (p - q);
*offset = p;
return q;
}
uint8_t *get_adts(uint32_t *len, uint8_t **offset, uint8_t *start, uint32_t total)
{
uint8_t *p = *offset;
uint32_t frame_len_1;
uint32_t frame_len_2;
uint32_t frame_len_3;
uint32_t frame_length;
if (total < AAC_ADTS_HEADER_SIZE) {
return NULL;
}
if ((p - start) >= total) {
return NULL;
}
if (p[0] != 0xff) {
return NULL;
}
if ((p[1] & 0xf0) != 0xf0) {
return NULL;
}
frame_len_1 = p[3] & 0x03;
frame_len_2 = p[4];
frame_len_3 = (p[5] & 0xe0) >> 5;
frame_length = (frame_len_1 << 11) | (frame_len_2 << 3) | frame_len_3;
*offset = p + frame_length;
*len = frame_length;
return p;
}
typedef unsigned long ULONG;
typedef unsigned int UINT;
typedef unsigned char BYTE;
int main(int argc, char *argv[])
{
char serverStrBuf[100];
sprintf(serverStrBuf, "rtmp://%s:%s/%s/livestream_chn_%s",argv[1]/*server*/,argv[2]/*port*/,argv[3],/*myapp*/argv[4]/*channel*/);
printf("serverStrBuf is %s\n",serverStrBuf);
char vpipe[15];
char apipe[15];
sprintf(vpipe,"/tmp/vfifoChn%s",argv[4]);
sprintf(apipe,"/tmp/afifoChn%s",argv[4]);
printf("vpipe is %s\n",vpipe);
printf("apipe is %s\n",apipe);
void*prtmp = rtmp_sender_alloc(serverStrBuf/*"rtmp://192.168.2.102:1936/myapp/livestream_chn_1"*/); //return handle
rtmp_sender_start_publish(prtmp, 0, 0);
uint8_t *audio_buf_offset ;
uint32_t audio_len;
uint8_t *p_audio;
int ret = 0;
int vpipeFD = open(vpipe/*"/tmp/vfifoChn1"*/, O_RDONLY|O_NONBLOCK);
if (vpipeFD < 0)
{
printf("open FOR READ failed\n");
}
int apipeFD = open(apipe/*"/tmp/afifoChn1"*/, O_RDONLY|O_NONBLOCK);
if (apipeFD < 0)
{
printf("open FOR aREAD failed\n");
}
ULONG nSampleRate = 8000; // 采样率
UINT nChannels = 1; // 声道数
UINT nBit = 16; // 单样本位数
ULONG nInputSamples = 0; //输入样本数
ULONG nMaxOutputBytes = 0; //输出所需最大空间
ULONG nMaxInputBytes=0; //输入最大字节
faacEncHandle hEncoder; //aac句柄
faacEncConfigurationPtr pConfiguration;//aac设置指针
char* abuffer;
char* vbuffer;
BYTE* pbAACBuffer;
// (1) Open FAAC engine
hEncoder = faacEncOpen(nSampleRate, nChannels, &nInputSamples, &nMaxOutputBytes);//初始化aac句柄,同时获取最大输入样本,及编码所需最小字节
nMaxInputBytes=nInputSamples*nBit/8;//计算最大输入字节,跟据最大输入样本数
printf("nInputSamples:%d nMaxInputBytes:%d nMaxOutputBytes:%d\n", nInputSamples, nMaxInputBytes,nMaxOutputBytes);
if(hEncoder == NULL)
{
printf("[ERROR] Failed to call faacEncOpen()\n");
return -1;
}
pbAACBuffer = (char*)malloc(nMaxOutputBytes);
// (2.1) Get current encoding configuration
pConfiguration = faacEncGetCurrentConfiguration(hEncoder);//获取配置结构指针
pConfiguration->inputFormat = FAAC_INPUT_16BIT;
pConfiguration->outputFormat=1;
pConfiguration->useTns=true;
pConfiguration->useLfe=false;
pConfiguration->aacObjectType=LOW;
pConfiguration->mpegVersion = MPEG4;
pConfiguration->shortctl=SHORTCTL_NORMAL;
pConfiguration->quantqual=60;
pConfiguration->bandWidth=80000;
pConfiguration->bitRate=0;
printf("!!!!!!!!!!!!!pConfiguration->outputFormat is %d\n",pConfiguration->outputFormat);
// (2.2) Set encoding configuration
ret = faacEncSetConfiguration(hEncoder, pConfiguration);//设置配置,根据不同设置,耗时不一样
abuffer = (char*)malloc(nMaxInputBytes);
if(abuffer == NULL)
exit(0);
vbuffer = (char*)malloc(25*1024);
if(vbuffer == NULL)
exit(0);
char* output = (char*)malloc(10*1024);
static unsigned int audioCount = 0;
uint32_t start_time = RTMP_GetTime();
uint32_t timeCount = 0;
timeCount = 0;//RTMP_GetTime();
while (1) {
// timeCount += 0.01;
// start_time += timeCount;
ret = read(vpipeFD, vbuffer, 25 * 1024);
if(ret > 0){
rtmp_sender_write_video_frame(prtmp, vbuffer, ret, timeCount, 0,start_time);
timeCount += 2;
}
ret = read(apipeFD, abuffer, nMaxInputBytes - audioCount);
if(ret >0){
if(audioCount < 1*2048) {
memcpy(output + audioCount,abuffer,ret);
audioCount += ret;
ret = 0;
if(audioCount >= 1*2048){
ret = audioCount;
audioCount = 0;
}
}else{
ret = audioCount;
audioCount = 0;
}
}
if(ret > 0){
nInputSamples = ret/ (nBit / 8);
// (3) Encode
ret = faacEncEncode(hEncoder, (int*) output, nInputSamples, pbAACBuffer, nMaxOutputBytes);
audio_buf_offset = pbAACBuffer;
if (ret > 0){
p_audio = get_adts(&audio_len, &audio_buf_offset, pbAACBuffer, ret);
if (p_audio == NULL){
printf("p_audio is null,this should not happen!!!!\n");
continue;
}
rtmp_sender_write_audio_frame(prtmp, p_audio, audio_len, timeCount,start_time);
}
}
usleep(1);
}
}
#define AAC_ADTS_HEADER_SIZE 7
static uint32_t find_start_code(uint8_t *buf, uint32_t zeros_in_startcode)
{
uint32_t info;
uint32_t i;
info = 1;
if ((info = (buf[zeros_in_startcode] != 1)? 0: 1) == 0)
return 0;
for (i = 0; i < zeros_in_startcode; i++)
if (buf != 0)
{
info = 0;
break;
};
return info;
}
uint8_t * get_nal(uint32_t *len, uint8_t **offset, uint8_t *start, uint32_t total)
{
uint32_t info;
uint8_t *q ;
uint8_t *p = *offset;
*len = 0;
while(1) {
info = find_start_code(p, 3);
if (info == 1)
break;
p++;
if ((p - start) >= total)
return NULL;
}
q = p + 4;
p = q;
while(1) {
info = find_start_code(p, 3);
if (info == 1)
break;
p++;
if ((p - start) >= total)
return NULL;
}
*len = (p - q);
*offset = p;
return q;
}
uint8_t *get_adts(uint32_t *len, uint8_t **offset, uint8_t *start, uint32_t total)
{
uint8_t *p = *offset;
uint32_t frame_len_1;
uint32_t frame_len_2;
uint32_t frame_len_3;
uint32_t frame_length;
if (total < AAC_ADTS_HEADER_SIZE) {
return NULL;
}
if ((p - start) >= total) {
return NULL;
}
if (p[0] != 0xff) {
return NULL;
}
if ((p[1] & 0xf0) != 0xf0) {
return NULL;
}
frame_len_1 = p[3] & 0x03;
frame_len_2 = p[4];
frame_len_3 = (p[5] & 0xe0) >> 5;
frame_length = (frame_len_1 << 11) | (frame_len_2 << 3) | frame_len_3;
*offset = p + frame_length;
*len = frame_length;
return p;
}
typedef unsigned long ULONG;
typedef unsigned int UINT;
typedef unsigned char BYTE;
int main(int argc, char *argv[])
{
char serverStrBuf[100];
sprintf(serverStrBuf, "rtmp://%s:%s/%s/livestream_chn_%s",argv[1]/*server*/,argv[2]/*port*/,argv[3],/*myapp*/argv[4]/*channel*/);
printf("serverStrBuf is %s\n",serverStrBuf);
char vpipe[15];
char apipe[15];
sprintf(vpipe,"/tmp/vfifoChn%s",argv[4]);
sprintf(apipe,"/tmp/afifoChn%s",argv[4]);
printf("vpipe is %s\n",vpipe);
printf("apipe is %s\n",apipe);
void*prtmp = rtmp_sender_alloc(serverStrBuf/*"rtmp://192.168.2.102:1936/myapp/livestream_chn_1"*/); //return handle
rtmp_sender_start_publish(prtmp, 0, 0);
uint8_t *audio_buf_offset ;
uint32_t audio_len;
uint8_t *p_audio;
int ret = 0;
int vpipeFD = open(vpipe/*"/tmp/vfifoChn1"*/, O_RDONLY|O_NONBLOCK);
if (vpipeFD < 0)
{
printf("open FOR READ failed\n");
}
int apipeFD = open(apipe/*"/tmp/afifoChn1"*/, O_RDONLY|O_NONBLOCK);
if (apipeFD < 0)
{
printf("open FOR aREAD failed\n");
}
ULONG nSampleRate = 8000; // 采样率
UINT nChannels = 1; // 声道数
UINT nBit = 16; // 单样本位数
ULONG nInputSamples = 0; //输入样本数
ULONG nMaxOutputBytes = 0; //输出所需最大空间
ULONG nMaxInputBytes=0; //输入最大字节
faacEncHandle hEncoder; //aac句柄
faacEncConfigurationPtr pConfiguration;//aac设置指针
char* abuffer;
char* vbuffer;
BYTE* pbAACBuffer;
// (1) Open FAAC engine
hEncoder = faacEncOpen(nSampleRate, nChannels, &nInputSamples, &nMaxOutputBytes);//初始化aac句柄,同时获取最大输入样本,及编码所需最小字节
nMaxInputBytes=nInputSamples*nBit/8;//计算最大输入字节,跟据最大输入样本数
printf("nInputSamples:%d nMaxInputBytes:%d nMaxOutputBytes:%d\n", nInputSamples, nMaxInputBytes,nMaxOutputBytes);
if(hEncoder == NULL)
{
printf("[ERROR] Failed to call faacEncOpen()\n");
return -1;
}
pbAACBuffer = (char*)malloc(nMaxOutputBytes);
// (2.1) Get current encoding configuration
pConfiguration = faacEncGetCurrentConfiguration(hEncoder);//获取配置结构指针
pConfiguration->inputFormat = FAAC_INPUT_16BIT;
pConfiguration->outputFormat=1;
pConfiguration->useTns=true;
pConfiguration->useLfe=false;
pConfiguration->aacObjectType=LOW;
pConfiguration->mpegVersion = MPEG4;
pConfiguration->shortctl=SHORTCTL_NORMAL;
pConfiguration->quantqual=60;
pConfiguration->bandWidth=80000;
pConfiguration->bitRate=0;
printf("!!!!!!!!!!!!!pConfiguration->outputFormat is %d\n",pConfiguration->outputFormat);
// (2.2) Set encoding configuration
ret = faacEncSetConfiguration(hEncoder, pConfiguration);//设置配置,根据不同设置,耗时不一样
abuffer = (char*)malloc(nMaxInputBytes);
if(abuffer == NULL)
exit(0);
vbuffer = (char*)malloc(25*1024);
if(vbuffer == NULL)
exit(0);
char* output = (char*)malloc(10*1024);
static unsigned int audioCount = 0;
uint32_t start_time = RTMP_GetTime();
uint32_t timeCount = 0;
timeCount = 0;//RTMP_GetTime();
while (1) {
// timeCount += 0.01;
// start_time += timeCount;
ret = read(vpipeFD, vbuffer, 25 * 1024);
if(ret > 0){
rtmp_sender_write_video_frame(prtmp, vbuffer, ret, timeCount, 0,start_time);
timeCount += 2;
}
ret = read(apipeFD, abuffer, nMaxInputBytes - audioCount);
if(ret >0){
if(audioCount < 1*2048) {
memcpy(output + audioCount,abuffer,ret);
audioCount += ret;
ret = 0;
if(audioCount >= 1*2048){
ret = audioCount;
audioCount = 0;
}
}else{
ret = audioCount;
audioCount = 0;
}
}
if(ret > 0){
nInputSamples = ret/ (nBit / 8);
// (3) Encode
ret = faacEncEncode(hEncoder, (int*) output, nInputSamples, pbAACBuffer, nMaxOutputBytes);
audio_buf_offset = pbAACBuffer;
if (ret > 0){
p_audio = get_adts(&audio_len, &audio_buf_offset, pbAACBuffer, ret);
if (p_audio == NULL){
printf("p_audio is null,this should not happen!!!!\n");
continue;
}
rtmp_sender_write_audio_frame(prtmp, p_audio, audio_len, timeCount,start_time);
}
}
usleep(1);
}
}
我来回答
回答6个
时间排序
认可量排序
认可0
认可0
认可0
认可0
认可0
认可0
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币
Markdown 语法
- 加粗**内容**
- 斜体*内容*
- 删除线~~内容~~
- 引用> 引用内容
- 代码`代码`
- 代码块```编程语言↵代码```
- 链接[链接标题](url)
- 无序列表- 内容
- 有序列表1. 内容
- 缩进内容
- 图片![alt](url)
相关问答
-
2017-09-15 10:56:53
-
22020-09-15 14:23:18
-
2017-02-20 12:33:53
-
2023-04-11 08:45:59
-
2020-11-24 17:34:06
-
32016-08-09 11:49:44
-
2014-10-24 08:55:49
-
2017-10-27 11:03:39
-
2015-07-31 19:36:12
-
2014-10-22 11:14:46
-
2020-10-02 12:56:51
-
2015-05-30 12:15:54
-
2019-01-10 10:09:57
-
2017-02-09 13:10:47
-
2020-07-24 18:47:29
-
2017-02-09 13:12:22
-
2016-04-07 12:17:25
-
2017-02-09 13:10:06
-
2016-03-21 10:25:48
无更多相似问答 去提问
点击登录
-- 积分
-- E币
提问
—
收益
—
被采纳
—
我要提问
切换马甲
上一页
下一页
悬赏问答
-
5Hi3516CV610 如何使用SD卡升级固件
-
5cat /dev/logmpp 报错 <3>[ vi] [func]:vi_send_frame_node [line]:99 [info]:vi pic queue is full!
-
50如何获取vpss chn的图像修改后发送至vo
-
5FPGA通过Bt1120传YUV422数据过来,vi接收不到数据——3516dv500
-
50SS928 运行PQtools 拼接 推到设备里有一半画面会异常
-
53536AV100的sample_vdec输出到CVBS显示
-
10海思板子mpp怎么在vi阶段改变视频数据尺寸
-
10HI3559AV100 多摄像头同步模式
-
9海思ss928单路摄像头vio中加入opencv处理并显示
-
10EB-RV1126-BC-191板子运行自己编码的程序
举报反馈
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明
提醒
你的问题还没有最佳答案,是否结题,结题后将扣除20%的悬赏金
取消
确认
提醒
你的问题还没有最佳答案,是否结题,结题后将根据回答情况扣除相应悬赏金(1回答=1E币)
取消
确认