medooze的mcu源码还是比较好理解的,目录清晰,代码结构也不复杂,适合用来做mcu框架的参考!
1、使用svn下载完整的mcu源码,参考http://medooze.com/products/mcu.aspx了解mcu的架构和功能;
svn checkout https://svn.code.sf.net/p/mcumediaserver/code/trunk mcumediaserver-code
2、修改配置文件:
[root@ff353cc400a7 mcu]# cat config.mk
#################################
# Config file
##################################
LOG = yes
DEBUG = yes
SANITIZE = no
STATIC = no
VADWEBRTC = yes
SRCDIR = /usr/local/src/medooze/mcu
TARGET = /usr/local
IMAGEMAGICK = yes
CEF = no
CEF_DIR = /usr/local/src/cef_3.2478.1316/
主要将config.mk中SRCDIR修改为你下载的medooze源码路径;
3、安装依赖包:
你也可以尝试性的在mcu路径下执行make,会提示你缺少依赖包,逐个安装就可以,我下载的依赖包主要包括:
mp4v2-master
texinfo-6.5
pjproject-2.4.5
xmlrpc-c
libsrtp-master
libgpg-error-1.30
libgcrypt-libgcrypt-1.8.5.zip
x264
ffmpeg-2.6.1.tar.gz
automake-1.16.tar.xz
ImageMagick.tar.gz
如果安装完了还是提示找不到安装包,可以修改LD_LOAD_PATH或者拷贝pkgconfig文件解决;
cp /usr/local/lib/pkgconfig/Magick++.pc /usr/local/lib/pkgconfig/ImageMagick++.pc
4、编译,正常的话make就成功了,输出如下类似的日志:
[0x7f07646ab1c0][1589007736.067][DBG][VP9PayloadDescription/]
[0x7f07646ab1c0][1589007736.067][DBG][0000] [0x02 0x80 0x01 0xe0 .... ]
[0x7f07646ab1c0][1589007736.067][DBG][0000] [0x8a 0x80 0x2a 0x18 0x02 0x80 0x01 0xe0 ..*.....]
[0x7f07646ab1c0][1589007736.067][DBG][0008] [0x01 0x04 0x01 ... ]
[0x7f07646ab1c0][1589007736.067][DBG][0000] [0x8a 0x2a 0x18 0x02 0x80 0x01 0xe0 0x01 .*......]
[0x7f07646ab1c0][1589007736.067][DBG][0008] [0x04 0x01 .. ]
[0x7f07646ab1c0][1589007736.067][LOG]
[0x7f07646ab1c0][1589007736.067][LOG]
5、单独mcu的使用,medooze使用mcu是配合web-java后台服务来使用的,其实可以考虑单独来使用mcu的服务,并且mcu提供了基于xml-rpc的接口,所以可以封装xml-rpc的客户端结合实现使用mcu服务;
启动mcu
[root@ff353cc400a7 mcu]# ./bin/debug/mcu
[0x7f9ae1c60700][1589008217.498][LOG]>Run RTMP Server [0x7fff32269180]
[0x7f9aebe901c0][1589008217.498][LOG]>Run XML RPC Server [0.0.0.0:8080]
[0x7f9aebe901c0][1589008217.498][LOG]-Handler on /upload/mcu/app/
[0x7f9aebe901c0][1589008217.498][LOG]-Handler on /stream
[0x7f9aebe901c0][1589008217.498][LOG]-Handler on /status
[0x7f9aebe901c0][1589008217.498][LOG]-Handler on /mediagateway
[0x7f9aebe901c0][1589008217.498][LOG]-Handler on /mcu
[0x7f9aebe901c0][1589008217.498][LOG]-Handler on /jsr309
[0x7f9aebe901c0][1589008217.498][LOG]-Handler on /events/mcu
[0x7f9aebe901c0][1589008217.498][LOG]-Handler on /events/jsr309
[0x7f9aebe901c0][1589008217.498][LOG]-Handler on /broadcaster
主要监听了三个端口:
[root@ff353cc400a7 ~]# netstat -pan|grep mc
tcp 0 0 0.0.0.0:1935 0.0.0.0:* LISTEN 3615/./bin/debug/mc
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 3615/./bin/debug/mc
tcp 0 0 0.0.0.0:9090 0.0.0.0:* LISTEN 3615/./bin/debug/mc
8080用来做xml-rpc的接口
6、使用xml-rpc创建客户端进行接口测试:#include "pch.h"
#include
using namespace std;
#include "xmlrpc-c/util.h"
#include "xmlrpc-c/base.h"
#include "xmlrpc-c/client.h"
#include "xmlrpc-c/client_global.h"
#define NAME "XML-RPC getSumAndDifference C Client"
#define VERSION "0.1"
#define SERVER_URL "http://11.12.117.200:8080/mediagateway"
#define H264_PAYLOAD 99
#define AAC_PAYLOAD 97
static void
die_if_fault_occurred(xmlrpc_env * const envP) {
if (envP->fault_occurred) {
fprintf(stderr, "XML-RPC Fault: %s (%d)\n",
envP->fault_string, envP->fault_code);
exit(1);
}
}
int StartSendingVideo(xmlrpc_env &env, int sessionId) {
xmlrpc_value *result = NULL;
xmlrpc_value *resultA = NULL;
xmlrpc_int32 return_code = 0, id = 0, difference = 0;
xmlrpc_value *rtpMap = xmlrpc_build_value(&env, "{}");
xmlrpc_value *rtpAudio = xmlrpc_build_value(&env, "i", AAC_PAYLOAD);
xmlrpc_value *rtpVideo = xmlrpc_build_value(&env, "i", H264_PAYLOAD);
xmlrpc_struct_set_value(&env, rtpMap, "0", rtpAudio);
xmlrpc_struct_set_value(&env, rtpMap, "96", rtpVideo);
/* Call our XML-RPC server. */
result = xmlrpc_client_call(&env, SERVER_URL,
"StartSendingVideo", "(isiS)",
sessionId, "11.12.112.10", 18080, rtpMap);
die_if_fault_occurred(&env);
/* Parse our result value. */
xmlrpc_parse_value(&env, result, "{s:i,*}",
"returnCode", &return_code);
die_if_fault_occurred(&env);
/* Print out our sum and difference. */
printf("StartSendingVideo return_code: %d \n", (int)return_code);
/* Dispose of our result value. */
xmlrpc_DECREF(result);
return return_code;
}
int StartReceivingVideo(xmlrpc_env &env, int sessionId) {
xmlrpc_value *result = NULL;
xmlrpc_value *resultA = NULL;
xmlrpc_int32 return_code = 0, id = 0, difference = 0;
xmlrpc_value *rtpMap = xmlrpc_build_value(&env, "{}");
//enum Type { H263_1996 = 34, H263_1998 = 103, MPEG4 = 104, H264 = 99, SORENSON = 100, VP6 = 106, VP8 = 107, VP9 = 112, ULPFEC = 108, FLEXFEC = 113, RED = 109, RTX = 110, UNKNOWN = -1 };
xmlrpc_value *rtpAudio = xmlrpc_build_value(&env, "i", AAC_PAYLOAD);
xmlrpc_value *rtpVideo = xmlrpc_build_value(&env, "i", H264_PAYLOAD);
xmlrpc_struct_set_value(&env, rtpMap, "97", rtpAudio);
xmlrpc_struct_set_value(&env, rtpMap, "96", rtpVideo);
/* Call our XML-RPC server. */
result = xmlrpc_client_call(&env, SERVER_URL,
"StartReceivingVideo", "(iS)",
sessionId, rtpMap);
die_if_fault_occurred(&env);
/* Parse our result value. */
xmlrpc_parse_value(&env, result, "{s:i,s:A,*}",
"returnCode", &return_code,
"returnVal", &resultA);
die_if_fault_occurred(&env);
xmlrpc_int32 valueRecvPort = 0;
xmlrpc_parse_value(&env, resultA, "(i)", &valueRecvPort);
die_if_fault_occurred(&env);
/* Print out our sum and difference. */
printf("StartReceivingVideo return_code: %d, valueRecvPort:%d \n", (int)return_code, (int)valueRecvPort);
/* Dispose of our result value. */
xmlrpc_DECREF(result);
xmlrpc_DECREF(rtpAudio);
xmlrpc_DECREF(rtpVideo);
xmlrpc_DECREF(rtpMap);
return (int)valueRecvPort;
}
xmlrpc_int32 CreateMediaBridge(xmlrpc_env &env) {
xmlrpc_value *result = NULL;
xmlrpc_value *resultA = NULL;
xmlrpc_int32 return_code = 0, id = 0, difference = 0;
//resultA = xmlrpc_build_value(&env, "()"); //
//resultA = xmlrpc_build_value(&env, "s", "returnVal");
//die_if_fault_occurred(&env);
/* Call our XML-RPC server. */
result = xmlrpc_client_call(&env, SERVER_URL,
"CreateMediaBridge", "(s)",
"120202");
die_if_fault_occurred(&env);
/* Parse our result value. */
xmlrpc_parse_value(&env, result, "{s:i,s:A,*}",
"returnCode", &return_code,
"returnVal", &resultA);
die_if_fault_occurred(&env);
xmlrpc_int32 valueSessionId = 0;
xmlrpc_parse_value(&env, resultA, "(i)", &valueSessionId);
die_if_fault_occurred(&env);
//xmlrpc_struct_find_value(&env, result, "returnVal", &resultA);
/* Print out our sum and difference. */
printf("return_code: %d, valueSessionId: %d\n", (int)return_code, (int)valueSessionId);
/* Dispose of our result value. */
xmlrpc_DECREF(result);
return valueSessionId;
}
int main()
{
xmlrpc_env env;
/* Start up our XML-RPC client library. */
xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION);
xmlrpc_env_init(&env);
//开始StartSendingVideo
xmlrpc_int32 valueSessionId = CreateMediaBridge(env);
int ret = StartReceivingVideo(env, valueSessionId);
//ret = StartSendingVideo(env, valueSessionId);
/* Shutdown our XML-RPC client library. */
xmlrpc_env_clean(&env);
xmlrpc_client_cleanup();
}
本文为呱牛笔记原创文章,转载无需和我联系,但请注明来自呱牛笔记 ,it3q.com