ZLMediaKit/api/tests/server.c

621 lines
25 KiB
C++
Raw Normal View History

2019-12-23 14:31:02 +08:00
/*
2023-12-09 16:23:51 +08:00
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
2019-12-23 14:31:02 +08:00
*
2023-12-09 16:23:51 +08:00
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
2019-12-23 14:31:02 +08:00
*
2023-12-09 16:23:51 +08:00
* Use of this source code is governed by MIT-like license that can be found in the
2020-04-04 20:30:09 +08:00
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
2019-12-23 14:31:02 +08:00
*/
2019-12-23 14:01:00 +08:00
2019-12-25 09:39:24 +08:00
#include <string.h>
#include <stdio.h>
#include "mk_mediakit.h"
2019-12-24 16:02:41 +08:00
#define LOG_LEV 4
/**
* MediaSource事件广播
* @param regist 10
* @param sender MediaSource对象
* Register or unregister MediaSource event broadcast
* @param regist Register as 1, unregister as 0
* @param sender The MediaSource object
* [AUTO-TRANSLATED:8bb75918]
2019-12-24 16:02:41 +08:00
*/
void API_CALL on_mk_media_changed(int regist,
const mk_media_source sender) {
log_printf(LOG_LEV,"%d %s/%s/%s/%s",(int)regist,
mk_media_source_get_schema(sender),
mk_media_source_get_vhost(sender),
mk_media_source_get_app(sender),
mk_media_source_get_stream(sender));
}
/**
* rtsp/rtmp推流事件广播
* @see mk_publish_auth_invoker_do
* @param url_info url相关信息
* @param invoker invoker返回鉴权结果
* @param sender tcp客户端相关信息
* Receive rtsp/rtmp push stream event broadcast, control push stream authentication through this event
* @see mk_publish_auth_invoker_do
* @param url_info Push stream url related information
* @param invoker Execute invoker to return authentication result
* @param sender The tcp client related information
* [AUTO-TRANSLATED:72053c81]
2019-12-24 16:02:41 +08:00
*/
void API_CALL on_mk_media_publish(const mk_media_info url_info,
const mk_publish_auth_invoker invoker,
const mk_sock_info sender) {
2020-04-24 14:06:28 +08:00
char ip[64];
2019-12-24 16:02:41 +08:00
log_printf(LOG_LEV,
"client info, local: %s:%d, peer: %s:%d\n"
"%s/%s/%s/%s, url params: %s",
2020-04-24 14:06:28 +08:00
mk_sock_info_local_ip(sender,ip),
mk_sock_info_local_port(sender),
2020-04-24 14:06:28 +08:00
mk_sock_info_peer_ip(sender,ip + 32),
mk_sock_info_peer_port(sender),
2019-12-24 16:02:41 +08:00
mk_media_info_get_schema(url_info),
mk_media_info_get_vhost(url_info),
mk_media_info_get_app(url_info),
mk_media_info_get_stream(url_info),
mk_media_info_get_params(url_info));
// 允许推流并且允许转hls/mp4 [AUTO-TRANSLATED:4b2d0e4e]
// Allow push stream, and allow to convert to hls/mp4
2020-09-12 19:09:56 +08:00
mk_publish_auth_invoker_do(invoker, NULL, 1, 1);
2019-12-24 16:02:41 +08:00
}
/**
* rtsp/rtmp/http-flv/hls事件广播
* @see mk_auth_invoker_do
* @param url_info url相关信息
* @param invoker invoker返回鉴权结果
* @param sender
* Play rtsp/rtmp/http-flv/hls event broadcast, control playback authentication through this event
* @see mk_auth_invoker_do
* @param url_info Play url related information
* @param invoker Execute invoker to return authentication result
* @param sender Play client related information
* [AUTO-TRANSLATED:fc351667]
2019-12-24 16:02:41 +08:00
*/
void API_CALL on_mk_media_play(const mk_media_info url_info,
const mk_auth_invoker invoker,
const mk_sock_info sender) {
2019-12-24 16:02:41 +08:00
2020-04-24 14:06:28 +08:00
char ip[64];
2019-12-24 16:02:41 +08:00
log_printf(LOG_LEV,
"client info, local: %s:%d, peer: %s:%d\n"
"%s/%s/%s/%s, url params: %s",
2020-04-24 14:06:28 +08:00
mk_sock_info_local_ip(sender,ip),
mk_sock_info_local_port(sender),
2020-04-24 14:06:28 +08:00
mk_sock_info_peer_ip(sender,ip + 32),
mk_sock_info_peer_port(sender),
2019-12-24 16:02:41 +08:00
mk_media_info_get_schema(url_info),
mk_media_info_get_vhost(url_info),
mk_media_info_get_app(url_info),
mk_media_info_get_stream(url_info),
mk_media_info_get_params(url_info));
// 允许播放 [AUTO-TRANSLATED:b940f821]
// Allow playback
2019-12-25 09:39:24 +08:00
mk_auth_invoker_do(invoker, NULL);
2019-12-24 16:02:41 +08:00
}
/**
* 广
* @param url_info url相关信息
* @param sender
* @return 1
* 0
* This event will be broadcast after the stream is not found. Please pull the stream or other methods to generate the stream after listening to this event, so that you can pull the stream on demand
* @param url_info Play url related information
* @param sender Play client related information
* @return 1 Close directly
* 0 Wait for stream registration
* [AUTO-TRANSLATED:71caa7d8]
2019-12-24 16:02:41 +08:00
*/
int API_CALL on_mk_media_not_found(const mk_media_info url_info,
const mk_sock_info sender) {
2020-04-24 14:06:28 +08:00
char ip[64];
2019-12-24 16:02:41 +08:00
log_printf(LOG_LEV,
"client info, local: %s:%d, peer: %s:%d\n"
"%s/%s/%s/%s, url params: %s",
2020-04-24 14:06:28 +08:00
mk_sock_info_local_ip(sender,ip),
mk_sock_info_local_port(sender),
2020-04-24 14:06:28 +08:00
mk_sock_info_peer_ip(sender,ip + 32),
mk_sock_info_peer_port(sender),
2019-12-24 16:02:41 +08:00
mk_media_info_get_schema(url_info),
mk_media_info_get_vhost(url_info),
mk_media_info_get_app(url_info),
mk_media_info_get_stream(url_info),
mk_media_info_get_params(url_info));
return 0;
2019-12-24 16:02:41 +08:00
}
/**
*
* @param sender MediaSource对象
* Triggered when no one consumes a certain stream, the purpose is to achieve business logic such as actively disconnecting the pull stream when no one is watching
* @param sender The MediaSource object
* [AUTO-TRANSLATED:d2881c87]
2019-12-24 16:02:41 +08:00
*/
void API_CALL on_mk_media_no_reader(const mk_media_source sender) {
log_printf(LOG_LEV,
"%s/%s/%s/%s",
mk_media_source_get_schema(sender),
mk_media_source_get_vhost(sender),
mk_media_source_get_app(sender),
mk_media_source_get_stream(sender));
}
// 按照json转义规则转义webrtc answer sdp [AUTO-TRANSLATED:b9373d68]
// Escape webrtc answer sdp according to json escape rules
2022-10-06 12:33:48 +08:00
static char *escape_string(const char *ptr){
char *escaped = malloc(2 * strlen(ptr));
char *ptr_escaped = escaped;
while (1) {
switch (*ptr) {
case '\r': {
*(ptr_escaped++) = '\\';
*(ptr_escaped++) = 'r';
break;
}
case '\n': {
*(ptr_escaped++) = '\\';
*(ptr_escaped++) = 'n';
break;
}
case '\t': {
*(ptr_escaped++) = '\\';
*(ptr_escaped++) = 't';
break;
}
default: {
*(ptr_escaped++) = *ptr;
if (!*ptr) {
return escaped;
}
break;
}
}
++ptr;
}
}
static void on_mk_webrtc_get_answer_sdp_func(void *user_data, const char *answer, const char *err) {
const char *response_header[] = { "Content-Type", "application/json", "Access-Control-Allow-Origin", "*" , NULL};
if (answer) {
answer = escape_string(answer);
}
size_t len = answer ? 2 * strlen(answer) : 1024;
char *response_content = (char *)malloc(len);
if (answer) {
snprintf(response_content, len,
"{"
"\"sdp\":\"%s\","
"\"type\":\"answer\","
"\"code\":0"
"}",
answer);
} else {
snprintf(response_content, len,
"{"
"\"msg\":\"%s\","
"\"code\":-1"
"}",
err);
}
mk_http_response_invoker_do_string(user_data, 200, response_header, response_content);
mk_http_response_invoker_clone_release(user_data);
free(response_content);
if (answer) {
2022-11-19 09:37:49 +08:00
free((void *)answer);
2022-10-06 12:33:48 +08:00
}
}
void API_CALL on_get_statistic_cb(void *user_data, mk_ini ini) {
const char *response_header[] = { NULL };
char *str = mk_ini_dump_string(ini);
mk_http_response_invoker_do_string(user_data, 200, response_header, str);
mk_free(str);
}
2019-12-24 16:02:41 +08:00
/**
* http api请求广播(GET/POST)
* @param parser http请求内容对象
* @param invoker invoker返回http回复
* @param consumed 1
* @param sender http客户端相关信息
* Receive http api request broadcast (including GET/POST)
* @param parser Http request content object
* @param invoker Execute this invoker to return http reply
* @param consumed Set to 1 if we want to handle this event
* @param sender Http client related information
* [AUTO-TRANSLATED:39435e52]
2019-12-24 16:02:41 +08:00
*/
// 测试url : http://127.0.0.1/api/test [AUTO-TRANSLATED:4776d7a3]
// Test url : http://127.0.0.1/api/test
2019-12-24 16:02:41 +08:00
void API_CALL on_mk_http_request(const mk_parser parser,
const mk_http_response_invoker invoker,
int *consumed,
const mk_sock_info sender) {
2019-12-24 16:02:41 +08:00
2020-04-24 14:06:28 +08:00
char ip[64];
2019-12-24 16:02:41 +08:00
log_printf(LOG_LEV,
"client info, local: %s:%d, peer: %s:%d\n"
"%s %s?%s %s\n"
"User-Agent: %s\n"
"%s",
2020-04-24 14:06:28 +08:00
mk_sock_info_local_ip(sender,ip),
mk_sock_info_local_port(sender),
2020-04-24 14:06:28 +08:00
mk_sock_info_peer_ip(sender,ip + 32),
mk_sock_info_peer_port(sender),
2019-12-24 16:02:41 +08:00
mk_parser_get_method(parser),
mk_parser_get_url(parser),
mk_parser_get_url_params(parser),
mk_parser_get_tail(parser),
mk_parser_get_header(parser, "User-Agent"),
2019-12-25 14:25:26 +08:00
mk_parser_get_content(parser,NULL));
2019-12-24 16:02:41 +08:00
const char *url = mk_parser_get_url(parser);
*consumed = 1;
// 拦截api: /api/test [AUTO-TRANSLATED:262baadf]
// Intercept api: /api/test
2022-10-06 12:33:48 +08:00
if (strcmp(url, "/api/test") == 0) {
const char *response_header[] = { "Content-Type", "text/html", NULL };
const char *content = "<html>"
"<head>"
"<title>hello world</title>"
"</head>"
"<body bgcolor=\"white\">"
"<center><h1>hello world</h1></center><hr>"
"<center>"
"ZLMediaKit-4.0</center>"
"</body>"
"</html>";
mk_http_body body = mk_http_body_from_string(content, 0);
mk_http_response_invoker_do(invoker, 200, response_header, body);
mk_http_body_release(body);
2022-10-06 12:33:48 +08:00
} else if (strcmp(url, "/index/api/webrtc") == 0) {
// 拦截api: /index/api/webrtc [AUTO-TRANSLATED:1db21d1c]
// Intercept api: /index/api/webrtc
2022-10-06 12:33:48 +08:00
char rtc_url[1024];
snprintf(rtc_url, sizeof(rtc_url), "rtc://%s/%s/%s?%s", mk_parser_get_header(parser, "Host"),
mk_parser_get_url_param(parser, "app"), mk_parser_get_url_param(parser, "stream"),
mk_parser_get_url_params(parser));
mk_webrtc_get_answer_sdp(mk_http_response_invoker_clone(invoker), on_mk_webrtc_get_answer_sdp_func,
mk_parser_get_url_param(parser, "type"), mk_parser_get_content(parser, NULL), rtc_url);
} else if (strcmp(url, "/index/api/getStatistic") == 0) {
// 拦截api: /index/api/webrtc [AUTO-TRANSLATED:1db21d1c]
// Intercept api: /index/api/webrtc
mk_get_statistic(on_get_statistic_cb, mk_http_response_invoker_clone(invoker), (on_user_data_free) mk_http_response_invoker_clone_release);
2022-10-06 12:33:48 +08:00
} else {
2019-12-25 09:39:24 +08:00
*consumed = 0;
2019-12-24 16:02:41 +08:00
return;
}
}
/**
* http文件服务器中,http访问文件或目录的广播,访http目录的权限
* @param parser http请求内容对象
* @param path
* @param is_dir path是否为文件夹
* @param invoker invoker返回本次访问文件的结果
* @param sender http客户端相关信息
* In the http file server, receive the broadcast of http access to files or directories, control the access permission of http directory through this event
* @param parser Http request content object
* @param path File absolute path
* @param is_dir Whether path is a folder
* @param invoker Execute invoker to return the result of accessing the file this time
* @param sender Http client related information
* [AUTO-TRANSLATED:2db5fc1e]
2019-12-24 16:02:41 +08:00
*/
void API_CALL on_mk_http_access(const mk_parser parser,
const char *path,
int is_dir,
const mk_http_access_path_invoker invoker,
const mk_sock_info sender) {
2019-12-24 16:02:41 +08:00
2020-04-24 14:06:28 +08:00
char ip[64];
2019-12-24 16:02:41 +08:00
log_printf(LOG_LEV,
"client info, local: %s:%d, peer: %s:%d, path: %s ,is_dir: %d\n"
"%s %s?%s %s\n"
"User-Agent: %s\n"
"%s",
2020-04-24 14:06:28 +08:00
mk_sock_info_local_ip(sender, ip),
mk_sock_info_local_port(sender),
2020-04-24 14:06:28 +08:00
mk_sock_info_peer_ip(sender, ip + 32),
mk_sock_info_peer_port(sender),
2019-12-24 16:02:41 +08:00
path,(int)is_dir,
mk_parser_get_method(parser),
mk_parser_get_url(parser),
mk_parser_get_url_params(parser),
mk_parser_get_tail(parser),
mk_parser_get_header(parser,"User-Agent"),
2019-12-25 14:25:26 +08:00
mk_parser_get_content(parser,NULL));
2019-12-24 16:02:41 +08:00
// 有访问权限,每次访问文件都需要鉴权 [AUTO-TRANSLATED:6ade8f21]
// Has access permission, each access to the file needs authentication
2019-12-25 09:39:24 +08:00
mk_http_access_path_invoker_do(invoker, NULL, NULL, 0);
2019-12-24 16:02:41 +08:00
}
/**
* http文件服务器中,http访问文件或目录前的广播,http url到文件路径的映射
* path参数app选择不同http根目录的目的
* @param parser http请求内容对象
* @param path ,
* @param sender http客户端相关信息
* In the http file server, receive the broadcast before http access to files or directories, through this event you can control the mapping of http url to file path
* By overriding the path parameter in this event, you can achieve the purpose of selecting different http root directories according to virtual hosts or apps
* @param parser Http request content object
* @param path File absolute path, override it to redirect to other files
* @param sender Http client related information
* [AUTO-TRANSLATED:e166f6cb]
2019-12-24 16:02:41 +08:00
*/
void API_CALL on_mk_http_before_access(const mk_parser parser,
char *path,
const mk_sock_info sender) {
2020-04-24 14:06:28 +08:00
char ip[64];
2019-12-24 16:02:41 +08:00
log_printf(LOG_LEV,
"client info, local: %s:%d, peer: %s:%d, path: %s\n"
"%s %s?%s %s\n"
"User-Agent: %s\n"
"%s",
2020-04-24 14:06:28 +08:00
mk_sock_info_local_ip(sender,ip),
mk_sock_info_local_port(sender),
2020-04-24 14:06:28 +08:00
mk_sock_info_peer_ip(sender,ip + 32),
mk_sock_info_peer_port(sender),
2019-12-24 16:02:41 +08:00
path,
mk_parser_get_method(parser),
mk_parser_get_url(parser),
mk_parser_get_url_params(parser),
mk_parser_get_tail(parser),
mk_parser_get_header(parser, "User-Agent"),
2019-12-25 14:25:26 +08:00
mk_parser_get_content(parser,NULL));
// 覆盖path的值可以重定向文件 [AUTO-TRANSLATED:7b03ed02]
// Overriding the value of path can redirect files
2019-12-24 16:02:41 +08:00
}
/**
* rtsp流是否需要认证invoker并传入realm,realm
* @param url_info rtsp url相关信息
* @param invoker invoker返回是否需要rtsp专属认证
* @param sender rtsp客户端相关信息
* Does this rtsp stream need authentication? If so, call invoker and pass in realm, otherwise pass in empty realm
* @param url_info Request rtsp url related information
* @param invoker Execute invoker to return whether rtsp exclusive authentication is required
* @param sender Rtsp client related information
* [AUTO-TRANSLATED:3308f34e]
2019-12-24 16:02:41 +08:00
*/
void API_CALL on_mk_rtsp_get_realm(const mk_media_info url_info,
const mk_rtsp_get_realm_invoker invoker,
const mk_sock_info sender) {
2020-04-24 14:06:28 +08:00
char ip[64];
2019-12-24 16:02:41 +08:00
log_printf(LOG_LEV,
"client info, local: %s:%d, peer: %s:%d\n"
"%s/%s/%s/%s, url params: %s",
2020-04-24 14:06:28 +08:00
mk_sock_info_local_ip(sender,ip),
mk_sock_info_local_port(sender),
2020-04-24 14:06:28 +08:00
mk_sock_info_peer_ip(sender,ip + 32),
mk_sock_info_peer_port(sender),
2019-12-24 16:02:41 +08:00
mk_media_info_get_schema(url_info),
mk_media_info_get_vhost(url_info),
mk_media_info_get_app(url_info),
mk_media_info_get_stream(url_info),
mk_media_info_get_params(url_info));
// rtsp播放默认鉴权 [AUTO-TRANSLATED:3a820721]
// Rtsp playback default authentication
2019-12-24 16:02:41 +08:00
mk_rtsp_get_realm_invoker_do(invoker, "zlmediakit");
}
/**
2019-12-25 09:39:24 +08:00
* user_name为用户名must_no_encrypt如果为1(base64认证方式),
2019-12-24 16:02:41 +08:00
* invoker并输入对应类型的密码和密码类型invoker执行时会匹配密码
* @param url_info rtsp url相关信息
* @param realm rtsp认证realm
* @param user_name rtsp认证用户名
2019-12-25 09:39:24 +08:00
* @param must_no_encrypt 1(base64认证方式),
2019-12-24 16:02:41 +08:00
* @param invoker invoker返回rtsp专属认证的密码
* @param sender rtsp客户端信息
* Request authentication user password event, user_name is the username, must_no_encrypt if it is 1, then you must provide plain text password (because it is base64 authentication method at this time), otherwise it will lead to authentication failure
* After getting the password, please call invoker and enter the corresponding type of password and password type, invoker will match the password when executing
* @param url_info Request rtsp url related information
* @param realm Rtsp authentication realm
* @param user_name Rtsp authentication username
* @param must_no_encrypt If it is 1, then you must provide plain text password (because it is base64 authentication method at this time), otherwise it will lead to authentication failure
* @param invoker Execute invoker to return the password of rtsp exclusive authentication
* @param sender Rtsp client information
* [AUTO-TRANSLATED:28391926]
2019-12-24 16:02:41 +08:00
*/
void API_CALL on_mk_rtsp_auth(const mk_media_info url_info,
const char *realm,
const char *user_name,
int must_no_encrypt,
const mk_rtsp_auth_invoker invoker,
const mk_sock_info sender) {
2019-12-24 16:02:41 +08:00
2020-04-24 14:06:28 +08:00
char ip[64];
2019-12-24 16:02:41 +08:00
log_printf(LOG_LEV,
"client info, local: %s:%d, peer: %s:%d\n"
"%s/%s/%s/%s, url params: %s\n"
"realm: %s, user_name: %s, must_no_encrypt: %d",
2020-04-24 14:06:28 +08:00
mk_sock_info_local_ip(sender,ip),
mk_sock_info_local_port(sender),
2020-04-24 14:06:28 +08:00
mk_sock_info_peer_ip(sender,ip + 32),
mk_sock_info_peer_port(sender),
2019-12-24 16:02:41 +08:00
mk_media_info_get_schema(url_info),
mk_media_info_get_vhost(url_info),
mk_media_info_get_app(url_info),
mk_media_info_get_stream(url_info),
mk_media_info_get_params(url_info),
realm,user_name,(int)must_no_encrypt);
// rtsp播放用户名跟密码一致 [AUTO-TRANSLATED:31cc5970]
// Rtsp playback username and password are consistent
2019-12-25 09:39:24 +08:00
mk_rtsp_auth_invoker_do(invoker,0,user_name);
2019-12-24 16:02:41 +08:00
}
/**
* mp4分片文件成功后广播
* Broadcast after recording mp4 fragment file successfully
* [AUTO-TRANSLATED:0fdeba0d]
2019-12-24 16:02:41 +08:00
*/
void API_CALL on_mk_record_mp4(const mk_record_info mp4) {
2019-12-24 16:02:41 +08:00
log_printf(LOG_LEV,
"\nstart_time: %d\n"
"time_len: %d\n"
"file_size: %d\n"
"file_path: %s\n"
"file_name: %s\n"
"folder: %s\n"
"url: %s\n"
"vhost: %s\n"
"app: %s\n"
"stream: %s\n",
mk_record_info_get_start_time(mp4),
mk_record_info_get_time_len(mp4),
mk_record_info_get_file_size(mp4),
mk_record_info_get_file_path(mp4),
mk_record_info_get_file_name(mp4),
mk_record_info_get_folder(mp4),
mk_record_info_get_url(mp4),
mk_record_info_get_vhost(mp4),
mk_record_info_get_app(mp4),
mk_record_info_get_stream(mp4));
2019-12-24 16:02:41 +08:00
}
/**
* shell登录鉴权
* Shell login authentication
* [AUTO-TRANSLATED:cc20f95e]
2019-12-24 16:02:41 +08:00
*/
void API_CALL on_mk_shell_login(const char *user_name,
const char *passwd,
const mk_auth_invoker invoker,
const mk_sock_info sender) {
2020-04-24 14:06:28 +08:00
char ip[64];
2019-12-24 16:02:41 +08:00
log_printf(LOG_LEV,"client info, local: %s:%d, peer: %s:%d\n"
"user_name: %s, passwd: %s",
2020-04-24 14:06:28 +08:00
mk_sock_info_local_ip(sender,ip),
mk_sock_info_local_port(sender),
2020-04-24 14:06:28 +08:00
mk_sock_info_peer_ip(sender,ip + 32),
mk_sock_info_peer_port(sender),
2019-12-24 16:02:41 +08:00
user_name, passwd);
// 允许登录shell [AUTO-TRANSLATED:64a9b374]
// Allow login shell
2019-12-25 09:39:24 +08:00
mk_auth_invoker_do(invoker, NULL);
2019-12-24 16:02:41 +08:00
}
/**
* rtsp/rtmp/http-flv会话后流量汇报事件广播
* @param url_info url相关信息
* @param total_bytes
* @param total_seconds tcp会话时长
* @param is_player
* @param peer_ip ip
* @param peer_port
* Stop rtsp/rtmp/http-flv session after traffic report event broadcast
* @param url_info Play url related information
* @param total_bytes Total traffic consumed up and down, unit is byte
* @param total_seconds The duration of this tcp session, unit is second
* @param is_player Whether the client is a player
* @param peer_ip Client ip
* @param peer_port Client port number
* [AUTO-TRANSLATED:6757a1c3]
2019-12-24 16:02:41 +08:00
*/
void API_CALL on_mk_flow_report(const mk_media_info url_info,
2021-01-17 20:15:08 +08:00
size_t total_bytes,
size_t total_seconds,
int is_player,
2020-04-23 22:04:59 +08:00
const mk_sock_info sender) {
2020-04-24 14:06:28 +08:00
char ip[64];
2019-12-29 15:38:29 +08:00
log_printf(LOG_LEV,"%s/%s/%s/%s, url params: %s,"
"total_bytes: %d, total_seconds: %d, is_player: %d, peer_ip:%s, peer_port:%d",
2019-12-29 15:38:29 +08:00
mk_media_info_get_schema(url_info),
mk_media_info_get_vhost(url_info),
mk_media_info_get_app(url_info),
mk_media_info_get_stream(url_info),
mk_media_info_get_params(url_info),
2020-04-24 14:06:28 +08:00
(int)total_bytes,
(int)total_seconds,
(int)is_player,
mk_sock_info_peer_ip(sender,ip),
(int)mk_sock_info_peer_port(sender));
2019-12-24 16:02:41 +08:00
}
int main(int argc, char *argv[]) {
2020-02-21 11:35:53 +08:00
char *ini_path = mk_util_get_exe_dir("c_api.ini");
char *ssl_path = mk_util_get_exe_dir("ssl.p12");
mk_config config = {
.ini = ini_path,
.ini_is_path = 1,
.log_level = 0,
2021-08-30 20:43:03 +08:00
.log_mask = LOG_CONSOLE,
2020-04-22 09:55:24 +08:00
.log_file_path = NULL,
.log_file_days = 0,
.ssl = ssl_path,
.ssl_is_path = 1,
.ssl_pwd = NULL,
.thread_num = 0
};
mk_env_init(&config);
free(ini_path);
free(ssl_path);
2019-12-25 09:39:24 +08:00
mk_http_server_start(80, 0);
mk_http_server_start(443, 1);
2019-12-25 09:39:24 +08:00
mk_rtsp_server_start(554, 0);
mk_rtmp_server_start(1935, 0);
2019-12-24 16:09:09 +08:00
mk_shell_server_start(9000);
2019-12-23 14:01:00 +08:00
mk_rtp_server_start(10000);
mk_rtc_server_start(8000);
2022-09-22 21:18:34 +08:00
mk_srt_server_start(9000);
2019-12-24 16:02:41 +08:00
mk_events events = {
.on_mk_media_changed = on_mk_media_changed,
.on_mk_media_publish = on_mk_media_publish,
.on_mk_media_play = on_mk_media_play,
.on_mk_media_not_found = on_mk_media_not_found,
.on_mk_media_no_reader = on_mk_media_no_reader,
.on_mk_http_request = on_mk_http_request,
.on_mk_http_access = on_mk_http_access,
.on_mk_http_before_access = on_mk_http_before_access,
.on_mk_rtsp_get_realm = on_mk_rtsp_get_realm,
.on_mk_rtsp_auth = on_mk_rtsp_auth,
.on_mk_record_mp4 = on_mk_record_mp4,
.on_mk_shell_login = on_mk_shell_login,
.on_mk_flow_report = on_mk_flow_report
};
mk_events_listen(&events);
2021-10-19 10:11:23 +08:00
log_info("media server %s", "stared!");
2022-05-25 15:38:32 +08:00
log_info("enter any key to exit");
getchar();
2019-12-23 14:20:49 +08:00
mk_stop_all_server();
return 0;
2019-12-23 14:01:00 +08:00
}