mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-22 19:00:01 +08:00
ffmpeg拉流支持指定命令模板
This commit is contained in:
parent
f63b2b1863
commit
af2481c619
@ -64,17 +64,28 @@ void FFmpegSource::setupRecordFlag(bool enable_hls, bool enable_mp4){
|
|||||||
_enable_mp4 = 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_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);
|
GET_CONFIG(string,ffmpeg_log,FFmpeg::kLog);
|
||||||
|
|
||||||
_src_url = src_url;
|
_src_url = src_url;
|
||||||
_dst_url = dst_url;
|
_dst_url = dst_url;
|
||||||
|
_ffmpeg_cmd_key = ffmpeg_cmd_key;
|
||||||
_media_info.parse(dst_url);
|
_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};
|
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));
|
_process.run(cmd,ffmpeg_log.empty() ? "" : File::absolutePath("",ffmpeg_log));
|
||||||
InfoL << cmd;
|
InfoL << cmd;
|
||||||
|
|
||||||
@ -206,7 +217,7 @@ void FFmpegSource::startTimer(int timeout_ms) {
|
|||||||
if(strongSelf->_replay_ticker.elapsedTime() > 20 * 1000){
|
if(strongSelf->_replay_ticker.elapsedTime() > 20 * 1000){
|
||||||
//上次重试时间超过10秒,那么再重试FFmpeg拉流
|
//上次重试时间超过10秒,那么再重试FFmpeg拉流
|
||||||
strongSelf->_replay_ticker.resetTime();
|
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推流中断,那么它应该会自动退出
|
//推流给其他服务器的,我们通过判断FFmpeg进程是否在线,如果FFmpeg推流中断,那么它应该会自动退出
|
||||||
if (!strongSelf->_process.wait(false)) {
|
if (!strongSelf->_process.wait(false)) {
|
||||||
//ffmpeg不在线,重新拉流
|
//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){
|
if(!ex){
|
||||||
//没有错误
|
//没有错误
|
||||||
return;
|
return;
|
||||||
|
@ -55,12 +55,13 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 开始播放url
|
* 开始播放url
|
||||||
|
* @param ffmpeg_cmd_key FFmpeg拉流命令配置项key,用户可以在配置文件中同时设置多个命令参数模板
|
||||||
* @param src_url FFmpeg拉流地址
|
* @param src_url FFmpeg拉流地址
|
||||||
* @param dst_url FFmpeg推流地址
|
* @param dst_url FFmpeg推流地址
|
||||||
* @param timeout_ms 等待结果超时时间,单位毫秒
|
* @param timeout_ms 等待结果超时时间,单位毫秒
|
||||||
* @param cb 成功与否回调
|
* @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;
|
MediaInfo _media_info;
|
||||||
string _src_url;
|
string _src_url;
|
||||||
string _dst_url;
|
string _dst_url;
|
||||||
|
string _ffmpeg_cmd_key;
|
||||||
function<void()> _onClose;
|
function<void()> _onClose;
|
||||||
Ticker _replay_ticker;
|
Ticker _replay_ticker;
|
||||||
};
|
};
|
||||||
|
@ -662,7 +662,8 @@ void installWebApi() {
|
|||||||
val["data"]["flag"] = s_proxyMap.erase(allArgs["key"]) == 1;
|
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,
|
const string &dst_url,
|
||||||
int timeout_ms,
|
int timeout_ms,
|
||||||
bool enable_hls,
|
bool enable_hls,
|
||||||
@ -684,7 +685,7 @@ void installWebApi() {
|
|||||||
s_ffmpegMap.erase(key);
|
s_ffmpegMap.erase(key);
|
||||||
});
|
});
|
||||||
ffmpeg->setupRecordFlag(enable_hls, enable_mp4);
|
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) {
|
if (ex) {
|
||||||
lock_guard<decltype(s_ffmpegMapMtx)> lck(s_ffmpegMapMtx);
|
lock_guard<decltype(s_ffmpegMapMtx)> lck(s_ffmpegMapMtx);
|
||||||
s_ffmpegMap.erase(key);
|
s_ffmpegMap.erase(key);
|
||||||
@ -704,7 +705,7 @@ void installWebApi() {
|
|||||||
auto enable_hls = allArgs["enable_hls"].as<int>();
|
auto enable_hls = allArgs["enable_hls"].as<int>();
|
||||||
auto enable_mp4 = allArgs["enable_mp4"].as<int>();
|
auto enable_mp4 = allArgs["enable_mp4"].as<int>();
|
||||||
|
|
||||||
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) {
|
[invoker, val, headerOut](const SockException &ex, const string &key) {
|
||||||
if (ex) {
|
if (ex) {
|
||||||
const_cast<Value &>(val)["code"] = API::OtherFailed;
|
const_cast<Value &>(val)["code"] = API::OtherFailed;
|
||||||
@ -1080,7 +1081,7 @@ void installWebApi() {
|
|||||||
<< allArgs["stream"] << "?vhost="
|
<< allArgs["stream"] << "?vhost="
|
||||||
<< allArgs["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,
|
dst_url,
|
||||||
(1000 * timeout_sec) - 500,
|
(1000 * timeout_sec) - 500,
|
||||||
false,
|
false,
|
||||||
|
Loading…
Reference in New Issue
Block a user