mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-23 11:17:09 +08:00
Merge branch 'master' of https://gitee.com/xia-chu/ZLMediaKit into open_src
This commit is contained in:
commit
8b134d5b2d
@ -12,7 +12,6 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <sstream>
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "jsoncpp/json.h"
|
#include "jsoncpp/json.h"
|
||||||
#include "Util/util.h"
|
#include "Util/util.h"
|
||||||
@ -98,25 +97,58 @@ public:
|
|||||||
#define API_ARGS1 SockInfo &sender,HttpSession::KeyValue &headerIn, HttpSession::KeyValue &headerOut, ApiArgsType &allArgs, Json::Value &val
|
#define API_ARGS1 SockInfo &sender,HttpSession::KeyValue &headerIn, HttpSession::KeyValue &headerOut, ApiArgsType &allArgs, Json::Value &val
|
||||||
#define API_ARGS2 API_ARGS1, const HttpSession::HttpResponseInvoker &invoker
|
#define API_ARGS2 API_ARGS1, const HttpSession::HttpResponseInvoker &invoker
|
||||||
#define API_ARGS_VALUE1 sender,headerIn,headerOut,allArgs,val
|
#define API_ARGS_VALUE1 sender,headerIn,headerOut,allArgs,val
|
||||||
#define API_ARGS_VALUE2 API_ARGS_VALUE1, invoker
|
|
||||||
|
|
||||||
typedef map<string, variant, StrCaseCompare> ApiArgsType;
|
typedef map<string, variant, StrCaseCompare> ApiArgsType;
|
||||||
|
typedef function<void(const Parser &parser, const HttpSession::HttpResponseInvoker &invoker, SockInfo &sender)> HttpApi;
|
||||||
//http api列表
|
//http api列表
|
||||||
static map<string, std::function<void(API_ARGS2)> > s_map_api;
|
static map<string, HttpApi> s_map_api;
|
||||||
|
|
||||||
template<typename FUNC>
|
static void responseApi(const Json::Value &res, const HttpSession::HttpResponseInvoker &invoker){
|
||||||
static void api_regist1(const string &api_path, FUNC &&func) {
|
GET_CONFIG(string, charSet, Http::kCharSet);
|
||||||
s_map_api.emplace(api_path, [func](API_ARGS2) {
|
HttpSession::KeyValue headerOut;
|
||||||
func(API_ARGS_VALUE1);
|
headerOut["Content-Type"] = string("application/json; charset=") + charSet;
|
||||||
|
invoker("200 OK", headerOut, res.toStyledString());
|
||||||
|
};
|
||||||
|
|
||||||
|
static void responseApi(int code, const string &msg, const HttpSession::HttpResponseInvoker &invoker){
|
||||||
|
Json::Value res;
|
||||||
|
res["code"] = code;
|
||||||
|
res["msg"] = msg;
|
||||||
|
responseApi(res, invoker);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ApiArgsType getAllArgs(const Parser &parser);
|
||||||
|
|
||||||
|
static HttpApi toApi(const function<void(API_ARGS2)> &cb) {
|
||||||
|
return [cb](const Parser &parser, const HttpSession::HttpResponseInvoker &invoker, SockInfo &sender) {
|
||||||
|
GET_CONFIG(string, charSet, Http::kCharSet);
|
||||||
|
HttpSession::KeyValue headerOut;
|
||||||
|
headerOut["Content-Type"] = string("application/json; charset=") + charSet;
|
||||||
|
|
||||||
|
Json::Value val;
|
||||||
|
val["code"] = API::Success;
|
||||||
|
|
||||||
|
auto args = getAllArgs(parser);
|
||||||
|
cb(sender, parser.getHeader(), headerOut, args, val, invoker);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static HttpApi toApi(const function<void(API_ARGS1)> &cb) {
|
||||||
|
return toApi([cb](API_ARGS2) {
|
||||||
|
cb(API_ARGS_VALUE1);
|
||||||
invoker("200 OK", headerOut, val.toStyledString());
|
invoker("200 OK", headerOut, val.toStyledString());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename FUNC>
|
template<typename FUNC>
|
||||||
static void api_regist2(const string &api_path, FUNC &&func) {
|
static void api_regist(const string &api_path, FUNC &&func) {
|
||||||
s_map_api.emplace(api_path, std::forward<FUNC>(func));
|
s_map_api.emplace(api_path, toApi(std::move(func)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define api_regist1 api_regist
|
||||||
|
#define api_regist2 api_regist
|
||||||
|
|
||||||
|
|
||||||
//获取HTTP请求中url参数、content参数
|
//获取HTTP请求中url参数、content参数
|
||||||
static ApiArgsType getAllArgs(const Parser &parser) {
|
static ApiArgsType getAllArgs(const Parser &parser) {
|
||||||
ApiArgsType allArgs;
|
ApiArgsType allArgs;
|
||||||
@ -157,22 +189,11 @@ static inline void addHttpListener(){
|
|||||||
}
|
}
|
||||||
//该api已被消费
|
//该api已被消费
|
||||||
consumed = true;
|
consumed = true;
|
||||||
//执行API
|
|
||||||
Json::Value val;
|
|
||||||
val["code"] = API::Success;
|
|
||||||
HttpSession::KeyValue headerOut;
|
|
||||||
auto allArgs = getAllArgs(parser);
|
|
||||||
HttpSession::KeyValue &headerIn = parser.getHeader();
|
|
||||||
GET_CONFIG(string,charSet,Http::kCharSet);
|
|
||||||
headerOut["Content-Type"] = StrPrinter << "application/json; charset=" << charSet;
|
|
||||||
if(api_debug){
|
if(api_debug){
|
||||||
auto newInvoker = [invoker,parser,allArgs](const string &codeOut,
|
auto newInvoker = [invoker, parser](const string &codeOut,
|
||||||
const HttpSession::KeyValue &headerOut,
|
const HttpSession::KeyValue &headerOut,
|
||||||
const HttpBody::Ptr &body){
|
const HttpBody::Ptr &body) {
|
||||||
stringstream ss;
|
|
||||||
for(auto &pr : allArgs ){
|
|
||||||
ss << pr.first << " : " << pr.second << "\r\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
//body默认为空
|
//body默认为空
|
||||||
int64_t size = 0;
|
int64_t size = 0;
|
||||||
@ -181,45 +202,36 @@ static inline void addHttpListener(){
|
|||||||
size = body->remainSize();
|
size = body->remainSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(size && size < 4 * 1024){
|
if (size && size < 4 * 1024) {
|
||||||
string contentOut = body->readData(size)->toString();
|
string contentOut = body->readData(size)->toString();
|
||||||
DebugL << "\r\n# request:\r\n" << parser.Method() << " " << parser.FullUrl() << "\r\n"
|
DebugL << "\r\n# request:\r\n" << parser.Method() << " " << parser.FullUrl() << "\r\n"
|
||||||
<< "# content:\r\n" << parser.Content() << "\r\n"
|
<< "# content:\r\n" << parser.Content() << "\r\n"
|
||||||
<< "# args:\r\n" << ss.str()
|
|
||||||
<< "# response:\r\n"
|
<< "# response:\r\n"
|
||||||
<< contentOut << "\r\n";
|
<< contentOut << "\r\n";
|
||||||
invoker(codeOut,headerOut,contentOut);
|
invoker(codeOut, headerOut, contentOut);
|
||||||
} else{
|
} else {
|
||||||
DebugL << "\r\n# request:\r\n" << parser.Method() << " " << parser.FullUrl() << "\r\n"
|
DebugL << "\r\n# request:\r\n" << parser.Method() << " " << parser.FullUrl() << "\r\n"
|
||||||
<< "# content:\r\n" << parser.Content() << "\r\n"
|
<< "# content:\r\n" << parser.Content() << "\r\n"
|
||||||
<< "# args:\r\n" << ss.str()
|
|
||||||
<< "# response size:"
|
<< "# response size:"
|
||||||
<< size <<"\r\n";
|
<< size << "\r\n";
|
||||||
invoker(codeOut,headerOut,body);
|
invoker(codeOut, headerOut, body);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
((HttpSession::HttpResponseInvoker &)invoker) = newInvoker;
|
((HttpSession::HttpResponseInvoker &) invoker) = newInvoker;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
it->second(sender,headerIn, headerOut, allArgs, val, invoker);
|
it->second(parser, invoker, sender);
|
||||||
} catch(ApiRetException &ex){
|
} catch (ApiRetException &ex) {
|
||||||
val["code"] = ex.code();
|
responseApi(ex.code(), ex.what(), invoker);
|
||||||
val["msg"] = ex.what();
|
|
||||||
invoker("200 OK", headerOut, val.toStyledString());
|
|
||||||
}
|
}
|
||||||
#ifdef ENABLE_MYSQL
|
#ifdef ENABLE_MYSQL
|
||||||
catch(SqlException &ex){
|
catch(SqlException &ex){
|
||||||
val["code"] = API::SqlFailed;
|
responseApi(API::SqlFailed, StrPrinter << "操作数据库失败:" << ex.what() << ":" << ex.getSql(), invoker);
|
||||||
val["msg"] = StrPrinter << "操作数据库失败:" << ex.what() << ":" << ex.getSql();
|
|
||||||
WarnL << ex.what() << ":" << ex.getSql();
|
|
||||||
invoker("200 OK", headerOut, val.toStyledString());
|
|
||||||
}
|
}
|
||||||
#endif// ENABLE_MYSQL
|
#endif// ENABLE_MYSQL
|
||||||
catch (std::exception &ex) {
|
catch (std::exception &ex) {
|
||||||
val["code"] = API::Exception;
|
responseApi(API::Exception, ex.what(), invoker);
|
||||||
val["msg"] = ex.what();
|
|
||||||
invoker("200 OK", headerOut, val.toStyledString());
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -101,16 +101,18 @@ bool RtpReceiver::handleOneRtp(int track_index, TrackType type, int samplerate,
|
|||||||
//ssrc匹配正确,不匹配计数清零
|
//ssrc匹配正确,不匹配计数清零
|
||||||
_ssrc_err_count[track_index] = 0;
|
_ssrc_err_count[track_index] = 0;
|
||||||
|
|
||||||
//获取rtp中媒体数据偏移量
|
//rtp 12个固定字节头
|
||||||
rtp.offset = 12 + 4;
|
rtp.offset = 12;
|
||||||
|
//rtp有csrc
|
||||||
rtp.offset += 4 * csrc;
|
rtp.offset += 4 * csrc;
|
||||||
if (ext && rtp_raw_len >= rtp.offset) {
|
if (ext) {
|
||||||
/* calculate the header extension length (stored as number of 32-bit words) */
|
//rtp有ext
|
||||||
ext = (AV_RB16(rtp_raw_ptr + rtp.offset - 2) + 1) << 2;
|
uint16_t reserved = AV_RB16(rtp_raw_ptr + rtp.offset);
|
||||||
rtp.offset += ext;
|
uint16_t extlen = AV_RB16(rtp_raw_ptr + rtp.offset + 2) << 2;
|
||||||
|
rtp.offset += extlen + 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rtp_raw_len + 4 <= rtp.offset) {
|
if (rtp_raw_len <= rtp.offset) {
|
||||||
WarnL << "无有效负载的rtp包:" << rtp_raw_len << " <= " << (int) rtp.offset;
|
WarnL << "无有效负载的rtp包:" << rtp_raw_len << " <= " << (int) rtp.offset;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -128,9 +130,10 @@ bool RtpReceiver::handleOneRtp(int track_index, TrackType type, int samplerate,
|
|||||||
payload_ptr[1] = rtp.interleaved;
|
payload_ptr[1] = rtp.interleaved;
|
||||||
payload_ptr[2] = rtp_raw_len >> 8;
|
payload_ptr[2] = rtp_raw_len >> 8;
|
||||||
payload_ptr[3] = (rtp_raw_len & 0x00FF);
|
payload_ptr[3] = (rtp_raw_len & 0x00FF);
|
||||||
|
//添加rtp over tcp前4个字节的偏移量
|
||||||
|
rtp.offset += 4;
|
||||||
//拷贝rtp负载
|
//拷贝rtp负载
|
||||||
memcpy(payload_ptr + 4, rtp_raw_ptr, rtp_raw_len);
|
memcpy(payload_ptr + 4, rtp_raw_ptr, rtp_raw_len);
|
||||||
|
|
||||||
//排序rtp
|
//排序rtp
|
||||||
auto seq = rtp_ptr->sequence;
|
auto seq = rtp_ptr->sequence;
|
||||||
_rtp_sortor[track_index].sortPacket(seq, std::move(rtp_ptr));
|
_rtp_sortor[track_index].sortPacket(seq, std::move(rtp_ptr));
|
||||||
|
Loading…
Reference in New Issue
Block a user