mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-26 04:31:37 +08:00
增加ffmpeg拉流自动重启时间, 避免长时间拉流导致的声音不同步现象 (#1346)
This commit is contained in:
parent
819599ac25
commit
26d458d067
@ -26,6 +26,8 @@ snap=%s -i %s -y -f mjpeg -t 0.001 %s
|
|||||||
#FFmpeg日志的路径,如果置空则不生成FFmpeg日志
|
#FFmpeg日志的路径,如果置空则不生成FFmpeg日志
|
||||||
#可以为相对(相对于本可执行程序目录)或绝对路径
|
#可以为相对(相对于本可执行程序目录)或绝对路径
|
||||||
log=./ffmpeg/ffmpeg.log
|
log=./ffmpeg/ffmpeg.log
|
||||||
|
# 自动重启的时间(秒), 默认为0, 也就是不自动重启. 主要是为了避免长时间ffmpeg拉流导致的不同步现象
|
||||||
|
restart_sec=0
|
||||||
|
|
||||||
[general]
|
[general]
|
||||||
#是否启用虚拟主机
|
#是否启用虚拟主机
|
||||||
|
@ -22,6 +22,7 @@ const string kBin = FFmpeg_FIELD"bin";
|
|||||||
const string kCmd = FFmpeg_FIELD"cmd";
|
const string kCmd = FFmpeg_FIELD"cmd";
|
||||||
const string kLog = FFmpeg_FIELD"log";
|
const string kLog = FFmpeg_FIELD"log";
|
||||||
const string kSnap = FFmpeg_FIELD"snap";
|
const string kSnap = FFmpeg_FIELD"snap";
|
||||||
|
const string kRestartSec = FFmpeg_FIELD"restart_sec";
|
||||||
|
|
||||||
onceToken token([]() {
|
onceToken token([]() {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@ -35,6 +36,7 @@ onceToken token([]() {
|
|||||||
mINI::Instance()[kLog] = "./ffmpeg/ffmpeg.log";
|
mINI::Instance()[kLog] = "./ffmpeg/ffmpeg.log";
|
||||||
mINI::Instance()[kCmd] = "%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s";
|
mINI::Instance()[kCmd] = "%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s";
|
||||||
mINI::Instance()[kSnap] = "%s -i %s -y -f mjpeg -t 0.001 %s";
|
mINI::Instance()[kSnap] = "%s -i %s -y -f mjpeg -t 0.001 %s";
|
||||||
|
mINI::Instance()[kRestartSec] = 0;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,17 +204,27 @@ void FFmpegSource::findAsync(int maxWaitMS, const function<void(const MediaSourc
|
|||||||
*/
|
*/
|
||||||
void FFmpegSource::startTimer(int timeout_ms) {
|
void FFmpegSource::startTimer(int timeout_ms) {
|
||||||
weak_ptr<FFmpegSource> weakSelf = shared_from_this();
|
weak_ptr<FFmpegSource> weakSelf = shared_from_this();
|
||||||
|
GET_CONFIG(uint64_t,ffmpeg_restart_sec,FFmpeg::kRestartSec);
|
||||||
_timer = std::make_shared<Timer>(1.0f, [weakSelf, timeout_ms]() {
|
_timer = std::make_shared<Timer>(1.0f, [weakSelf, timeout_ms]() {
|
||||||
auto strongSelf = weakSelf.lock();
|
auto strongSelf = weakSelf.lock();
|
||||||
if (!strongSelf) {
|
if (!strongSelf) {
|
||||||
//自身已经销毁
|
//自身已经销毁
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
bool needRestart = ffmpeg_restart_sec > 0 && strongSelf->_replay_ticker.elapsedTime() > ffmpeg_restart_sec * 1000;
|
||||||
if (is_local_ip(strongSelf->_media_info._host)) {
|
if (is_local_ip(strongSelf->_media_info._host)) {
|
||||||
//推流给自己的,我们通过检查是否已经注册来判断FFmpeg是否工作正常
|
//推流给自己的,我们通过检查是否已经注册来判断FFmpeg是否工作正常
|
||||||
strongSelf->findAsync(0, [&](const MediaSource::Ptr &src) {
|
strongSelf->findAsync(0, [&](const MediaSource::Ptr &src) {
|
||||||
//同步查找流
|
//同步查找流
|
||||||
if (!src) {
|
if (!src || needRestart) {
|
||||||
|
if(needRestart){
|
||||||
|
strongSelf->_replay_ticker.resetTime();
|
||||||
|
if(strongSelf->_process.wait(false)){
|
||||||
|
//FFmpeg进程还在运行,超时就关闭它
|
||||||
|
strongSelf->_process.kill(2000);
|
||||||
|
}
|
||||||
|
InfoL << "FFmpeg即将重启, 将会继续拉流 " << strongSelf->_src_url;
|
||||||
|
}
|
||||||
//流不在线,重新拉流, 这里原先是10秒超时,实际发现10秒不够,改成20秒了
|
//流不在线,重新拉流, 这里原先是10秒超时,实际发现10秒不够,改成20秒了
|
||||||
if(strongSelf->_replay_ticker.elapsedTime() > 20 * 1000){
|
if(strongSelf->_replay_ticker.elapsedTime() > 20 * 1000){
|
||||||
//上次重试时间超过10秒,那么再重试FFmpeg拉流
|
//上次重试时间超过10秒,那么再重试FFmpeg拉流
|
||||||
@ -223,7 +235,15 @@ void FFmpegSource::startTimer(int timeout_ms) {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
//推流给其他服务器的,我们通过判断FFmpeg进程是否在线,如果FFmpeg推流中断,那么它应该会自动退出
|
//推流给其他服务器的,我们通过判断FFmpeg进程是否在线,如果FFmpeg推流中断,那么它应该会自动退出
|
||||||
if (!strongSelf->_process.wait(false)) {
|
if (!strongSelf->_process.wait(false) || needRestart) {
|
||||||
|
if(needRestart){
|
||||||
|
strongSelf->_replay_ticker.resetTime();
|
||||||
|
if(strongSelf->_process.wait(false)){
|
||||||
|
//FFmpeg进程还在运行,超时就关闭它
|
||||||
|
strongSelf->_process.kill(2000);
|
||||||
|
}
|
||||||
|
InfoL << "FFmpeg即将重启, 将会继续拉流 " << strongSelf->_src_url;
|
||||||
|
}
|
||||||
//ffmpeg不在线,重新拉流
|
//ffmpeg不在线,重新拉流
|
||||||
strongSelf->play(strongSelf->_ffmpeg_cmd_key, 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){
|
||||||
|
Loading…
Reference in New Issue
Block a user