Firefly1126移植rtmp推流器到RKMedia源码库中
Firefly1126移植rtmp推流器到RKMedia源码库中
1,桌面上新建一个librtmp文件夹,在其中放入srs-librtmp.a和srs-librtmp.h两个文件及libssl.a,libcrypto.a两个文件 ,文件分别来自
/home/kxq/Desktop/srs.oschina/trunk/objs/lib
/home/kxq/Desktop/srs.oschina/trunk/objs/include
/home/kxq/Desktop/srs.oschina/trunk/objs/openssl/lib
2,将librtmp文件夹放入RkMedia文件夹下,文件夹位置
/home/kxq/Desktop/rv1126_rv1109_linux_release_20210306/external/rkmedia/examples
3,新建一个rkmedia_vi_venc_rtmp_test.c文件,在其中编入srs-librtmp.a库,并将srs-librtmp.a文件改名为librtmp.a,使用rtmp推流
首先在同一目录下的cmakelist.txt文件中添加c文件的信息如下 :
#--------------------------
# rkmedia_vi_venc_rtmp_test
#--------------------------
link_directories("/home/kxq/Desktop/rv1126_rv1109_linux_release_20210306/external/rkmedia/examples/librtmp/")
add_executable(rkmedia_vi_venc_rtmp_test rkmedia_vi_venc_rtmp_test.c ${COMMON_SRC})
add_dependencies(rkmedia_vi_venc_rtmp_test easymedia)
target_link_libraries(rkmedia_vi_venc_rtmp_test easymedia
rtmp -ldl -lstdc++ -lm
ssl -ldl -lstdc++ -lm
crypto -ldl -lstdc++ -lm)
target_include_directories(rkmedia_vi_venc_rtmp_test PRIVATE ${CMAKE_SOURCE_DIR}/include)
install(TARGETS rkmedia_vi_venc_rtmp_test RUNTIME DESTINATION "bin")
4,参考rkmedia_vi_venc_rtmp_test.c和srs_h264_raw_publish.c加入rtmp的推流程序,rkmedia_vi_venc_rtmp_test.c文件中主要做了以下改动
首先在头文件中加入rtmp库引用位置
#include "librtmp/srs_librtmp.h"
再加入rtmp推流所用全局变量
static srs_rtmp_t rtmp = NULL;
static int dts,pts = 0;
加入推流代码
void push_rtmp_stream(srs_rtmp_t rtmp_input, MEDIA_BUFFER mb, int dts_input, int pts_input){
char* h264_raw = (char*)RK_MPI_MB_GetPtr(mb);
if(h264_raw != NULL){
// send out the h264 packet over RTMP
int ret = srs_h264_write_raw_frames(rtmp_input, h264_raw, RK_MPI_MB_GetSize(mb), dts_input, pts_input);
//printf("ret = %d\n",ret);
if (ret != 0) {
if (srs_h264_is_dvbsp_error(ret)) {
srs_human_trace("ignore drop video error, code=%d", ret);
} else if (srs_h264_is_duplicated_sps_error(ret)) {
srs_human_trace("ignore duplicated sps, code=%d", ret);
} else if (srs_h264_is_duplicated_pps_error(ret)) {
srs_human_trace("ignore duplicated pps, code=%d", ret);
} else {
srs_human_trace("send h264 raw data failed. ret=%d", ret);
srs_rtmp_destroy(rtmp);
return ;
}
}
}
usleep(10 * 1000);
}
将回调函数中改为
void video_packet_cb(MEDIA_BUFFER mb) {
static RK_S32 packet_cnt = 0;
double fps_rtmp = 25;
if (quit)
return;
printf("#Get packet-%d, size %zu\n", packet_cnt, RK_MPI_MB_GetSize(mb));
push_rtmp_stream(rtmp, mb, dts, pts);
RK_MPI_MB_ReleaseBuffer(mb);
dts += 1000 / fps_rtmp;
pts = dts;
packet_cnt++;
}
在Main函数中加入rtmp握手初始化相关代码
// init rtsp
//g_rtsplive = create_rtsp_demo(554);
//g_rtsp_session = rtsp_new_session(g_rtsplive, "/live/main_stream");
//init rtmp
printf("Example for srs-librtmp\n");
printf("SRS(ossrs) client librtmp library.\n");
printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision());
// connect rtmp context
const char* rtmp_url = "rtmp://公网rtmp服务器IP:端口/live/livestream";
rtmp = srs_rtmp_create(rtmp_url);
if (srs_rtmp_handshake(rtmp) != 0) {
srs_human_trace("simple handshake failed.");
srs_rtmp_destroy(rtmp);
return 0;
}
srs_human_trace("simple handshake success");
if (srs_rtmp_connect_app(rtmp) != 0) {
srs_human_trace("connect vhost/app failed.");
srs_rtmp_destroy(rtmp);
return 0;
}
srs_human_trace("connect vhost/app success");
if (srs_rtmp_publish_stream(rtmp) != 0) {
srs_human_trace("publish stream failed.");
srs_rtmp_destroy(rtmp);
return 0;
}
srs_human_trace("publish stream success");
在主函数退出时注销rtmp推流服务
srs_rtmp_destroy(rtmp);
5,编译程序指令如下
# SDK根目录,选择环境
source envsetup.sh firefly_rv1126_rv1109
# 重编rkmedia源码
make rkmedia-dirclean && make rkmedia
# rkmedia库/程序打包到文件系统(oem.img)
./build.sh rootfs
# 重新烧写oem.img,若有其他基础包配置更新(如ffmpeg),则需要重烧rootfs.img
或者执行完前两步后,在SDK/buildroot/output/firefly_rv1126_rv1109/oem/usr/bin目录下找到rkmedia_vi_venc_rtmp_test二进制可执行程序,移动到板子某一个目录下,再进行测试。
测试代码
./rkmedia_vi_venc_rtmp_test -w 640 -h 480 -d /dev/video25
拉流代码
vlc rtmp://公网rtmp服务器IP:端口/live/livestream
注:不要用vlc获取rtmp流,在window下下载OBS软件点击媒体源,设置中将本地文件勾选去掉,在输入中输入rtmp://公网rtmp服务器IP:端口/live/livestream,之后点击确认开始拉流。