From af2481c619bd2b9bebbd9914d7a3b1a009fa951e Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Sat, 23 Jan 2021 09:42:15 +0800 Subject: [PATCH] =?UTF-8?q?ffmpeg=E6=8B=89=E6=B5=81=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E5=91=BD=E4=BB=A4=E6=A8=A1=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/FFmpegSource.cpp | 21 ++++++++++++++++----- server/FFmpegSource.h | 4 +++- server/WebApi.cpp | 9 +++++---- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/server/FFmpegSource.cpp b/server/FFmpegSource.cpp index 150b0603..145787b1 100644 --- a/server/FFmpegSource.cpp +++ b/server/FFmpegSource.cpp @@ -64,17 +64,28 @@ void FFmpegSource::setupRecordFlag(bool enable_hls, bool enable_mp4){ _enable_mp4 = enable_mp4; } -void FFmpegSource::play(const string &src_url,const string &dst_url,int timeout_ms,const onPlay &cb) { +void FFmpegSource::play(const string &ffmpeg_cmd_key, const string &src_url,const string &dst_url,int timeout_ms,const onPlay &cb) { GET_CONFIG(string,ffmpeg_bin,FFmpeg::kBin); - GET_CONFIG(string,ffmpeg_cmd,FFmpeg::kCmd); + GET_CONFIG(string,ffmpeg_cmd_default,FFmpeg::kCmd); GET_CONFIG(string,ffmpeg_log,FFmpeg::kLog); _src_url = src_url; _dst_url = dst_url; + _ffmpeg_cmd_key = ffmpeg_cmd_key; _media_info.parse(dst_url); + auto ffmpeg_cmd = ffmpeg_cmd_default; + if (!ffmpeg_cmd_key.empty()) { + auto cmd_it = mINI::Instance().find(ffmpeg_cmd_key); + if (cmd_it != mINI::Instance().end()) { + ffmpeg_cmd = cmd_it->second; + } else{ + WarnL << "配置文件中,ffmpeg命令模板(" << ffmpeg_cmd_key << ")不存在,已采用默认模板(" << ffmpeg_cmd_default << ")"; + } + } + char cmd[1024] = {0}; - snprintf(cmd, sizeof(cmd),ffmpeg_cmd.data(),ffmpeg_bin.data(),src_url.data(),dst_url.data()); + snprintf(cmd, sizeof(cmd), ffmpeg_cmd.data(), ffmpeg_bin.data(), src_url.data(), dst_url.data()); _process.run(cmd,ffmpeg_log.empty() ? "" : File::absolutePath("",ffmpeg_log)); InfoL << cmd; @@ -206,7 +217,7 @@ void FFmpegSource::startTimer(int timeout_ms) { if(strongSelf->_replay_ticker.elapsedTime() > 20 * 1000){ //上次重试时间超过10秒,那么再重试FFmpeg拉流 strongSelf->_replay_ticker.resetTime(); - strongSelf->play(strongSelf->_src_url, strongSelf->_dst_url, timeout_ms, [](const SockException &) {}); + strongSelf->play(strongSelf->_ffmpeg_cmd_key, strongSelf->_src_url, strongSelf->_dst_url, timeout_ms, [](const SockException &) {}); } } }); @@ -214,7 +225,7 @@ void FFmpegSource::startTimer(int timeout_ms) { //推流给其他服务器的,我们通过判断FFmpeg进程是否在线,如果FFmpeg推流中断,那么它应该会自动退出 if (!strongSelf->_process.wait(false)) { //ffmpeg不在线,重新拉流 - strongSelf->play(strongSelf->_src_url, strongSelf->_dst_url, timeout_ms, [weakSelf](const SockException &ex) { + strongSelf->play(strongSelf->_ffmpeg_cmd_key, strongSelf->_src_url, strongSelf->_dst_url, timeout_ms, [weakSelf](const SockException &ex) { if(!ex){ //没有错误 return; diff --git a/server/FFmpegSource.h b/server/FFmpegSource.h index 8bc8cff5..69a653d2 100644 --- a/server/FFmpegSource.h +++ b/server/FFmpegSource.h @@ -55,12 +55,13 @@ public: /** * 开始播放url + * @param ffmpeg_cmd_key FFmpeg拉流命令配置项key,用户可以在配置文件中同时设置多个命令参数模板 * @param src_url FFmpeg拉流地址 * @param dst_url FFmpeg推流地址 * @param timeout_ms 等待结果超时时间,单位毫秒 * @param cb 成功与否回调 */ - void play(const string &src_url, const string &dst_url, int timeout_ms, const onPlay &cb); + void play(const string &ffmpeg_cmd_key, const string &src_url, const string &dst_url, int timeout_ms, const onPlay &cb); /** * 设置录制 @@ -93,6 +94,7 @@ private: MediaInfo _media_info; string _src_url; string _dst_url; + string _ffmpeg_cmd_key; function _onClose; Ticker _replay_ticker; }; diff --git a/server/WebApi.cpp b/server/WebApi.cpp index d393f78a..5e431161 100755 --- a/server/WebApi.cpp +++ b/server/WebApi.cpp @@ -662,7 +662,8 @@ void installWebApi() { val["data"]["flag"] = s_proxyMap.erase(allArgs["key"]) == 1; }); - static auto addFFmpegSource = [](const string &src_url, + static auto addFFmpegSource = [](const string &ffmpeg_cmd_key, + const string &src_url, const string &dst_url, int timeout_ms, bool enable_hls, @@ -684,7 +685,7 @@ void installWebApi() { s_ffmpegMap.erase(key); }); ffmpeg->setupRecordFlag(enable_hls, enable_mp4); - ffmpeg->play(src_url, dst_url, timeout_ms, [cb, key](const SockException &ex) { + ffmpeg->play(ffmpeg_cmd_key, src_url, dst_url, timeout_ms, [cb, key](const SockException &ex) { if (ex) { lock_guard lck(s_ffmpegMapMtx); s_ffmpegMap.erase(key); @@ -704,7 +705,7 @@ void installWebApi() { auto enable_hls = allArgs["enable_hls"].as(); auto enable_mp4 = allArgs["enable_mp4"].as(); - addFFmpegSource(src_url, dst_url, timeout_ms, enable_hls, enable_mp4, + addFFmpegSource(allArgs["ffmpeg_cmd_key"], src_url, dst_url, timeout_ms, enable_hls, enable_mp4, [invoker, val, headerOut](const SockException &ex, const string &key) { if (ex) { const_cast(val)["code"] = API::OtherFailed; @@ -1080,7 +1081,7 @@ void installWebApi() { << allArgs["stream"] << "?vhost=" << allArgs["vhost"]; - addFFmpegSource("http://hls-ott-zhibo.wasu.tv/live/272/index.m3u8",/** ffmpeg拉流支持任意编码格式任意协议 **/ + addFFmpegSource("", "http://hls-ott-zhibo.wasu.tv/live/272/index.m3u8",/** ffmpeg拉流支持任意编码格式任意协议 **/ dst_url, (1000 * timeout_sec) - 500, false,