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