高站网站建设,版面设计教案,郑州网页网站制作,用.aspx做网站若该文为原创文章#xff0c;转载请注明原文出处。 T31使用librtmp拉流并保存成FLV文件或H264和AAC文件。
librtmp编译在前面有教程#xff0c;自行编译。
实现的目的是想要获取获取rtmp的AAC流并播放#xff0c;实时双向对讲功能。 一、硬件和开发环境 1、硬件#xff1…若该文为原创文章转载请注明原文出处。 T31使用librtmp拉流并保存成FLV文件或H264和AAC文件。
librtmp编译在前面有教程自行编译。
实现的目的是想要获取获取rtmp的AAC流并播放实时双向对讲功能。 一、硬件和开发环境 1、硬件T31XSC5235
2、开发环境 ubuntu16.04-64bit
3、编译器mips-gcc540-glibc222-32bit-r3.3.0.tar.gz
注板子和和WIFI模块是某淘上淘的使用的是RTL8188使用的是USB接口uboot和内核是自己裁剪移植的内核默认自带WIFI驱动所以不用移植可以直接使用。
二、使用librtmp拉流流程
初使化RTMP上下文设置拉流地址连接服务器连接流地址循环拉流提取媒体数据保存为文件或者交给解码模块拉流完毕释放资源
三、代码解析
编译代码需要用到的库本人在T31上使用的是静态库可以自行改成动态库以减少编译文件的大小 。
编译所需的库有librtmp.a、libssl.a、libcrypto.a、libz.a
下面这个例子演示了使用librtmp库从服务器拉流到本地保存为flv文件或是h264和aac文件代码如下
/*!******************************************************************************* Copyright ? 2017-2018 yifeng. All Rights Reserved.** \file main.c* \author yifeng* \version 1.0* \date 2022年3月3日* \brief rtmp测试代码**----------------------------------------------------------------------------* \attention********************************************************************************//*****************************************************************************change history: 1.date : 2022年3月3日author: yifengchange: create file*****************************************************************************/#include stdio.h
#include stdlib.h
#include string.h
#include fcntl.h
#include limits.h
#include sys/types.h
#include sys/stat.h
#include arpa/inet.h
#include sys/select.h
#include sys/time.h
#include time.h
#include unistd.h
#include signal.h
#include sys/ioctl.h
#include net/if.h
#include netinet/in.h
#include pthread.h
#include stdbool.h/* 环形队列头文件 */
#include xiecc_rtmp.h
#include rtmp.htypedef unsigned long ULONG;
typedef unsigned int UINT;
typedef unsigned char BYTE;
typedef char _TCHAR;uint8_t nalu_header[4] { 0x00, 0x00, 0x00, 0x01 };/*!* \fn main* \brief 主函数* * \param [in] int argc #* \param [in] char *argv[] #* * \retval int*/
int main(int argc, char *argv[])
{ uint16_t object_type 0;uint16_t sample_frequency_index 0;uint8_t channels 0;uint8_t frame_length_flag 0;uint8_t depend_on_core_coder 0;uint8_t extension_flag 0;// 初使化RTMP上下文RTMP* pRTMP RTMP_Alloc();RTMP_Init(pRTMP);// 设置拉流地址RTMP_SetupURL(pRTMP, (char*)rtmp://192.168.0.109/live/stream);// 连接服务器pRTMP-Link.timeout 10;pRTMP-Link.lFlags | RTMP_LF_LIVE;bool b RTMP_Connect(pRTMP, NULL);if (!b){printf(connect failed! \n);return -1;}// 连接流地址b RTMP_ConnectStream(pRTMP, 0);if (!b){printf(connect stream failed! \n);return -1;}bool bSaveFlv false; // 保存成FLV格式FILE *pFile fopen(testrtmp.flv, wb);FILE *h264_file_ptr fopen(testrtmp.h264, wb);FILE *aac_file_ptr fopen(testrtmp.aac, wb);while (RTMP_IsConnected(pRTMP)){if (bSaveFlv true){char sBuf[4096] {0};int bytes RTMP_Read(pRTMP, sBuf, sizeof(sBuf));printf(RTMP_Read() ret:[%d] \n, bytes);if (bytes 0)break;fwrite(sBuf, 1, bytes, pFile);}else{RTMPPacket packet;RTMPPacket_Reset(packet);packet.m_body NULL;packet.m_chunk NULL;b RTMP_ReadPacket(pRTMP, packet);if (b 0)break;if (0 b )continue;if (RTMPPacket_IsReady(packet)){RTMP_ClientPacket(pRTMP, packet);if (packet.m_packetType RTMP_PACKET_TYPE_VIDEO){bool keyframe 0x17 packet.m_body[0] ? true : false;bool sequence 0x00 packet.m_body[1];printf(keyframe%s, sequence%s\n, keyframe ? true : false, sequence ? true : false);// SPS/PPS sequenceif (sequence){uint32_t offset 10;uint32_t sps_num packet.m_body[offset] 0x1f;for (int i 0; i sps_num; i) {uint8_t ch0 packet.m_body[offset];uint8_t ch1 packet.m_body[offset 1];uint32_t sps_len ((ch0 8) | ch1);offset 2;// Write sps dataprintf(Write sps data len: %d\n, sps_len);fwrite(nalu_header, sizeof(uint8_t), 4, h264_file_ptr);fwrite(packet.m_body offset, sizeof(uint8_t), sps_len, h264_file_ptr);offset sps_len;}uint32_t pps_num packet.m_body[offset] 0x1f;for (int i 0; i pps_num; i) {uint8_t ch0 packet.m_body[offset];uint8_t ch1 packet.m_body[offset 1];uint32_t pps_len ((ch0 8) | ch1);offset 2;// Write pps dataprintf(Write pps data len: %d\n, pps_len);fwrite(nalu_header, sizeof(uint8_t), 4, h264_file_ptr);fwrite(packet.m_body offset, sizeof(uint8_t), pps_len, h264_file_ptr);offset pps_len;}}// Nalu frameselse{uint32_t offset 5;uint8_t ch0 packet.m_body[offset];uint8_t ch1 packet.m_body[offset 1];uint8_t ch2 packet.m_body[offset 2];uint8_t ch3 packet.m_body[offset 3];uint32_t data_len ((ch0 24) | (ch1 16) | (ch2 8) | ch3);offset 4;// Write nalu data(already started with 0x00,0x00,0x00,0x01)printf(Write nalu data len: %d\n, data_len);fwrite(nalu_header, sizeof(uint8_t), 4, h264_file_ptr);fwrite(packet.m_body offset, sizeof(uint8_t), data_len, h264_file_ptr);offset data_len;}}else if (packet.m_packetType RTMP_PACKET_TYPE_AUDIO){bool sequence 0x00 packet.m_body[1];printf(sequence%s\n, sequence ? true : false);// AAC sequenceif (sequence) {uint8_t format (packet.m_body[0] 0xf0) 4;uint8_t samplerate (packet.m_body[0] 0x0c) 2;uint8_t sampledepth (packet.m_body[0] 0x02) 1;uint8_t type packet.m_body[0] 0x01;// sequence packet.m_body[1];// AAC(AudioSpecificConfig)if (format 10){uint8_t ch0 packet.m_body[2];uint8_t ch1 packet.m_body[3];uint16_t config ((ch0 8) | ch1);object_type (config 0xF800) 11;sample_frequency_index (config 0x0780) 7;channels (config 0x78) 3;frame_length_flag (config 0x04) 2;depend_on_core_coder (config 0x02) 1;extension_flag config 0x01;}// Speex(Fix data here, so no need to parse...)else if (format 11) {// 16 KHz, mono, 16bit/sampletype 0;sampledepth 1;samplerate 4;}}// Audio frameselse {// ADTS(7 bytes) AAC datauint32_t data_len packet.m_nBodySize - 2 7;uint8_t adts[7];adts[0] 0xff;adts[1] 0xf1;adts[2] ((object_type - 1) 6) | (sample_frequency_index 2) | (channels 2);adts[3] ((channels 3) 6) (data_len 11);adts[4] (data_len 0x7FF) 3;adts[5] ((data_len 7) 5) 0x1F;adts[6] 0xfc;// Write audio framesprintf(Write audio frames len: %d\n, packet.m_nBodySize - 2);fwrite(adts, sizeof(uint8_t), 7, aac_file_ptr);fwrite(packet.m_body 2, sizeof(uint8_t), packet.m_nBodySize - 2, aac_file_ptr);}}else if (packet.m_packetType RTMP_PACKET_TYPE_INFO) {// TODO:// ...printf(RTMP_PACKET_TYPE_INFO1\n);}else {// TODO:// ...printf(RTMP_PACKET_TYPE_INFO2\n);}}RTMPPacket_Free(packet);}}fclose(pFile);RTMP_Close(pRTMP);RTMP_Free(pRTMP);return 0;
}
定义了bSaveFlv标记是否保存成flv文件true保存成flv文件否则保存成aac和h264
rtmp的Url需要根据自己的服务器修改。
四、测试结果
执行后在当前目录下生成264和aac文件 把文件复制到pc端用vlc播放 使用librtmp拉流网友説会有问题目前测试是正常有遇到的网友麻烦告知一下。谢谢。 如有侵权或需要完整代码请及时联系博主。