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]<Executed VP9 test plan
[0x7f07646ab1c0][1589007736.067][LOG]<All plans executed
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 <iostream> 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(); }
-------------------广告线---------------
项目、合作,欢迎勾搭,邮箱:promall@qq.com
本文为呱牛笔记原创文章,转载无需和我联系,但请注明来自呱牛笔记 ,it3q.com