1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-13 03:41:55 +00:00

Fix HLS segment close bug

This commit is contained in:
winlin 2019-04-16 09:32:26 +08:00
parent 138d1e3cad
commit 6380e8f1c0
4 changed files with 18 additions and 10 deletions

View file

@ -242,15 +242,15 @@ void SrsFragmentWindow::clear_expired(bool delete_files)
expired_fragments.clear();
}
int64_t SrsFragmentWindow::max_duration()
srs_utime_t SrsFragmentWindow::max_duration()
{
int64_t v = 0;
srs_utime_t v = 0;
std::vector<SrsFragment*>::iterator it;
for (it = fragments.begin(); it != fragments.end(); ++it) {
SrsFragment* fragment = *it;
v = srs_max(v, srsu2ms(fragment->duration()));
v = srs_max(v, fragment->duration());
}
return v;

View file

@ -96,8 +96,8 @@ public:
virtual void shrink(srs_utime_t window);
// Clear the expired fragments.
virtual void clear_expired(bool delete_files);
// Get the max duration in ms of all fragments.
virtual int64_t max_duration();
// Get the max duration in srs_utime_t of all fragments.
virtual srs_utime_t max_duration();
public:
virtual bool empty();
virtual SrsFragment* first();

View file

@ -312,7 +312,7 @@ srs_error_t SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix,
m3u8 = path + "/" + m3u8_url;
// when update config, reset the history target duration.
max_td = (int)(fragment * _srs_config->get_hls_td_ratio(r->vhost));
max_td = fragment * _srs_config->get_hls_td_ratio(r->vhost);
// create m3u8 dir once.
m3u8_dir = srs_path_dirname(m3u8);
@ -585,12 +585,19 @@ srs_error_t SrsHlsMuxer::segment_close()
// when close current segment, the current segment must not be NULL.
srs_assert(current);
// We should always close the underlayer writer.
if (current && current->writer) {
current->writer->close();
}
// valid, add to segments if segment duration is ok
// when too small, it maybe not enough data to play.
// when too large, it maybe timestamp corrupt.
// make the segment more acceptable, when in [min, max_td * 2], it's ok.
if (current->duration() >= SRS_AUTO_HLS_SEGMENT_MIN_DURATION && (int)srsu2msi(current->duration()) <= max_td * 2 * 1000) {
bool matchMinDuration = current->duration() >= SRS_AUTO_HLS_SEGMENT_MIN_DURATION;
bool matchMaxDuration = current->duration() <= max_td * 2 * 1000;
if (matchMinDuration && matchMaxDuration) {
// use async to call the http hooks, for it will cause thread switch.
if ((err = async->execute(new SrsDvrAsyncCallOnHls(_srs_context->get_id(), req, current->fullpath(),
current->uri, m3u8, m3u8_url, current->sequence_no, current->duration()))) != srs_success) {
@ -607,6 +614,7 @@ srs_error_t SrsHlsMuxer::segment_close()
// rename from tmp to real path
if ((err = current->rename()) != srs_success) {
srs_freep(current);
return srs_error_wrap(err, "rename");
}
@ -744,8 +752,8 @@ srs_error_t SrsHlsMuxer::_refresh_m3u8(string m3u8_file)
* typical target duration is 10 seconds.
*/
// @see https://github.com/ossrs/srs/issues/304#issuecomment-74000081
int target_duration = (int)ceil(segments->max_duration() / 1000.0);
target_duration = srs_max(target_duration, max_td);
srs_utime_t max_duration = segments->max_duration();
int target_duration = (int)ceil(srsu2msi(srs_max(max_duration, max_td)) / 1000.0);
ss << "#EXT-X-TARGETDURATION:" << target_duration << SRS_CONSTS_LF;

View file

@ -168,7 +168,7 @@ private:
SrsFileWriter *writer;
private:
int _sequence_no;
int max_td;
srs_utime_t max_td;
std::string m3u8;
std::string m3u8_url;
private: