Commit 4dbe0a1d by ziyue

合并pr:#1025

parent 30b139ea
...@@ -6,32 +6,26 @@ set(CMAKE_CXX_STANDARD 11) ...@@ -6,32 +6,26 @@ set(CMAKE_CXX_STANDARD 11)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
#set(CMAKE_BUILD_TYPE "Release") #set(CMAKE_BUILD_TYPE "Release")
message(STATUS "编译类型:${CMAKE_BUILD_TYPE}")
if (${CMAKE_BUILD_TYPE} MATCHES "Release")
message(STATUS "Release版本")
set(BuildType "Release")
else ()
set(BuildType "Debug")
message(STATUS "Debug版本")
endif ()
#设置bin和lib库目录 #设置bin和lib库目录
set(RELEASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/release) set(RELEASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/release)
if(CMAKE_CL_64)
set(CL_32_64 64)
else(CMAKE_CL_64)
set(CL_32_64 32)
endif(CMAKE_CL_64)
if (CMAKE_SYSTEM_NAME MATCHES "Linux") if (CMAKE_SYSTEM_NAME MATCHES "Linux")
SET(LIBRARY_OUTPUT_PATH ${RELEASE_DIR}/linux${CL_32_64}/${BuildType}) SET(LIBRARY_OUTPUT_PATH ${RELEASE_DIR}/linux/${CMAKE_BUILD_TYPE})
SET(EXECUTABLE_OUTPUT_PATH ${RELEASE_DIR}/linux${CL_32_64}/${BuildType}) SET(EXECUTABLE_OUTPUT_PATH ${RELEASE_DIR}/linux/${CMAKE_BUILD_TYPE})
add_compile_options(-fPIC -Wall -Wno-unused-variable -Wno-unused-value) add_compile_options(-fPIC -Wall -Wno-unused-variable -Wno-unused-value)
elseif (CMAKE_SYSTEM_NAME MATCHES "Windows") elseif (CMAKE_SYSTEM_NAME MATCHES "Windows")
SET(LIBRARY_OUTPUT_PATH ${RELEASE_DIR}/windows${CL_32_64}/${BuildType}) if (CMAKE_CL_64)
SET(EXECUTABLE_OUTPUT_PATH ${RELEASE_DIR}/windows${CL_32_64}/${BuildType}) set(CL_32_64 64)
else ()
set(CL_32_64 32)
endif ()
SET(LIBRARY_OUTPUT_PATH ${RELEASE_DIR}/windows${CL_32_64}/${CMAKE_BUILD_TYPE})
SET(EXECUTABLE_OUTPUT_PATH ${RELEASE_DIR}/windows${CL_32_64}/${CMAKE_BUILD_TYPE})
elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin") elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin")
SET(LIBRARY_OUTPUT_PATH ${RELEASE_DIR}/mac${CL_32_64}/${BuildType}) SET(LIBRARY_OUTPUT_PATH ${RELEASE_DIR}/mac/${CMAKE_BUILD_TYPE})
SET(EXECUTABLE_OUTPUT_PATH ${RELEASE_DIR}/mac${CL_32_64/${BuildType}) SET(EXECUTABLE_OUTPUT_PATH ${RELEASE_DIR}/mac/${CMAKE_BUILD_TYPE})
add_compile_options(-Wall -Wno-unused-variable -Wno-unused-value) add_compile_options(-Wall -Wno-unused-variable -Wno-unused-value)
endif () endif ()
...@@ -62,10 +56,9 @@ option(ENABLE_MEM_DEBUG "Enable Memory Debug" false) ...@@ -62,10 +56,9 @@ option(ENABLE_MEM_DEBUG "Enable Memory Debug" false)
option(ENABLE_ASAN "Enable Address Sanitize" false) option(ENABLE_ASAN "Enable Address Sanitize" false)
option(ENABLE_WEBRTC "Enable WebRTC" false) option(ENABLE_WEBRTC "Enable WebRTC" false)
option(ENABLE_PLAYER "Enable Player" true) option(ENABLE_PLAYER "Enable Player" true)
option(ENABLE_MsvcMT "Enable MSVC Mt/Mtd lib" true) option(ENABLE_MSVC_MT "Enable MSVC Mt/Mtd lib" true)
if (ENABLE_STATIC AND MSVC) if (MSVC AND ENABLE_MSVC_MT)
set(CompilerFlags set(CompilerFlags
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS
CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_DEBUG
...@@ -147,7 +140,6 @@ if (OPENSSL_FOUND AND ENABLE_OPENSSL) ...@@ -147,7 +140,6 @@ if (OPENSSL_FOUND AND ENABLE_OPENSSL)
if (CMAKE_SYSTEM_NAME MATCHES "Linux" AND OPENSSL_USE_STATIC_LIBS) if (CMAKE_SYSTEM_NAME MATCHES "Linux" AND OPENSSL_USE_STATIC_LIBS)
list(APPEND LINK_LIB_LIST dl) list(APPEND LINK_LIB_LIST dl)
endif () endif ()
else () else ()
message(WARNING "openssl未找到,rtmp将不支持flash播放器,https/wss/rtsps/rtmps也将失效") message(WARNING "openssl未找到,rtmp将不支持flash播放器,https/wss/rtsps/rtmps也将失效")
endif () endif ()
...@@ -301,23 +293,28 @@ if (ENABLE_WEBRTC) ...@@ -301,23 +293,28 @@ if (ENABLE_WEBRTC)
file(GLOB SRC_WEBRTC_LIST ./webrtc/*.cpp ./webrtc/*.h ./webrtc/*.hpp) file(GLOB SRC_WEBRTC_LIST ./webrtc/*.cpp ./webrtc/*.h ./webrtc/*.hpp)
add_library(webrtc ${SRC_WEBRTC_LIST}) add_library(webrtc ${SRC_WEBRTC_LIST})
list(APPEND LINK_LIB_LIST webrtc) list(APPEND LINK_LIB_LIST webrtc)
message(STATUS "webrtc功能已开启")
else () else ()
message(WARNING "srtp未找到, webrtc相关功能打开失败") message(WARNING "srtp未找到, webrtc相关功能打开失败")
endif () endif ()
endif () endif ()
if (NOT IOS) #ios不编译可执行程序
#测试程序 if (IOS)
if (ENABLE_TESTS) return()
add_subdirectory(tests) endif()
endif ()
#主服务器
if (ENABLE_SERVER)
add_subdirectory(server)
endif ()
#播放器 #测试程序
if (ENABLE_PLAYER) if (ENABLE_TESTS)
add_subdirectory(player) add_subdirectory(tests)
endif () endif ()
#主服务器
if (ENABLE_SERVER)
add_subdirectory(server)
endif ()
#播放器
if (ENABLE_PLAYER)
add_subdirectory(player)
endif () endif ()
...@@ -143,10 +143,11 @@ API_EXPORT void API_CALL mk_media_set_on_close(mk_media ctx, on_mk_media_close c ...@@ -143,10 +143,11 @@ API_EXPORT void API_CALL mk_media_set_on_close(mk_media ctx, on_mk_media_close c
typedef int(API_CALL *on_mk_media_seek)(void *user_data,uint32_t stamp_ms); typedef int(API_CALL *on_mk_media_seek)(void *user_data,uint32_t stamp_ms);
/** /**
* 收到客户端的pause请求时触发该回调 * 收到客户端的pause或resume请求时触发该回调
* @param user_data 用户数据指针,通过mk_media_set_on_pause设置 * @param user_data 用户数据指针,通过mk_media_set_on_pause设置
* @param pause 1:暂停, 0: 恢复
*/ */
typedef int(API_CALL* on_mk_media_pause)(void* user_data); typedef int(API_CALL* on_mk_media_pause)(void* user_data, int pause);
/** /**
* 收到客户端的speed请求时触发该回调 * 收到客户端的speed请求时触发该回调
......
...@@ -90,9 +90,9 @@ API_EXPORT void API_CALL mk_player_seekto(mk_player ctx, float progress); ...@@ -90,9 +90,9 @@ API_EXPORT void API_CALL mk_player_seekto(mk_player ctx, float progress);
/** /**
* 设置点播进度条 * 设置点播进度条
* @param ctx 对象指针 * @param ctx 对象指针
* @param seekPos 取值范围 相对于开始时间增量 单位秒 * @param seek_pos 取值范围 相对于开始时间增量 单位秒
*/ */
API_EXPORT void API_CALL mk_player_seektoByPos(mk_player ctx, int seekPos); API_EXPORT void API_CALL mk_player_seekto_pos(mk_player ctx, int seek_pos);
/** /**
* 设置播放器开启播放结果回调函数 * 设置播放器开启播放结果回调函数
...@@ -124,7 +124,7 @@ API_EXPORT void API_CALL mk_player_set_on_data(mk_player ctx, on_mk_play_data cb ...@@ -124,7 +124,7 @@ API_EXPORT void API_CALL mk_player_set_on_data(mk_player ctx, on_mk_play_data cb
* 获取视频codec_id -1:不存在 0:H264,1:H265,2:AAC 3.G711A 4.G711U * 获取视频codec_id -1:不存在 0:H264,1:H265,2:AAC 3.G711A 4.G711U
* @param ctx 播放器指针 * @param ctx 播放器指针
*/ */
API_EXPORT int API_CALL mk_player_video_codecId(mk_player ctx); API_EXPORT int API_CALL mk_player_video_codec_id(mk_player ctx);
/** /**
* 获取视频codec_id, vendor类型, 私有头数据 codec_id -1:不存在 0:H264,1:H265,2:AAC 3.G711A 4.G711U * 获取视频codec_id, vendor类型, 私有头数据 codec_id -1:不存在 0:H264,1:H265,2:AAC 3.G711A 4.G711U
...@@ -133,7 +133,7 @@ API_EXPORT int API_CALL mk_player_video_codecId(mk_player ctx); ...@@ -133,7 +133,7 @@ API_EXPORT int API_CALL mk_player_video_codecId(mk_player ctx);
* @param head 厂家SDK头数据 * @param head 厂家SDK头数据
* @param head 厂家SDK头数据长度 * @param head 厂家SDK头数据长度
*/ */
API_EXPORT int API_CALL mk_player_video_codecId_vendor_head(mk_player ctx, char* vendor, char* head, int* headLen); API_EXPORT int API_CALL mk_player_video_codec_id_vendor_head(mk_player ctx, char* vendor, char* head, int* headLen);
/** /**
* 获取视频宽度 * 获取视频宽度
...@@ -154,7 +154,7 @@ API_EXPORT float API_CALL mk_player_video_fps(mk_player ctx); ...@@ -154,7 +154,7 @@ API_EXPORT float API_CALL mk_player_video_fps(mk_player ctx);
* 获取音频codec_id -1:不存在 0:H264,1:H265,2:AAC 3.G711A 4.G711U * 获取音频codec_id -1:不存在 0:H264,1:H265,2:AAC 3.G711A 4.G711U
* @param ctx 播放器指针 * @param ctx 播放器指针
*/ */
API_EXPORT int API_CALL mk_player_audio_codecId(mk_player ctx); API_EXPORT int API_CALL mk_player_audio_codec_id(mk_player ctx);
/** /**
* 获取音频采样率 * 获取音频采样率
......
...@@ -76,24 +76,24 @@ protected: ...@@ -76,24 +76,24 @@ protected:
return true; return true;
} }
bool seekTo(MediaSource &sender,uint32_t ui32Stamp) override{ bool seekTo(MediaSource &sender, uint32_t stamp) override {
if(!_on_seek){ if (!_on_seek) {
return false; return false;
} }
return _on_seek(_on_seek_data,ui32Stamp); return _on_seek(_on_seek_data, stamp);
} }
// 通知暂停
bool pause(MediaSource &sender) override { // 通知暂停或恢复
if (!_on_pause) bool pause(MediaSource &sender, bool pause) override {
{ if (!_on_pause) {
return false; return false;
} }
return _on_pause(_on_pause_data); return _on_pause(_on_pause_data, pause);
} }
//通知倍数播放 //通知倍数播放
bool speed(MediaSource& sender, float speed) override { bool speed(MediaSource &sender, float speed) override {
if (!_on_speed) if (!_on_speed) {
{
return false; return false;
} }
return _on_speed(_on_pause_data, speed); return _on_speed(_on_pause_data, speed);
...@@ -130,23 +130,21 @@ API_EXPORT void API_CALL mk_media_set_on_close(mk_media ctx, on_mk_media_close c ...@@ -130,23 +130,21 @@ API_EXPORT void API_CALL mk_media_set_on_close(mk_media ctx, on_mk_media_close c
(*obj)->setOnClose(cb, user_data); (*obj)->setOnClose(cb, user_data);
} }
API_EXPORT void API_CALL mk_media_set_on_seek(mk_media ctx, on_mk_media_seek cb, void *user_data){ API_EXPORT void API_CALL mk_media_set_on_seek(mk_media ctx, on_mk_media_seek cb, void *user_data) {
assert(ctx); assert(ctx);
MediaHelper::Ptr *obj = (MediaHelper::Ptr *) ctx; MediaHelper::Ptr *obj = (MediaHelper::Ptr *) ctx;
(*obj)->setOnSeek(cb, user_data); (*obj)->setOnSeek(cb, user_data);
} }
API_EXPORT void API_CALL mk_media_set_on_pause(mk_media ctx, on_mk_media_pause cb, void* user_data) API_EXPORT void API_CALL mk_media_set_on_pause(mk_media ctx, on_mk_media_pause cb, void *user_data) {
{
assert(ctx); assert(ctx);
MediaHelper::Ptr* obj = (MediaHelper::Ptr*) ctx; MediaHelper::Ptr *obj = (MediaHelper::Ptr *) ctx;
(*obj)->setOnPause(cb, user_data); (*obj)->setOnPause(cb, user_data);
} }
API_EXPORT void API_CALL mk_media_set_on_speed(mk_media ctx, on_mk_media_speed cb, void* user_data) API_EXPORT void API_CALL mk_media_set_on_speed(mk_media ctx, on_mk_media_speed cb, void *user_data) {
{
assert(ctx); assert(ctx);
MediaHelper::Ptr* obj = (MediaHelper::Ptr*) ctx; MediaHelper::Ptr *obj = (MediaHelper::Ptr *) ctx;
(*obj)->setOnSpeed(cb, user_data); (*obj)->setOnSpeed(cb, user_data);
} }
......
...@@ -171,12 +171,12 @@ API_EXPORT void API_CALL mk_player_pause(mk_player ctx, int pause) { ...@@ -171,12 +171,12 @@ API_EXPORT void API_CALL mk_player_pause(mk_player ctx, int pause) {
API_EXPORT void API_CALL mk_player_speed(mk_player ctx, float speed) { API_EXPORT void API_CALL mk_player_speed(mk_player ctx, float speed) {
assert(ctx); assert(ctx);
MediaPlayerForC& obj = **((MediaPlayerForC::Ptr*)ctx); MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *) ctx);
auto player = obj.getPlayer(); auto player = obj.getPlayer();
player->getPoller()->async([speed, player]() { player->getPoller()->async([speed, player]() {
//切换线程后再操作 //切换线程后再操作
player->speed(speed); player->speed(speed);
}); });
} }
API_EXPORT void API_CALL mk_player_seekto(mk_player ctx, float progress) { API_EXPORT void API_CALL mk_player_seekto(mk_player ctx, float progress) {
...@@ -189,14 +189,14 @@ API_EXPORT void API_CALL mk_player_seekto(mk_player ctx, float progress) { ...@@ -189,14 +189,14 @@ API_EXPORT void API_CALL mk_player_seekto(mk_player ctx, float progress) {
}); });
} }
API_EXPORT void API_CALL mk_player_seektoByPos(mk_player ctx, int seekPos){ API_EXPORT void API_CALL mk_player_seekto_pos(mk_player ctx, int seek_pos) {
assert(ctx); assert(ctx);
MediaPlayerForC& obj = **((MediaPlayerForC::Ptr*)ctx); MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *) ctx);
auto player = obj.getPlayer(); auto player = obj.getPlayer();
player->getPoller()->async([seekPos, player]() { player->getPoller()->async([seek_pos, player]() {
//切换线程后再操作 //切换线程后再操作
player->seekTo((uint32_t)seekPos); player->seekTo((uint32_t) seek_pos);
}); });
} }
static void mk_player_set_on_event(mk_player ctx, on_mk_play_event cb, void *user_data, int type) { static void mk_player_set_on_event(mk_player ctx, on_mk_play_event cb, void *user_data, int type) {
...@@ -219,30 +219,26 @@ API_EXPORT void API_CALL mk_player_set_on_data(mk_player ctx, on_mk_play_data cb ...@@ -219,30 +219,26 @@ API_EXPORT void API_CALL mk_player_set_on_data(mk_player ctx, on_mk_play_data cb
obj.setOnData(cb,user_data); obj.setOnData(cb,user_data);
} }
API_EXPORT int API_CALL mk_player_video_codecId(mk_player ctx){ API_EXPORT int API_CALL mk_player_video_codec_id(mk_player ctx){
assert(ctx); assert(ctx);
MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx); MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
auto track = dynamic_pointer_cast<VideoTrack>(obj->getTrack(TrackVideo)); auto track = dynamic_pointer_cast<VideoTrack>(obj->getTrack(TrackVideo));
return track ? track->getCodecId() : CodecInvalid; return track ? track->getCodecId() : CodecInvalid;
} }
API_EXPORT int API_CALL mk_player_video_codecId_vendor_head(mk_player ctx, char* vendor, char* head, int* head_len) API_EXPORT int API_CALL mk_player_video_codec_id_vendor_head(mk_player ctx, char *vendor, char *head, int *head_len) {
{
assert(ctx); assert(ctx);
MediaPlayerForC& obj = **((MediaPlayerForC::Ptr*)ctx); MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *) ctx);
auto track = dynamic_pointer_cast<VideoTrack>(obj->getTrack(TrackVideo)); auto track = dynamic_pointer_cast<VideoTrack>(obj->getTrack(TrackVideo));
int codecId = track ? track->getCodecId() : CodecInvalid; int codecId = track ? track->getCodecId() : CodecInvalid;
if (codecId == CodecH264) if (codecId == CodecH264) {
{
auto h264Track = dynamic_pointer_cast<H264Track>(obj->getTrack(TrackVideo)); auto h264Track = dynamic_pointer_cast<H264Track>(obj->getTrack(TrackVideo));
auto pps = h264Track->getPps(); auto pps = h264Track->getPps();
auto ppsLen = pps.size(); auto ppsLen = pps.size();
if (ppsLen >= (4 + 16)) if (ppsLen >= (4 + 16)) {
{
std::string temVendor = std::string(pps.c_str() + 4, 16); std::string temVendor = std::string(pps.c_str() + 4, 16);
memcpy(vendor, temVendor.c_str(), temVendor.length()); memcpy(vendor, temVendor.c_str(), temVendor.length());
if (ppsLen > (4 + 16)) if (ppsLen > (4 + 16)) {
{
std::string temHead = std::string(pps.c_str() + 20, ppsLen - 20); std::string temHead = std::string(pps.c_str() + 20, ppsLen - 20);
memcpy(head, temHead.c_str(), temHead.length()); memcpy(head, temHead.c_str(), temHead.length());
*head_len = temHead.length(); *head_len = temHead.length();
...@@ -273,7 +269,7 @@ API_EXPORT float API_CALL mk_player_video_fps(mk_player ctx) { ...@@ -273,7 +269,7 @@ API_EXPORT float API_CALL mk_player_video_fps(mk_player ctx) {
return track ? track->getVideoFps() : 0; return track ? track->getVideoFps() : 0;
} }
API_EXPORT int API_CALL mk_player_audio_codecId(mk_player ctx){ API_EXPORT int API_CALL mk_player_audio_codec_id(mk_player ctx){
assert(ctx); assert(ctx);
MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx); MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
auto track = dynamic_pointer_cast<AudioTrack>(obj->getTrack(TrackAudio)); auto track = dynamic_pointer_cast<AudioTrack>(obj->getTrack(TrackAudio));
......
...@@ -93,8 +93,8 @@ void API_CALL on_mk_play_event_func(void *user_data, int err_code, const char *e ...@@ -93,8 +93,8 @@ void API_CALL on_mk_play_event_func(void *user_data, int err_code, const char *e
log_debug("play success!"); log_debug("play success!");
ctx->media = mk_media_create("__defaultVhost__", "live", "test", 0, 0, 0); ctx->media = mk_media_create("__defaultVhost__", "live", "test", 0, 0, 0);
int video_codec = mk_player_video_codecId(ctx->player); int video_codec = mk_player_video_codec_id(ctx->player);
int audio_codec = mk_player_audio_codecId(ctx->player); int audio_codec = mk_player_audio_codec_id(ctx->player);
if(video_codec != -1){ if(video_codec != -1){
mk_media_init_video(ctx->media, video_codec, mk_media_init_video(ctx->media, video_codec,
mk_player_video_width(ctx->player), mk_player_video_width(ctx->player),
......
...@@ -79,16 +79,117 @@ public: ...@@ -79,16 +79,117 @@ public:
~SuccessException() = default; ~SuccessException() = default;
}; };
using ApiArgsType = map<string, variant, StrCaseCompare>; using ApiArgsType = map<string, string, StrCaseCompare>;
#define API_ARGS_MAP SockInfo &sender, HttpSession::KeyValue &headerIn, HttpSession::KeyValue &headerOut, ApiArgsType &allArgs, Json::Value &val template<typename Args, typename First>
string getValue(Args &args, const First &first) {
return args[first];
}
template<typename First>
string getValue(Json::Value &args, const First &first) {
return args[first].asString();
}
template<typename First>
string getValue(string &args, const First &first) {
return "";
}
template<typename First>
string getValue(const Parser &parser, const First &first) {
auto ret = parser.getUrlArgs()[first];
if (!ret.empty()) {
return ret;
}
return parser.getHeader()[first];
}
template<typename First>
string getValue(Parser &parser, const First &first) {
return getValue((const Parser &) parser, first);
}
template<typename Args, typename First>
string getValue(const Parser &parser, Args &args, const First &first) {
auto ret = getValue(args, first);
if (!ret.empty()) {
return ret;
}
return getValue(parser, first);
}
template<typename Args>
class HttpAllArgs {
public:
HttpAllArgs(const Parser &parser, Args &args) {
_get_args = [&args]() {
return (void *) &args;
};
_get_parser = [&parser]() -> const Parser & {
return parser;
};
_get_value = [](HttpAllArgs &that, const string &key) {
return getValue(that.getParser(), that.getArgs(), key);
};
_clone = [&](HttpAllArgs &that) {
that._get_args = [args]() {
return (void *) &args;
};
that._get_parser = [parser]() -> const Parser & {
return parser;
};
that._get_value = [](HttpAllArgs &that, const string &key) {
return getValue(that.getParser(), that.getArgs(), key);
};
that._cache_able = true;
};
}
HttpAllArgs(const HttpAllArgs &that) {
if (that._cache_able) {
_get_args = that._get_args;
_get_parser = that._get_parser;
_get_value = that._get_value;
} else {
that._clone(*this);
}
}
~HttpAllArgs() = default;
template<typename Key>
variant operator[](const Key &key) const {
return (variant)_get_value(*(HttpAllArgs*)this, key);
}
const Parser &getParser() const {
return _get_parser();
}
Args &getArgs() {
return *((Args *) _get_args());
}
const Args &getArgs() const {
return *((Args *) _get_args());
}
private:
bool _cache_able = false;
function<void *() > _get_args;
function<const Parser &() > _get_parser;
function<string(HttpAllArgs &that, const string &key)> _get_value;
function<void(HttpAllArgs &that) > _clone;
};
#define API_ARGS_MAP SockInfo &sender, HttpSession::KeyValue &headerOut, const HttpAllArgs<ApiArgsType> &allArgs, Json::Value &val
#define API_ARGS_MAP_ASYNC API_ARGS_MAP, const HttpSession::HttpResponseInvoker &invoker #define API_ARGS_MAP_ASYNC API_ARGS_MAP, const HttpSession::HttpResponseInvoker &invoker
#define API_ARGS_JSON SockInfo &sender, HttpSession::KeyValue &headerIn, HttpSession::KeyValue &headerOut, Json::Value &bodyArgs, ApiArgsType &allArgs, Json::Value &val #define API_ARGS_JSON SockInfo &sender, HttpSession::KeyValue &headerOut, const HttpAllArgs<Json::Value> &allArgs, Json::Value &val
#define API_ARGS_JSON_ASYNC API_ARGS_JSON, const HttpSession::HttpResponseInvoker &invoker #define API_ARGS_JSON_ASYNC API_ARGS_JSON, const HttpSession::HttpResponseInvoker &invoker
#define API_ARGS_STRING SockInfo &sender, HttpSession::KeyValue &headerIn, HttpSession::KeyValue &headerOut, const Parser &allArgs, Json::Value &val #define API_ARGS_STRING SockInfo &sender, HttpSession::KeyValue &headerOut, const HttpAllArgs<string> &allArgs, Json::Value &val
#define API_ARGS_STRING_ASYNC API_ARGS_STRING, const HttpSession::HttpResponseInvoker &invoker #define API_ARGS_STRING_ASYNC API_ARGS_STRING, const HttpSession::HttpResponseInvoker &invoker
#define API_ARGS_VALUE sender, headerIn, headerOut, allArgs, val #define API_ARGS_VALUE sender, headerOut, allArgs, val
#define API_ARGS_JSON_VALUE sender, headerIn, headerOut, bodyArgs, allArgs, val
//注册http请求参数是map<string, variant, StrCaseCompare>类型的http api //注册http请求参数是map<string, variant, StrCaseCompare>类型的http api
void api_regist(const string &api_path, const function<void(API_ARGS_MAP)> &func); void api_regist(const string &api_path, const function<void(API_ARGS_MAP)> &func);
...@@ -106,26 +207,16 @@ void api_regist(const string &api_path, const function<void(API_ARGS_STRING)> &f ...@@ -106,26 +207,16 @@ void api_regist(const string &api_path, const function<void(API_ARGS_STRING)> &f
void api_regist(const string &api_path, const function<void(API_ARGS_STRING_ASYNC)> &func); void api_regist(const string &api_path, const function<void(API_ARGS_STRING_ASYNC)> &func);
template<typename Args, typename First> template<typename Args, typename First>
bool checkArgs(Args &&args, First &&first) { bool checkArgs(Args &args, const First &first) {
return !args[first].empty(); return !args[first].empty();
} }
template<typename Args, typename First, typename ...KeyTypes> template<typename Args, typename First, typename ...KeyTypes>
bool checkArgs(Args &&args, First &&first, KeyTypes &&...keys) { bool checkArgs(Args &args, const First &first, const KeyTypes &...keys) {
return !args[first].empty() && checkArgs(std::forward<Args>(args), std::forward<KeyTypes>(keys)...); return checkArgs(args, first) && checkArgs(args, keys...);
}
template<typename First>
bool checkArgs(const Parser &args, First &&first) {
return !args.getUrlArgs()[first].empty();
}
template<typename First, typename ...KeyTypes>
bool checkArgs(const Parser &args, First &&first, KeyTypes &&...keys) {
return !args.getUrlArgs()[first].empty() && checkArgs(args, std::forward<KeyTypes>(keys)...);
} }
//检查http参数是否为空的宏 //检查http url中或body中或http header参数是否为空的宏
#define CHECK_ARGS(...) \ #define CHECK_ARGS(...) \
if(!checkArgs(allArgs,##__VA_ARGS__)){ \ if(!checkArgs(allArgs,##__VA_ARGS__)){ \
throw InvalidArgsException("缺少必要参数:" #__VA_ARGS__); \ throw InvalidArgsException("缺少必要参数:" #__VA_ARGS__); \
......
...@@ -157,17 +157,15 @@ bool MediaSource::seekTo(uint32_t stamp) { ...@@ -157,17 +157,15 @@ bool MediaSource::seekTo(uint32_t stamp) {
return listener->seekTo(*this, stamp); return listener->seekTo(*this, stamp);
} }
bool MediaSource::pause() bool MediaSource::pause(bool pause) {
{
auto listener = _listener.lock(); auto listener = _listener.lock();
if (!listener) { if (!listener) {
return false; return false;
} }
return listener->pause(*this); return listener->pause(*this, pause);
} }
bool MediaSource::speed(float speed) bool MediaSource::speed(float speed) {
{
auto listener = _listener.lock(); auto listener = _listener.lock();
if (!listener) { if (!listener) {
return false; return false;
...@@ -601,17 +599,15 @@ bool MediaSourceEventInterceptor::seekTo(MediaSource &sender, uint32_t stamp) { ...@@ -601,17 +599,15 @@ bool MediaSourceEventInterceptor::seekTo(MediaSource &sender, uint32_t stamp) {
return listener->seekTo(sender, stamp); return listener->seekTo(sender, stamp);
} }
bool MediaSourceEventInterceptor::pause(MediaSource& sender) bool MediaSourceEventInterceptor::pause(MediaSource &sender, bool pause) {
{
auto listener = _listener.lock(); auto listener = _listener.lock();
if (!listener) { if (!listener) {
return false; return false;
} }
return listener->pause(sender); return listener->pause(sender, pause);
} }
bool MediaSourceEventInterceptor::speed(MediaSource& sender, float speed) bool MediaSourceEventInterceptor::speed(MediaSource &sender, float speed) {
{
auto listener = _listener.lock(); auto listener = _listener.lock();
if (!listener) { if (!listener) {
return false; return false;
......
...@@ -67,10 +67,10 @@ public: ...@@ -67,10 +67,10 @@ public:
// 通知拖动进度条 // 通知拖动进度条
virtual bool seekTo(MediaSource &sender, uint32_t stamp) { return false; } virtual bool seekTo(MediaSource &sender, uint32_t stamp) { return false; }
// 通知暂停 // 通知暂停或恢复
virtual bool pause(MediaSource& sender) { return false; } virtual bool pause(MediaSource &sender, bool pause) { return false; }
// 通知倍数 // 通知倍数
virtual bool speed(MediaSource& sender, float speed) { return false; } virtual bool speed(MediaSource &sender, float speed) { return false; }
// 通知其停止产生流 // 通知其停止产生流
virtual bool close(MediaSource &sender, bool force) { return false; } virtual bool close(MediaSource &sender, bool force) { return false; }
// 获取观看总人数 // 获取观看总人数
...@@ -110,8 +110,8 @@ public: ...@@ -110,8 +110,8 @@ public:
std::shared_ptr<SockInfo> getOriginSock(MediaSource &sender) const override; std::shared_ptr<SockInfo> getOriginSock(MediaSource &sender) const override;
bool seekTo(MediaSource &sender, uint32_t stamp) override; bool seekTo(MediaSource &sender, uint32_t stamp) override;
bool pause(MediaSource& sender) override; bool pause(MediaSource &sender, bool pause) override;
bool speed(MediaSource& sender, float speed) override; bool speed(MediaSource &sender, float speed) override;
bool close(MediaSource &sender, bool force) override; bool close(MediaSource &sender, bool force) override;
int totalReaderCount(MediaSource &sender) override; int totalReaderCount(MediaSource &sender) override;
void onReaderChanged(MediaSource &sender, int size) override; void onReaderChanged(MediaSource &sender, int size) override;
...@@ -256,8 +256,7 @@ public: ...@@ -256,8 +256,7 @@ public:
// 拖动进度条 // 拖动进度条
bool seekTo(uint32_t stamp); bool seekTo(uint32_t stamp);
//暂停 //暂停
bool pause(); bool pause(bool pause);
//倍数播放 //倍数播放
bool speed(float speed); bool speed(float speed);
// 关闭该流 // 关闭该流
......
...@@ -33,11 +33,11 @@ public: ...@@ -33,11 +33,11 @@ public:
protected: protected:
void onResponseBody(const char *buf, size_t size, size_t recvedSize, size_t totalSize) override; void onResponseBody(const char *buf, size_t size, size_t recvedSize, size_t totalSize) override;
private:
ssize_t onResponseHeader(const string &status, const HttpHeader &headers) override; ssize_t onResponseHeader(const string &status, const HttpHeader &headers) override;
void onResponseCompleted() override; void onResponseCompleted() override;
void onDisconnect(const SockException &ex) override; void onDisconnect(const SockException &ex) override;
private:
void closeFile(); void closeFile();
private: private:
......
...@@ -130,7 +130,7 @@ void HttpSession::onManager() { ...@@ -130,7 +130,7 @@ void HttpSession::onManager() {
if(_ticker.elapsedTime() > keepAliveSec * 1000){ if(_ticker.elapsedTime() > keepAliveSec * 1000){
//1分钟超时 //1分钟超时
shutdown(SockException(Err_timeout,"session timeouted")); shutdown(SockException(Err_timeout,"session timeout"));
} }
} }
......
...@@ -64,8 +64,7 @@ void MediaPlayer::pause(bool pause) { ...@@ -64,8 +64,7 @@ void MediaPlayer::pause(bool pause) {
} }
} }
void MediaPlayer::speed(float speed) void MediaPlayer::speed(float speed) {
{
if (_delegate) { if (_delegate) {
_delegate->speed(speed); _delegate->speed(speed);
} }
......
...@@ -29,7 +29,7 @@ public: ...@@ -29,7 +29,7 @@ public:
virtual ~MediaPlayer(); virtual ~MediaPlayer();
void play(const string &url) override; void play(const string &url) override;
void pause(bool pause) override; void pause(bool pause) override;
void speed(float speed)override; void speed(float speed) override;
void teardown() override; void teardown() override;
EventPoller::Ptr getPoller(); EventPoller::Ptr getPoller();
void setOnCreateSocket(Socket::onCreateSocket cb); void setOnCreateSocket(Socket::onCreateSocket cb);
......
...@@ -102,7 +102,6 @@ public: ...@@ -102,7 +102,6 @@ public:
/** /**
* 获取播放进度pos,取值 相对开始时间增量 单位秒 * 获取播放进度pos,取值 相对开始时间增量 单位秒
* @return
*/ */
virtual uint32_t getProgressPos() const { return 0; } virtual uint32_t getProgressPos() const { return 0; }
...@@ -152,15 +151,16 @@ public: ...@@ -152,15 +151,16 @@ public:
typedef std::shared_ptr<PlayerImp> Ptr; typedef std::shared_ptr<PlayerImp> Ptr;
template<typename ...ArgsType> template<typename ...ArgsType>
PlayerImp(ArgsType &&...args):Parent(std::forward<ArgsType>(args)...){} PlayerImp(ArgsType &&...args):Parent(std::forward<ArgsType>(args)...) {}
virtual ~PlayerImp() {}
virtual ~PlayerImp(){}
void setOnShutdown(const function<void(const SockException &)> &cb) override { void setOnShutdown(const function<void(const SockException &)> &cb) override {
if (_delegate) { if (_delegate) {
_delegate->setOnShutdown(cb); _delegate->setOnShutdown(cb);
} }
_shutdownCB = cb; _shutdownCB = cb;
} }
void setOnPlayResult(const function<void(const SockException &ex)> &cb) override { void setOnPlayResult(const function<void(const SockException &ex)> &cb) override {
if (_delegate) { if (_delegate) {
_delegate->setOnPlayResult(cb); _delegate->setOnPlayResult(cb);
...@@ -175,31 +175,35 @@ public: ...@@ -175,31 +175,35 @@ public:
_resumeCB = cb; _resumeCB = cb;
} }
bool isInited(int analysisMs) override{ bool isInited(int analysisMs) override {
if (_delegate) { if (_delegate) {
return _delegate->isInited(analysisMs); return _delegate->isInited(analysisMs);
} }
return Parent::isInited(analysisMs); return Parent::isInited(analysisMs);
} }
float getDuration() const override { float getDuration() const override {
if (_delegate) { if (_delegate) {
return _delegate->getDuration(); return _delegate->getDuration();
} }
return Parent::getDuration(); return Parent::getDuration();
} }
float getProgress() const override{
float getProgress() const override {
if (_delegate) { if (_delegate) {
return _delegate->getProgress(); return _delegate->getProgress();
} }
return Parent::getProgress(); return Parent::getProgress();
} }
uint32_t getProgressPos() const override { uint32_t getProgressPos() const override {
if (_delegate) { if (_delegate) {
return _delegate->getProgressPos(); return _delegate->getProgressPos();
} }
return Parent::getProgressPos(); return Parent::getProgressPos();
} }
void seekTo(float fProgress) override{
void seekTo(float fProgress) override {
if (_delegate) { if (_delegate) {
return _delegate->seekTo(fProgress); return _delegate->seekTo(fProgress);
} }
...@@ -213,21 +217,21 @@ public: ...@@ -213,21 +217,21 @@ public:
return Parent::seekTo(seekPos); return Parent::seekTo(seekPos);
} }
void setMediaSource(const MediaSource::Ptr & src) override { void setMediaSource(const MediaSource::Ptr &src) override {
if (_delegate) { if (_delegate) {
_delegate->setMediaSource(src); _delegate->setMediaSource(src);
} }
_pMediaSrc = src; _pMediaSrc = src;
} }
vector<Track::Ptr> getTracks(bool trackReady = true) const override{ vector<Track::Ptr> getTracks(bool trackReady = true) const override {
if (_delegate) { if (_delegate) {
return _delegate->getTracks(trackReady); return _delegate->getTracks(trackReady);
} }
return Parent::getTracks(trackReady); return Parent::getTracks(trackReady);
} }
std::shared_ptr<SockInfo> getSockInfo() const{ std::shared_ptr<SockInfo> getSockInfo() const {
return dynamic_pointer_cast<SockInfo>(_delegate); return dynamic_pointer_cast<SockInfo>(_delegate);
} }
......
...@@ -65,7 +65,6 @@ void MP4Recorder::createFile() { ...@@ -65,7 +65,6 @@ void MP4Recorder::createFile() {
} }
_strFileTmp = strFileTmp; _strFileTmp = strFileTmp;
_strFile = strFile; _strFile = strFile;
_createFileTicker.resetTime();
} catch (std::exception &ex) { } catch (std::exception &ex) {
WarnL << ex.what(); WarnL << ex.what();
} }
...@@ -107,21 +106,21 @@ void MP4Recorder::closeFile() { ...@@ -107,21 +106,21 @@ void MP4Recorder::closeFile() {
} }
void MP4Recorder::inputFrame(const Frame::Ptr &frame) { void MP4Recorder::inputFrame(const Frame::Ptr &frame) {
if (_baseSec == 0) if (_baseSec == 0) {
_baseSec = frame->dts(); _baseSec = frame->dts();
auto dis = frame->dts() - _baseSec; }
if(!_muxer || ((dis > _max_second * 1000) &&
(!_haveVideo || (_haveVideo && frame->keyFrame()))) ){ auto duration = frame->dts() - _baseSec;
if (!_muxer || ((duration > _max_second * 1000) && (!_haveVideo || (_haveVideo && frame->keyFrame())))) {
//成立条件 //成立条件
//1、_muxer为空 //1、_muxer为空
//2、到了切片时间,并且只有音频 //2、到了切片时间,并且只有音频
//3、到了切片时间,有视频并且遇到视频的关键帧 //3、到了切片时间,有视频并且遇到视频的关键帧
DebugL << "create file dts:" << frame->dts() << " baseSec:" << _baseSec;
_baseSec = 0; _baseSec = 0;
createFile(); createFile();
} }
if(_muxer){ if (_muxer) {
//生成mp4文件 //生成mp4文件
_muxer->inputFrame(frame); _muxer->inputFrame(frame);
} }
...@@ -139,7 +138,6 @@ void MP4Recorder::resetTracks() { ...@@ -139,7 +138,6 @@ void MP4Recorder::resetTracks() {
closeFile(); closeFile();
_tracks.clear(); _tracks.clear();
_haveVideo = false; _haveVideo = false;
_createFileTicker.resetTime();
} }
} /* namespace mediakit */ } /* namespace mediakit */
......
...@@ -61,11 +61,9 @@ private: ...@@ -61,11 +61,9 @@ private:
string _strPath; string _strPath;
string _strFile; string _strFile;
string _strFileTmp; string _strFileTmp;
Ticker _createFileTicker;
RecordInfo _info; RecordInfo _info;
MP4Muxer::Ptr _muxer; MP4Muxer::Ptr _muxer;
list<Track::Ptr> _tracks; list<Track::Ptr> _tracks;
uint64_t _baseSec = 0; uint64_t _baseSec = 0;
}; };
......
...@@ -171,8 +171,7 @@ void RtmpPlayer::pause(bool bPause) { ...@@ -171,8 +171,7 @@ void RtmpPlayer::pause(bool bPause) {
send_pause(bPause); send_pause(bPause);
} }
void RtmpPlayer::speed(float speed) void RtmpPlayer::speed(float speed) {
{
//todo //todo
} }
......
...@@ -38,7 +38,7 @@ public: ...@@ -38,7 +38,7 @@ public:
void play(const string &strUrl) override; void play(const string &strUrl) override;
void pause(bool bPause) override; void pause(bool bPause) override;
void speed(float speed)override; void speed(float speed) override;
void teardown() override; void teardown() override;
protected: protected:
......
...@@ -47,7 +47,7 @@ public: ...@@ -47,7 +47,7 @@ public:
} }
void seekTo(uint32_t seekPos) override { void seekTo(uint32_t seekPos) override {
uint32_t pos = MAX(float(0), MIN(seekPos, getDuration()))*1000; uint32_t pos = MAX(float(0), MIN(seekPos, getDuration())) * 1000;
seekToMilliSecond(pos); seekToMilliSecond(pos);
} }
......
...@@ -413,23 +413,18 @@ void RtmpSession::onCmd_pause(AMFDecoder &dec) { ...@@ -413,23 +413,18 @@ void RtmpSession::onCmd_pause(AMFDecoder &dec) {
sendUserControl(paused ? CONTROL_STREAM_EOF : CONTROL_STREAM_BEGIN, STREAM_MEDIA); sendUserControl(paused ? CONTROL_STREAM_EOF : CONTROL_STREAM_BEGIN, STREAM_MEDIA);
_paused = paused; _paused = paused;
auto stongSrc = _player_src.lock(); auto strongSrc = _player_src.lock();
if (stongSrc) { if (strongSrc) {
if (_paused) strongSrc->pause(paused);
stongSrc->pause();
else
stongSrc->seekTo(-1);
} }
} }
void RtmpSession::onCmd_playCtrl(AMFDecoder& dec) void RtmpSession::onCmd_playCtrl(AMFDecoder &dec) {
{
dec.load<AMFValue>(); dec.load<AMFValue>();
auto ctrlObj = dec.load<AMFValue>(); auto ctrlObj = dec.load<AMFValue>();
int ctrlType = ctrlObj["ctrlType"].as_integer(); int ctrlType = ctrlObj["ctrlType"].as_integer();
float speed = ctrlObj["speed"].as_number(); float speed = ctrlObj["speed"].as_number();
AMFValue status(AMF_OBJECT); AMFValue status(AMF_OBJECT);
status.set("level", "status"); status.set("level", "status");
status.set("code", "NetStream.Speed.Notify"); status.set("code", "NetStream.Speed.Notify");
......
...@@ -53,7 +53,7 @@ private: ...@@ -53,7 +53,7 @@ private:
void onCmd_seek(AMFDecoder &dec); void onCmd_seek(AMFDecoder &dec);
void onCmd_pause(AMFDecoder &dec); void onCmd_pause(AMFDecoder &dec);
void onCmd_playCtrl(AMFDecoder& dec); void onCmd_playCtrl(AMFDecoder &dec);
void setMetaData(AMFDecoder &dec); void setMetaData(AMFDecoder &dec);
void onSendMedia(const RtmpPacket::Ptr &pkt); void onSendMedia(const RtmpPacket::Ptr &pkt);
......
...@@ -419,9 +419,8 @@ void RtspPlayer::pause(bool bPause) { ...@@ -419,9 +419,8 @@ void RtspPlayer::pause(bool bPause) {
sendPause(bPause ? type_pause : type_seek, getProgressMilliSecond()); sendPause(bPause ? type_pause : type_seek, getProgressMilliSecond());
} }
void RtspPlayer::speed(float speed) void RtspPlayer::speed(float speed) {
{ sendRtspRequest("PLAY", _content_base, {"Scale", StrPrinter << speed});
sendRtspRequest("PLAY", _content_base, { "Scale",StrPrinter << speed });
} }
void RtspPlayer::handleResPAUSE(const Parser& parser,int type) { void RtspPlayer::handleResPAUSE(const Parser& parser,int type) {
......
...@@ -41,8 +41,8 @@ public: ...@@ -41,8 +41,8 @@ public:
~RtspPlayer() override; ~RtspPlayer() override;
void play(const string &strUrl) override; void play(const string &strUrl) override;
void pause(bool bPause) override; void pause(bool pause) override;
void speed(float speed)override; void speed(float speed) override;
void teardown() override; void teardown() override;
float getPacketLossRate(TrackType type) const override; float getPacketLossRate(TrackType type) const override;
......
...@@ -47,12 +47,11 @@ public: ...@@ -47,12 +47,11 @@ public:
return getProgressMilliSecond(); return getProgressMilliSecond();
} }
return PlayerBase::getProgressPos(); return PlayerBase::getProgressPos();
}
}; void seekTo(float fProgress) override {
fProgress = MAX(float(0), MIN(fProgress, float(1.0)));
void seekTo(float fProgress) override{ seekToMilliSecond((uint32_t) (fProgress * getDuration() * 1000));
fProgress = MAX(float(0),MIN(fProgress,float(1.0)));
seekToMilliSecond((uint32_t)(fProgress * getDuration() * 1000));
} }
void seekTo(uint32_t seekPos) override { void seekTo(uint32_t seekPos) override {
......
...@@ -101,13 +101,13 @@ void RtspSession::onManager() { ...@@ -101,13 +101,13 @@ void RtspSession::onManager() {
if (_push_src && _alive_ticker.elapsedTime() > keep_alive_sec * 1000) { if (_push_src && _alive_ticker.elapsedTime() > keep_alive_sec * 1000) {
//推流超时 //推流超时
shutdown(SockException(Err_timeout, "pusher session timeouted")); shutdown(SockException(Err_timeout, "pusher session timeout"));
return; return;
} }
if (!_push_src && _rtp_type == Rtsp::RTP_UDP && _enable_send_rtp && _alive_ticker.elapsedTime() > keep_alive_sec * 4000) { if (!_push_src && _rtp_type == Rtsp::RTP_UDP && _enable_send_rtp && _alive_ticker.elapsedTime() > keep_alive_sec * 4000) {
//rtp over udp播放器超时 //rtp over udp播放器超时
shutdown(SockException(Err_timeout, "rtp over udp player timeouted")); shutdown(SockException(Err_timeout, "rtp over udp player timeout"));
} }
} }
...@@ -774,36 +774,27 @@ void RtspSession::handleReq_Play(const Parser &parser) { ...@@ -774,36 +774,27 @@ void RtspSession::handleReq_Play(const Parser &parser) {
} }
bool useGOP = true; bool useGOP = true;
//_enable_send_rtp = false;
float iStartTime = 0; float iStartTime = 0;
auto strRange = parser["Range"]; auto &strRange = parser["Range"];
auto strScale = parser["Scale"]; auto &strScale = parser["Scale"];
if (strScale.size() == 0)
{ if (!strScale.empty()) {
//这是设置播放速度
if (strRange.size()) { auto speed = atof(strScale.data());
//这个是seek操作 play_src->speed(speed);
auto strStart = FindField(strRange.data(), "npt=", "-"); InfoP(this) << "rtp set play speed:" << speed;
if (strStart == "now") { }
strStart = "0";
} if (!strRange.empty()) {
iStartTime = 1000 * (float)atof(strStart.data()); //这是seek操作
InfoP(this) << "rtsp seekTo(ms):" << iStartTime; _enable_send_rtp = false;
useGOP = !play_src->seekTo((uint32_t)iStartTime); auto strStart = FindField(strRange.data(), "npt=", "-");
} if (strStart == "now") {
else if (play_src->totalReaderCount() == 0) { strStart = "0";
//第一个消费者
play_src->seekTo(0);
}
else if (play_src->totalReaderCount() > 0)
{
_enable_send_rtp = true;
play_src->seekTo(-1);
} }
} iStartTime = 1000 * (float) atof(strStart.data());
else useGOP = !play_src->seekTo((uint32_t) iStartTime);
{ InfoP(this) << "rtsp seekTo(ms):" << iStartTime;
play_src->speed(atof(strScale.data()));
} }
_StrPrinter rtp_info; _StrPrinter rtp_info;
...@@ -828,7 +819,10 @@ void RtspSession::handleReq_Play(const Parser &parser) { ...@@ -828,7 +819,10 @@ void RtspSession::handleReq_Play(const Parser &parser) {
"RTP-Info",rtp_info "RTP-Info",rtp_info
}); });
//在回复rtsp信令后再恢复播放
_enable_send_rtp = true; _enable_send_rtp = true;
play_src->pause(false);
setSocketFlags(); setSocketFlags();
if (!_play_reader && _rtp_type != Rtsp::RTP_MULTICAST) { if (!_play_reader && _rtp_type != Rtsp::RTP_MULTICAST) {
...@@ -856,26 +850,21 @@ void RtspSession::handleReq_Play(const Parser &parser) { ...@@ -856,26 +850,21 @@ void RtspSession::handleReq_Play(const Parser &parser) {
void RtspSession::handleReq_Pause(const Parser &parser) { void RtspSession::handleReq_Pause(const Parser &parser) {
if (parser["Session"] != _sessionid) { if (parser["Session"] != _sessionid) {
send_SessionNotFound(); send_SessionNotFound();
throw SockException(Err_shutdown,"session not found when pause"); throw SockException(Err_shutdown, "session not found when pause");
} }
sendRtspResponse("200 OK"); sendRtspResponse("200 OK");
_enable_send_rtp = false;
auto play_src = _play_src.lock(); auto play_src = _play_src.lock();
if (!play_src) { if (play_src) {
send_StreamNotFound(); play_src->pause(true);
shutdown(SockException(Err_shutdown, "rtsp stream released"));
return;
} }
play_src->pause();
//_enable_send_rtp = false;
} }
void RtspSession::handleReq_Teardown(const Parser &parser) { void RtspSession::handleReq_Teardown(const Parser &parser) {
sendRtspResponse("200 OK"); sendRtspResponse("200 OK");
throw SockException(Err_shutdown,"rtsp player send teardown request"); throw SockException(Err_shutdown,"recv teardown request");
} }
void RtspSession::handleReq_Get(const Parser &parser) { void RtspSession::handleReq_Get(const Parser &parser) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论