mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-24 03:30:52 +08:00
Compare commits
5 Commits
efac670778
...
beb7171efe
Author | SHA1 | Date | |
---|---|---|---|
|
beb7171efe | ||
|
8ccb4e95b3 | ||
|
901c381300 | ||
|
6729257eab | ||
|
ea263b9205 |
@ -19,7 +19,8 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// /////////////////////////////////////////flv录制///////////////////////////////////////////// [AUTO-TRANSLATED:a084663f]
|
// /////////////////////////////////////////flv录制///////////////////////////////////////////// [AUTO-TRANSLATED:a084663f]
|
||||||
// /////////////////////////////////////////flv录制/////////////////////////////////////////////
|
// /////////////////////////////////////////flv录制///////////////////////////////////////////// [AUTO-TRANSLATED:dbe04ff9]
|
||||||
|
// /////////////////////////////////////////FLV recording/////////////////////////////////////////////
|
||||||
|
|
||||||
typedef struct mk_flv_recorder_t *mk_flv_recorder;
|
typedef struct mk_flv_recorder_t *mk_flv_recorder;
|
||||||
|
|
||||||
@ -64,7 +65,8 @@ API_EXPORT void API_CALL mk_flv_recorder_release(mk_flv_recorder ctx);
|
|||||||
API_EXPORT int API_CALL mk_flv_recorder_start(mk_flv_recorder ctx, const char *vhost, const char *app, const char *stream, const char *file_path);
|
API_EXPORT int API_CALL mk_flv_recorder_start(mk_flv_recorder ctx, const char *vhost, const char *app, const char *stream, const char *file_path);
|
||||||
|
|
||||||
// /////////////////////////////////////////hls/mp4录制///////////////////////////////////////////// [AUTO-TRANSLATED:99c61c68]
|
// /////////////////////////////////////////hls/mp4录制///////////////////////////////////////////// [AUTO-TRANSLATED:99c61c68]
|
||||||
// /////////////////////////////////////////hls/mp4录制/////////////////////////////////////////////
|
// /////////////////////////////////////////hls/mp4录制///////////////////////////////////////////// [AUTO-TRANSLATED:0f2773b8]
|
||||||
|
// /////////////////////////////////////////HLS/MP4 recording/////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取录制状态
|
* 获取录制状态
|
||||||
@ -133,6 +135,15 @@ API_EXPORT int API_CALL mk_recorder_stop(int type, const char *vhost, const char
|
|||||||
* @param file_path 文件路径
|
* @param file_path 文件路径
|
||||||
* @param file_repeat 循环解复用
|
* @param file_repeat 循环解复用
|
||||||
* @param ini 配置
|
* @param ini 配置
|
||||||
|
* Load MP4 list
|
||||||
|
* @param vhost Virtual host
|
||||||
|
* @param app App
|
||||||
|
* @param stream Stream ID
|
||||||
|
* @param file_path File path
|
||||||
|
* @param file_repeat Loop demux
|
||||||
|
* @param ini Configuration
|
||||||
|
|
||||||
|
* [AUTO-TRANSLATED:2fa2d09a]
|
||||||
*/
|
*/
|
||||||
API_EXPORT void API_CALL mk_load_mp4_file(const char *vhost, const char *app, const char *stream, const char *file_path, int file_repeat);
|
API_EXPORT void API_CALL mk_load_mp4_file(const char *vhost, const char *app, const char *stream, const char *file_path, int file_repeat);
|
||||||
API_EXPORT void API_CALL mk_load_mp4_file2(const char *vhost, const char *app, const char *stream, const char *file_path, int file_repeat, mk_ini ini);
|
API_EXPORT void API_CALL mk_load_mp4_file2(const char *vhost, const char *app, const char *stream, const char *file_path, int file_repeat, mk_ini ini);
|
||||||
|
@ -700,6 +700,58 @@
|
|||||||
},
|
},
|
||||||
"response": []
|
"response": []
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "获取拉流代理列表(listStreamProxy)",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{ZLMediaKit_URL}}/index/api/listStreamProxy?secret={{ZLMediaKit_secret}}",
|
||||||
|
"host": [
|
||||||
|
"{{ZLMediaKit_URL}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"index",
|
||||||
|
"api",
|
||||||
|
"listStreamProxy"
|
||||||
|
],
|
||||||
|
"query": [
|
||||||
|
{
|
||||||
|
"key": "secret",
|
||||||
|
"value": "{{ZLMediaKit_secret}}",
|
||||||
|
"description": "api操作密钥(配置文件配置)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "获取推流代理列表(listStreamPusherProxy)",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{ZLMediaKit_URL}}/index/api/listStreamPusherProxy?secret={{ZLMediaKit_secret}}",
|
||||||
|
"host": [
|
||||||
|
"{{ZLMediaKit_URL}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"index",
|
||||||
|
"api",
|
||||||
|
"listStreamPusherProxy"
|
||||||
|
],
|
||||||
|
"query": [
|
||||||
|
{
|
||||||
|
"key": "secret",
|
||||||
|
"value": "{{ZLMediaKit_secret}}",
|
||||||
|
"description": "api操作密钥(配置文件配置)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "添加rtsp/rtmp推流(addStreamPusherProxy)",
|
"name": "添加rtsp/rtmp推流(addStreamPusherProxy)",
|
||||||
"request": {
|
"request": {
|
||||||
@ -800,6 +852,32 @@
|
|||||||
},
|
},
|
||||||
"response": []
|
"response": []
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "获取FFmpeg拉流代理列表(listFFmpegSource)",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{ZLMediaKit_URL}}/index/api/listFFmpegSource?secret={{ZLMediaKit_secret}}",
|
||||||
|
"host": [
|
||||||
|
"{{ZLMediaKit_URL}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"index",
|
||||||
|
"api",
|
||||||
|
"listFFmpegSource"
|
||||||
|
],
|
||||||
|
"query": [
|
||||||
|
{
|
||||||
|
"key": "secret",
|
||||||
|
"value": "{{ZLMediaKit_secret}}",
|
||||||
|
"description": "api操作密钥(配置文件配置)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "添加FFmpeg拉流代理(addFFmpegSource)",
|
"name": "添加FFmpeg拉流代理(addFFmpegSource)",
|
||||||
"request": {
|
"request": {
|
||||||
|
@ -103,6 +103,7 @@ void FFmpegSource::play(const string &ffmpeg_cmd_key, const string &src_url, con
|
|||||||
snprintf(cmd, sizeof(cmd), ffmpeg_cmd.data(), File::absolutePath("", ffmpeg_bin).data(), src_url.data(), dst_url.data());
|
snprintf(cmd, sizeof(cmd), ffmpeg_cmd.data(), File::absolutePath("", ffmpeg_bin).data(), src_url.data(), dst_url.data());
|
||||||
auto log_file = ffmpeg_log.empty() ? "" : File::absolutePath("", ffmpeg_log);
|
auto log_file = ffmpeg_log.empty() ? "" : File::absolutePath("", ffmpeg_log);
|
||||||
_process.run(cmd, log_file);
|
_process.run(cmd, log_file);
|
||||||
|
_cmd = cmd;
|
||||||
InfoL << cmd;
|
InfoL << cmd;
|
||||||
|
|
||||||
if (is_local_ip(_media_info.host)) {
|
if (is_local_ip(_media_info.host)) {
|
||||||
|
@ -77,6 +77,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
void play(const std::string &ffmpeg_cmd_key, const std::string &src_url, const std::string &dst_url, int timeout_ms, const onPlay &cb);
|
void play(const std::string &ffmpeg_cmd_key, const std::string &src_url, const std::string &dst_url, int timeout_ms, const onPlay &cb);
|
||||||
|
|
||||||
|
const std::string& getSrcUrl() const { return _src_url; }
|
||||||
|
const std::string& getDstUrl() const { return _dst_url; }
|
||||||
|
const std::string& getCmd() const { return _cmd; }
|
||||||
|
const std::string& getCmdKey() const { return _ffmpeg_cmd_key; }
|
||||||
|
const mediakit::MediaInfo& getMediaInfo() const { return _media_info; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置录制
|
* 设置录制
|
||||||
* @param enable_hls 是否开启hls直播或录制
|
* @param enable_hls 是否开启hls直播或录制
|
||||||
@ -115,6 +121,7 @@ private:
|
|||||||
std::string _src_url;
|
std::string _src_url;
|
||||||
std::string _dst_url;
|
std::string _dst_url;
|
||||||
std::string _ffmpeg_cmd_key;
|
std::string _ffmpeg_cmd_key;
|
||||||
|
std::string _cmd;
|
||||||
std::function<void()> _onClose;
|
std::function<void()> _onClose;
|
||||||
toolkit::Ticker _replay_ticker;
|
toolkit::Ticker _replay_ticker;
|
||||||
};
|
};
|
||||||
|
@ -346,6 +346,15 @@ public:
|
|||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void for_each(const std::function<void(const std::string&, const Pointer&)>& cb) {
|
||||||
|
std::lock_guard<std::recursive_mutex> lck(_mtx);
|
||||||
|
auto it = _map.begin();
|
||||||
|
while (it != _map.end()) {
|
||||||
|
cb(it->first, it->second);
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<class ..._Args>
|
template<class ..._Args>
|
||||||
Pointer make(const std::string &key, _Args&& ...__args) {
|
Pointer make(const std::string &key, _Args&& ...__args) {
|
||||||
// assert(!find(key));
|
// assert(!find(key));
|
||||||
@ -409,6 +418,29 @@ void dumpMediaTuple(const MediaTuple &tuple, Json::Value& item) {
|
|||||||
item["params"] = tuple.params;
|
item["params"] = tuple.params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value ToJson(const PusherProxy::Ptr& p) {
|
||||||
|
Value item;
|
||||||
|
item["url"] = p->getUrl();
|
||||||
|
item["status"] = p->getStatus();
|
||||||
|
item["liveSecs"] = p->getLiveSecs();
|
||||||
|
item["rePublishCount"] = p->getRePublishCount();
|
||||||
|
if (auto src = p->getSrc()) {
|
||||||
|
dumpMediaTuple(src->getMediaTuple(), item["src"]);
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
Value ToJson(const PlayerProxy::Ptr& p) {
|
||||||
|
Value item;
|
||||||
|
item["url"] = p->getUrl();
|
||||||
|
item["status"] = p->getStatus();
|
||||||
|
item["liveSecs"] = p->getLiveSecs();
|
||||||
|
item["rePullCount"] = p->getRePullCount();
|
||||||
|
item["totalReaderCount"] = p->totalReaderCount();
|
||||||
|
dumpMediaTuple(p->getMediaTuple(), item["src"]);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
Value makeMediaSourceJson(MediaSource &media){
|
Value makeMediaSourceJson(MediaSource &media){
|
||||||
Value item;
|
Value item;
|
||||||
item["schema"] = media.getSchema();
|
item["schema"] = media.getSchema();
|
||||||
@ -1173,7 +1205,22 @@ void installWebApi() {
|
|||||||
CHECK_ARGS("key");
|
CHECK_ARGS("key");
|
||||||
val["data"]["flag"] = s_pusher_proxy.erase(allArgs["key"]) == 1;
|
val["data"]["flag"] = s_pusher_proxy.erase(allArgs["key"]) == 1;
|
||||||
});
|
});
|
||||||
|
api_regist("/index/api/listStreamPusherProxy", [](API_ARGS_MAP) {
|
||||||
|
CHECK_SECRET();
|
||||||
|
s_pusher_proxy.for_each([&val](const std::string& key, const PusherProxy::Ptr& p) {
|
||||||
|
Json::Value item = ToJson(p);
|
||||||
|
item["key"] = key;
|
||||||
|
val["data"].append(item);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
api_regist("/index/api/listStreamProxy", [](API_ARGS_MAP) {
|
||||||
|
CHECK_SECRET();
|
||||||
|
s_player_proxy.for_each([&val](const std::string& key, const PlayerProxy::Ptr& p) {
|
||||||
|
Json::Value item = ToJson(p);
|
||||||
|
item["key"] = key;
|
||||||
|
val["data"].append(item);
|
||||||
|
});
|
||||||
|
});
|
||||||
// 动态添加rtsp/rtmp拉流代理 [AUTO-TRANSLATED:2616537c]
|
// 动态添加rtsp/rtmp拉流代理 [AUTO-TRANSLATED:2616537c]
|
||||||
// Dynamically add rtsp/rtmp pull stream proxy
|
// Dynamically add rtsp/rtmp pull stream proxy
|
||||||
// 测试url http://127.0.0.1/index/api/addStreamProxy?vhost=__defaultVhost__&app=proxy&enable_rtsp=1&enable_rtmp=1&stream=0&url=rtmp://127.0.0.1/live/obs [AUTO-TRANSLATED:71ddce15]
|
// 测试url http://127.0.0.1/index/api/addStreamProxy?vhost=__defaultVhost__&app=proxy&enable_rtsp=1&enable_rtmp=1&stream=0&url=rtmp://127.0.0.1/live/obs [AUTO-TRANSLATED:71ddce15]
|
||||||
@ -1286,7 +1333,18 @@ void installWebApi() {
|
|||||||
CHECK_ARGS("key");
|
CHECK_ARGS("key");
|
||||||
val["data"]["flag"] = s_ffmpeg_src.erase(allArgs["key"]) == 1;
|
val["data"]["flag"] = s_ffmpeg_src.erase(allArgs["key"]) == 1;
|
||||||
});
|
});
|
||||||
|
api_regist("/index/api/listFFmpegSource", [](API_ARGS_MAP) {
|
||||||
|
CHECK_SECRET();
|
||||||
|
s_ffmpeg_src.for_each([&val](const std::string& key, const FFmpegSource::Ptr& src) {
|
||||||
|
Json::Value item;
|
||||||
|
item["src_url"] = src->getSrcUrl();
|
||||||
|
item["dst_url"] = src->getDstUrl();
|
||||||
|
item["cmd"] = src->getCmd();
|
||||||
|
item["ffmpeg_cmd_key"] = src->getCmdKey();
|
||||||
|
item["key"] = key;
|
||||||
|
val["data"].append(item);
|
||||||
|
});
|
||||||
|
});
|
||||||
// 新增http api下载可执行程序文件接口 [AUTO-TRANSLATED:d6e44e84]
|
// 新增http api下载可执行程序文件接口 [AUTO-TRANSLATED:d6e44e84]
|
||||||
// Add a new http api to download executable files
|
// Add a new http api to download executable files
|
||||||
// 测试url http://127.0.0.1/index/api/downloadBin [AUTO-TRANSLATED:9525e834]
|
// 测试url http://127.0.0.1/index/api/downloadBin [AUTO-TRANSLATED:9525e834]
|
||||||
@ -1477,7 +1535,11 @@ void installWebApi() {
|
|||||||
obj["vhost"] = vec[0];
|
obj["vhost"] = vec[0];
|
||||||
obj["app"] = vec[1];
|
obj["app"] = vec[1];
|
||||||
obj["stream_id"] = vec[2];
|
obj["stream_id"] = vec[2];
|
||||||
obj["port"] = pr.second->getPort();
|
auto& rtps = pr.second;
|
||||||
|
obj["port"] = rtps->getPort();
|
||||||
|
obj["ssrc"] = rtps->getSSRC();
|
||||||
|
obj["tcp_mode"] = rtps->getTcpMode();
|
||||||
|
obj["only_track"] = rtps->getOnlyTrack();
|
||||||
val["data"].append(obj);
|
val["data"].append(obj);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1741,9 +1803,7 @@ void installWebApi() {
|
|||||||
throw ApiRetException("can not find pusher", API::NotFound);
|
throw ApiRetException("can not find pusher", API::NotFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
val["data"]["status"] = pusher->getStatus();
|
val["data"] = ToJson(pusher);
|
||||||
val["data"]["liveSecs"] = pusher->getLiveSecs();
|
|
||||||
val["data"]["rePublishCount"] = pusher->getRePublishCount();
|
|
||||||
invoker(200, headerOut, val.toStyledString());
|
invoker(200, headerOut, val.toStyledString());
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1755,9 +1815,7 @@ void installWebApi() {
|
|||||||
throw ApiRetException("can not find the proxy", API::NotFound);
|
throw ApiRetException("can not find the proxy", API::NotFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
val["data"]["status"] = proxy->getStatus();
|
val["data"] = ToJson(proxy);
|
||||||
val["data"]["liveSecs"] = proxy->getLiveSecs();
|
|
||||||
val["data"]["rePullCount"] = proxy->getRePullCount();
|
|
||||||
invoker(200, headerOut, val.toStyledString());
|
invoker(200, headerOut, val.toStyledString());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -139,6 +139,10 @@ public:
|
|||||||
// Using this only makes sense after a successful connection to the server
|
// Using this only makes sense after a successful connection to the server
|
||||||
TranslationInfo getTranslationInfo();
|
TranslationInfo getTranslationInfo();
|
||||||
|
|
||||||
|
const std::string& getUrl() const { return _pull_url; }
|
||||||
|
const MediaTuple& getMediaTuple() const { return _tuple; }
|
||||||
|
const ProtocolOption& getOption() const { return _option; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// MediaSourceEvent override
|
// MediaSourceEvent override
|
||||||
bool close(MediaSource &sender) override;
|
bool close(MediaSource &sender) override;
|
||||||
|
@ -46,6 +46,7 @@ void MediaPusher::publish(const string &url) {
|
|||||||
_delegate->setOnPublished(_on_publish);
|
_delegate->setOnPublished(_on_publish);
|
||||||
_delegate->mINI::operator=(*this);
|
_delegate->mINI::operator=(*this);
|
||||||
_delegate->publish(url);
|
_delegate->publish(url);
|
||||||
|
_url = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
EventPoller::Ptr MediaPusher::getPoller(){
|
EventPoller::Ptr MediaPusher::getPoller(){
|
||||||
|
@ -33,11 +33,13 @@ public:
|
|||||||
void publish(const std::string &url) override;
|
void publish(const std::string &url) override;
|
||||||
toolkit::EventPoller::Ptr getPoller();
|
toolkit::EventPoller::Ptr getPoller();
|
||||||
void setOnCreateSocket(toolkit::Socket::onCreateSocket cb);
|
void setOnCreateSocket(toolkit::Socket::onCreateSocket cb);
|
||||||
|
std::shared_ptr<MediaSource> getSrc() { return _src.lock(); }
|
||||||
|
const std::string& getUrl() const { return _url; }
|
||||||
private:
|
private:
|
||||||
std::weak_ptr<MediaSource> _src;
|
std::weak_ptr<MediaSource> _src;
|
||||||
toolkit::EventPoller::Ptr _poller;
|
toolkit::EventPoller::Ptr _poller;
|
||||||
toolkit::Socket::onCreateSocket _on_create_socket;
|
toolkit::Socket::onCreateSocket _on_create_socket;
|
||||||
|
std::string _url;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace mediakit */
|
} /* namespace mediakit */
|
||||||
|
@ -19,7 +19,6 @@ PusherProxy::PusherProxy(const MediaSource::Ptr &src, int retry_count, const Eve
|
|||||||
: MediaPusher(src, poller) {
|
: MediaPusher(src, poller) {
|
||||||
_retry_count = retry_count;
|
_retry_count = retry_count;
|
||||||
_on_close = [](const SockException &) {};
|
_on_close = [](const SockException &) {};
|
||||||
_weak_src = src;
|
|
||||||
_live_secs = 0;
|
_live_secs = 0;
|
||||||
_live_status = 1;
|
_live_status = 1;
|
||||||
_republish_count = 0;
|
_republish_count = 0;
|
||||||
@ -52,7 +51,7 @@ void PusherProxy::publish(const string &dst_url) {
|
|||||||
strong_self->_on_publish = nullptr;
|
strong_self->_on_publish = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto src = strong_self->_weak_src.lock();
|
auto src = strong_self->getSrc();
|
||||||
if (!err) {
|
if (!err) {
|
||||||
// 推流成功 [AUTO-TRANSLATED:28ce6e56]
|
// 推流成功 [AUTO-TRANSLATED:28ce6e56]
|
||||||
// Stream successfully pushed
|
// Stream successfully pushed
|
||||||
@ -87,7 +86,7 @@ void PusherProxy::publish(const string &dst_url) {
|
|||||||
TraceL << " live secs " << strong_self->_live_secs;
|
TraceL << " live secs " << strong_self->_live_secs;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto src = strong_self->_weak_src.lock();
|
auto src = strong_self->getSrc();
|
||||||
// 推流异常中断,延时重试播放 [AUTO-TRANSLATED:e69e5a05]
|
// 推流异常中断,延时重试播放 [AUTO-TRANSLATED:e69e5a05]
|
||||||
// Stream abnormally interrupted, retry playing with delay
|
// Stream abnormally interrupted, retry playing with delay
|
||||||
if (src && (*failed_cnt < strong_self->_retry_count || strong_self->_retry_count < 0)) {
|
if (src && (*failed_cnt < strong_self->_retry_count || strong_self->_retry_count < 0)) {
|
||||||
|
@ -77,7 +77,6 @@ private:
|
|||||||
std::atomic<int> _live_status;
|
std::atomic<int> _live_status;
|
||||||
std::atomic<uint64_t> _live_secs;
|
std::atomic<uint64_t> _live_secs;
|
||||||
std::atomic<uint64_t> _republish_count;
|
std::atomic<uint64_t> _republish_count;
|
||||||
std::weak_ptr<MediaSource> _weak_src;
|
|
||||||
std::function<void(const toolkit::SockException &ex)> _on_close;
|
std::function<void(const toolkit::SockException &ex)> _on_close;
|
||||||
std::function<void(const toolkit::SockException &ex)> _on_publish;
|
std::function<void(const toolkit::SockException &ex)> _on_publish;
|
||||||
};
|
};
|
||||||
|
@ -126,7 +126,7 @@ bool MP4Recorder::inputFrame(const Frame::Ptr &frame) {
|
|||||||
if (_last_dts == 0 || _last_dts > frame->dts()) {
|
if (_last_dts == 0 || _last_dts > frame->dts()) {
|
||||||
// b帧情况下dts时间戳可能回退 [AUTO-TRANSLATED:1de38f77]
|
// b帧情况下dts时间戳可能回退 [AUTO-TRANSLATED:1de38f77]
|
||||||
// In the case of b-frames, the dts timestamp may regress
|
// In the case of b-frames, the dts timestamp may regress
|
||||||
_last_dts = MAX(frame->dts(), _last_dts);
|
_last_dts = MIN(frame->dts(), _last_dts);
|
||||||
}
|
}
|
||||||
auto duration = 5u; // 默认至少一帧5ms
|
auto duration = 5u; // 默认至少一帧5ms
|
||||||
if (frame->dts() > 0 && frame->dts() > _last_dts) {
|
if (frame->dts() > 0 && frame->dts() > _last_dts) {
|
||||||
|
@ -295,5 +295,15 @@ void RtpServer::updateSSRC(uint32_t ssrc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t RtpServer::getSSRC() const {
|
||||||
|
if (_ssrc) {
|
||||||
|
return *_ssrc;
|
||||||
|
}
|
||||||
|
if (_tcp_server) {
|
||||||
|
return (*_tcp_server)[RtpSession::kSSRC];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
}//namespace mediakit
|
}//namespace mediakit
|
||||||
#endif//defined(ENABLE_RTPPROXY)
|
#endif//defined(ENABLE_RTPPROXY)
|
||||||
|
@ -97,6 +97,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
void updateSSRC(uint32_t ssrc);
|
void updateSSRC(uint32_t ssrc);
|
||||||
|
|
||||||
|
uint32_t getSSRC() const;
|
||||||
|
int getOnlyTrack() const { return _only_track; }
|
||||||
|
TcpMode getTcpMode() const { return _tcp_mode; }
|
||||||
private:
|
private:
|
||||||
// tcp主动模式连接服务器成功回调 [AUTO-TRANSLATED:0775844e]
|
// tcp主动模式连接服务器成功回调 [AUTO-TRANSLATED:0775844e]
|
||||||
// tcp active mode connection server success callback
|
// tcp active mode connection server success callback
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit b02d2a4c1abf95db45e50bb77d789defa0fcc4b7
|
Subproject commit 353af1f60115767e57662107e30935ac6ef178a2
|
Loading…
Reference in New Issue
Block a user