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,之后點擊確認開始拉流。