我正在尝试使用 librtmp 库,它可以很好地提取流。但现在我正在尝试发布一个流,为此我相信我必须使用 RTMP_Write 函数。
我在这里要完成的是一个简单的 c++ 程序,它将从文件中读取并尝试将流推送到 crtmp 服务器。连接和流创建都可以,但是我对使用 RTMP_Write 感到很困惑。
这是我所做的:
int Upload(RTMP * rtmp, FILE * file){
int nRead = 0;
unsigned int nWrite = 0;
int diff = 0;
int bufferSize = 64 * 1024;
int byteSum = 0;
int count = 0;
char * buffer;
buffer = (char *) malloc(bufferSize);
do{
nRead = fread(buffer+diff,1,bufferSize-diff,file);
if(nRead != bufferSize){
if(feof(file)){
RTMP_LogPrintf("End of file reached!\n");
break;
}else if(ferror(file)){
RTMP_LogPrintf("Error reading from file stream detected\n");
break;
}
}
count += 1;
byteSum += nRead;
RTMP_LogPrintf("Read %d from file, Sum: %d, Count: %d\n",nRead,byteSum,count);
nWrite = RTMP_Write(rtmp,buffer,nRead);
if(nWrite != nRead){
diff = nRead - nWrite;
memcpy(buffer,(const void*)(buffer+bufferSize-diff),diff);
}
}while(!RTMP_ctrlC && RTMP_IsConnected(rtmp) && !RTMP_IsTimedout(rtmp));
free(buffer);
return RD_SUCCESS;
}
在这个上传函数中,我收到了已经初始化的 RTMP 结构和一个指向打开文件的指针。
这实际上有效,我可以看到正在显示一些视频,但它很快就会丢失并停止发送包裹。我设法理解,每当我设置的缓冲区(我随机要求为 64k,没有特殊原因)碰巧拆分 flv 标记(http://osflash.org/flv#flv_format)时,就会发生这种情况新包。
为此,我修改了 RTMP_Write 函数并告诉它验证它是否能够解码整个 flv 标签(数据包类型、正文大小、时间戳等),如果不能,那么它应该只返回数量缓冲区中剩余的有用字节。
if(s2 - 11 <= 0){
rest = size - s2;
return rest;
}
上面的代码注意到了这一点,如果 RTMP_Write 返回的值不是它应该发送的字节数,那么它知道该值是缓冲区中剩余的有用字节数。然后我将这些字节复制到缓冲区的开头并从文件中读取更多内容。
但是我一直遇到问题,所以我想知道:这个函数的正确用法是什么?是否有我应该使用的特定缓冲区值?(不这么认为)还是它本身就是越野车?