diff --git a/3rdpart/ZLToolKit b/3rdpart/ZLToolKit index 91246bb0..b7485c4b 160000 --- a/3rdpart/ZLToolKit +++ b/3rdpart/ZLToolKit @@ -1 +1 @@ -Subproject commit 91246bb01475c7336040a4b7ec35d0584887f365 +Subproject commit b7485c4b48b277bfaba2ad930cf1f30e2806299c diff --git a/conf/config.ini b/conf/config.ini index 902d2215..7ce085e8 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -39,6 +39,7 @@ filePath=/Users/xzl/git/ZLMediaKit/release/mac/Release/httpRoot #hls最大切片时间 segDur=3 #m3u8索引中,hls保留切片个数(实际保留切片个数大2~3个) +#如果设置为0,则不删除切片,而是保存为点播 segNum=3 [hook] diff --git a/server/Process.cpp b/server/Process.cpp index 984657a7..3b67145a 100644 --- a/server/Process.cpp +++ b/server/Process.cpp @@ -25,6 +25,7 @@ */ #include +#include #include #include #include diff --git a/server/Process.h b/server/Process.h index 1276cf28..b0b994d9 100644 --- a/server/Process.h +++ b/server/Process.h @@ -27,7 +27,7 @@ #define IPTV_PROCESS_H #include -#include +#include #include using namespace std; diff --git a/src/Common/config.cpp b/src/Common/config.cpp index fa4a1c44..49f43e7b 100644 --- a/src/Common/config.cpp +++ b/src/Common/config.cpp @@ -77,12 +77,15 @@ const string kStreamNoneReaderDelayMS = GENERAL_FIELD"streamNoneReaderDelayMS"; const string kMaxStreamWaitTimeMS = GENERAL_FIELD"maxStreamWaitMS"; const string kEnableVhost = GENERAL_FIELD"enableVhost"; const string kUltraLowDelay = GENERAL_FIELD"ultraLowDelay"; +const string kAddMuteAudio = GENERAL_FIELD"addMuteAudio"; + onceToken token([](){ mINI::Instance()[kFlowThreshold] = 1024; mINI::Instance()[kStreamNoneReaderDelayMS] = 5 * 1000; mINI::Instance()[kMaxStreamWaitTimeMS] = 5 * 1000; mINI::Instance()[kEnableVhost] = 1; mINI::Instance()[kUltraLowDelay] = 1; + mINI::Instance()[kAddMuteAudio] = 1; },nullptr); }//namespace General diff --git a/src/Common/config.h b/src/Common/config.h index 89ed9cb1..31a27d2d 100644 --- a/src/Common/config.h +++ b/src/Common/config.h @@ -177,6 +177,8 @@ extern const string kMaxStreamWaitTimeMS; extern const string kEnableVhost; //超低延时模式,默认打开,打开后会降低延时但是转发性能会稍差 extern const string kUltraLowDelay; +//拉流代理时是否添加静音音频 +extern const string kAddMuteAudio; }//namespace General @@ -276,7 +278,7 @@ extern const string kFileRepeat; namespace Hls { //HLS切片时长,单位秒 extern const string kSegmentDuration; -//HLS切片个数 +//HLS切片个数,如果设置为0,则不删除切片,而是保存为点播 extern const string kSegmentNum; //HLS文件写缓存大小 extern const string kFileBufSize; diff --git a/src/Extension/Factory.cpp b/src/Extension/Factory.cpp index 0a504f64..aee7de21 100644 --- a/src/Extension/Factory.cpp +++ b/src/Extension/Factory.cpp @@ -60,16 +60,16 @@ Track::Ptr Factory::getTrackBySdp(const SdpTrack::Ptr &track) { } if (strcasecmp(track->_codec.data(), "h264") == 0) { - string sps_pps = FindField(track->_fmtp.data(), "sprop-parameter-sets=", nullptr); + auto map = Parser::parseArgs(track->_fmtp," ","="); + for(auto &pr : map){ + trim(pr.second," ;"); + } + auto sps_pps = map["sprop-parameter-sets"]; if(sps_pps.empty()){ return std::make_shared(); } string base64_SPS = FindField(sps_pps.data(), NULL, ","); string base64_PPS = FindField(sps_pps.data(), ",", NULL); - if(base64_PPS.back() == ';'){ - base64_PPS.pop_back(); - } - auto sps = decodeBase64(base64_SPS); auto pps = decodeBase64(base64_PPS); return std::make_shared(sps,pps,0,0); diff --git a/src/MediaFile/HlsMaker.cpp b/src/MediaFile/HlsMaker.cpp index 5e88b31a..36f88c39 100644 --- a/src/MediaFile/HlsMaker.cpp +++ b/src/MediaFile/HlsMaker.cpp @@ -28,7 +28,8 @@ namespace mediakit { HlsMaker::HlsMaker(float seg_duration, uint32_t seg_number) { - seg_number = MAX(1,seg_number); + //最小允许设置为0,0个切片代表点播 + seg_number = MAX(0,seg_number); seg_duration = MAX(1,seg_duration); _seg_number = seg_number; _seg_duration = seg_duration; @@ -37,12 +38,9 @@ HlsMaker::HlsMaker(float seg_duration, uint32_t seg_number) { HlsMaker::~HlsMaker() { } -#define PRINT(...) file_size += snprintf(file_content + file_size,sizeof(file_content) - file_size, ##__VA_ARGS__) void HlsMaker::makeIndexFile(bool eof) { - char file_content[4 * 1024]; - int file_size = 0; - + char file_content[1024]; int maxSegmentDuration = 0; for (auto &tp : _seg_dur_list) { int dur = std::get<0>(tp); @@ -50,7 +48,10 @@ void HlsMaker::makeIndexFile(bool eof) { maxSegmentDuration = dur; } } - PRINT("#EXTM3U\n" + + string m3u8; + snprintf(file_content,sizeof(file_content), + "#EXTM3U\n" "#EXT-X-VERSION:3\n" "#EXT-X-ALLOW-CACHE:NO\n" "#EXT-X-TARGETDURATION:%u\n" @@ -58,14 +59,18 @@ void HlsMaker::makeIndexFile(bool eof) { (maxSegmentDuration + 999) / 1000, _file_index); + m3u8.assign(file_content); + for (auto &tp : _seg_dur_list) { - PRINT("#EXTINF:%.3f,\n%s\n", std::get<0>(tp) / 1000.0, std::get<1>(tp).data()); + snprintf(file_content,sizeof(file_content), "#EXTINF:%.3f,\n%s\n", std::get<0>(tp) / 1000.0, std::get<1>(tp).data()); + m3u8.append(file_content); } if (eof) { - PRINT("#EXT-X-ENDLIST\n"); + snprintf(file_content,sizeof(file_content),"#EXT-X-ENDLIST\n"); + m3u8.append(file_content); } - onWriteHls(file_content, file_size); + onWriteHls(m3u8.data(), m3u8.size()); } @@ -75,6 +80,10 @@ void HlsMaker::inputData(void *data, uint32_t len, uint32_t timestamp) { } void HlsMaker::delOldFile() { + if(_seg_number == 0){ + //如果设置为保留0个切片,则认为是保存为点播 + return; + } //在hls m3u8索引文件中,我们保存的切片个数跟_seg_number相关设置一致 if (_file_index >= _seg_number + 2) { _seg_dur_list.pop_front(); diff --git a/src/MediaFile/HlsMaker.h b/src/MediaFile/HlsMaker.h index 37f6d671..0a1e9617 100644 --- a/src/MediaFile/HlsMaker.h +++ b/src/MediaFile/HlsMaker.h @@ -81,13 +81,18 @@ protected: * @param len */ virtual void onWriteHls(const char *data, int len) = 0; -private: + + /** + * 生成m3u8文件 + * @param eof true代表点播 + */ + void makeIndexFile(bool eof = false); void delOldFile(); void addNewFile(uint32_t timestamp); - void makeIndexFile(bool eof = false); +protected: + uint32_t _seg_number = 0; private: float _seg_duration = 0; - uint32_t _seg_number = 0; uint64_t _file_index = 0; Ticker _ticker; string _last_file_name; diff --git a/src/MediaFile/HlsMakerImp.cpp b/src/MediaFile/HlsMakerImp.cpp index ece25b73..77763e30 100644 --- a/src/MediaFile/HlsMakerImp.cpp +++ b/src/MediaFile/HlsMakerImp.cpp @@ -46,8 +46,12 @@ HlsMakerImp::HlsMakerImp(const string &m3u8_file, } HlsMakerImp::~HlsMakerImp() { - _file.reset(); - File::delete_file(_path_prefix.data()); + //录制完了 + makeIndexFile(true); + if(_seg_number){ + //hls直播才删除文件 + File::delete_file(_path_prefix.data()); + } } string HlsMakerImp::onOpenFile(int index) { diff --git a/src/MediaFile/MediaReader.cpp b/src/MediaFile/MediaReader.cpp index a39d1354..22683b4e 100644 --- a/src/MediaFile/MediaReader.cpp +++ b/src/MediaFile/MediaReader.cpp @@ -30,6 +30,7 @@ #include "Http/HttpSession.h" #include "Extension/AAC.h" #include "Extension/H264.h" +#include "Thread/WorkThreadPool.h" using namespace toolkit; @@ -37,7 +38,7 @@ namespace mediakit { #ifdef ENABLE_MP4V2 MediaReader::MediaReader(const string &strVhost,const string &strApp, const string &strId,const string &filePath ) { - _poller = EventPollerPool::Instance().getPoller(); + _poller = WorkThreadPool::Instance().getPoller(); auto strFileName = filePath; if(strFileName.empty()){ GET_CONFIG(string,recordPath,Record::kFilePath); diff --git a/src/Player/PlayerProxy.cpp b/src/Player/PlayerProxy.cpp index 5b821d85..fce309b9 100644 --- a/src/Player/PlayerProxy.cpp +++ b/src/Player/PlayerProxy.cpp @@ -244,13 +244,16 @@ void PlayerProxy::onPlaySuccess() { videoTrack->addDelegate(_mediaMuxer); } + //是否添加静音音频 + GET_CONFIG(bool,addMuteAudio,General::kAddMuteAudio); + auto audioTrack = getTrack(TrackAudio, false); if(audioTrack){ //添加音频 _mediaMuxer->addTrack(audioTrack); //音频数据写入_mediaMuxer audioTrack->addDelegate(_mediaMuxer); - }else if(videoTrack){ + }else if(addMuteAudio && videoTrack){ //没有音频信息,产生一个静音音频 MuteAudioMaker::Ptr audioMaker = std::make_shared(); //videoTrack把数据写入MuteAudioMaker