mirror of
https://github.com/ossrs/srs.git
synced 2025-02-15 04:42:04 +00:00
support pure audio hls. change to 0.9.24
This commit is contained in:
parent
b708f588fc
commit
e0fb1029c9
3 changed files with 81 additions and 39 deletions
|
@ -44,7 +44,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#include <srs_app_pithy_print.hpp>
|
||||
|
||||
// max PES packets size to flush the video.
|
||||
#define SRS_HLS_AUDIO_CACHE_SIZE 512 * 1024
|
||||
#define SRS_HLS_AUDIO_CACHE_SIZE 1024 * 1024
|
||||
|
||||
// @see: NGX_RTMP_HLS_DELAY,
|
||||
// 63000: 700ms, ts_tbn=90000
|
||||
|
@ -481,12 +481,20 @@ SrsHlsSegment::~SrsHlsSegment()
|
|||
srs_freep(muxer);
|
||||
}
|
||||
|
||||
double SrsHlsSegment::update_duration(int64_t current_frame_dts)
|
||||
void SrsHlsSegment::update_duration(int64_t current_frame_dts)
|
||||
{
|
||||
// we use video/audio to update segment duration,
|
||||
// so when reap segment, some previous audio frame will
|
||||
// update the segment duration, which is nagetive,
|
||||
// just ignore it.
|
||||
if (current_frame_dts < segment_start_dts) {
|
||||
return;
|
||||
}
|
||||
|
||||
duration = (current_frame_dts - segment_start_dts) / 90000.0;
|
||||
srs_assert(duration >= 0);
|
||||
|
||||
return duration;
|
||||
return;
|
||||
}
|
||||
|
||||
SrsHlsAacJitter::SrsHlsAacJitter()
|
||||
|
@ -503,7 +511,6 @@ SrsHlsMuxer::SrsHlsMuxer()
|
|||
hls_fragment = hls_window = 0;
|
||||
file_index = 0;
|
||||
current = NULL;
|
||||
video_count = 0;
|
||||
}
|
||||
|
||||
SrsHlsMuxer::~SrsHlsMuxer()
|
||||
|
@ -542,9 +549,6 @@ int SrsHlsMuxer::segment_open(int64_t segment_start_dts)
|
|||
return ret;
|
||||
}
|
||||
|
||||
// reset video count for new publish session.
|
||||
video_count = 0;
|
||||
|
||||
// TODO: create all parents dirs.
|
||||
// create dir for app.
|
||||
if ((ret = create_dir()) != ERROR_SUCCESS) {
|
||||
|
@ -605,6 +609,9 @@ int SrsHlsMuxer::flush_audio(SrsMpegtsFrame* af, SrsCodecBuffer* ab)
|
|||
return ret;
|
||||
}
|
||||
|
||||
// update the duration of segment.
|
||||
current->update_duration(af->pts);
|
||||
|
||||
if ((ret = current->muxer->write_audio(af, ab)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -635,6 +642,9 @@ int SrsHlsMuxer::flush_video(
|
|||
return ret;
|
||||
}
|
||||
|
||||
// write success, clear and free the buffer
|
||||
vb->free();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -860,6 +870,8 @@ SrsHlsCache::SrsHlsCache()
|
|||
|
||||
af = new SrsMpegtsFrame();
|
||||
vf = new SrsMpegtsFrame();
|
||||
|
||||
video_count = 0;
|
||||
}
|
||||
|
||||
SrsHlsCache::~SrsHlsCache()
|
||||
|
@ -890,6 +902,9 @@ int SrsHlsCache::on_publish(SrsHlsMuxer* muxer, SrsRequest* req, int64_t segment
|
|||
// get the hls path config
|
||||
std::string hls_path = _srs_config->get_hls_path(vhost);
|
||||
|
||||
// reset video count for new publish session.
|
||||
video_count = 0;
|
||||
|
||||
// open muxer
|
||||
if ((ret = muxer->update_config(app, stream, hls_path, hls_fragment, hls_window)) != ERROR_SUCCESS) {
|
||||
srs_error("m3u8 muxer update config failed. ret=%d", ret);
|
||||
|
@ -956,13 +971,25 @@ int SrsHlsCache::write_audio(SrsCodec* codec, SrsHlsMuxer* muxer, int64_t pts, S
|
|||
}
|
||||
}
|
||||
|
||||
// for pure audio
|
||||
// start new segment when duration overflow.
|
||||
if (video_count == 0 && muxer->is_segment_overflow()) {
|
||||
srs_trace("pure audio segment reap");
|
||||
if ((ret = reap_segment(muxer, af->pts)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsHlsCache::write_video(SrsCodec* codec, SrsHlsMuxer* muxer, int64_t dts, SrsCodecSample* sample)
|
||||
int SrsHlsCache::write_video(
|
||||
SrsCodec* codec, SrsHlsMuxer* muxer, int64_t dts, SrsCodecSample* sample)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
video_count++;
|
||||
|
||||
// write video to cache.
|
||||
if ((ret = cache_video(codec, sample)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
|
@ -974,26 +1001,11 @@ int SrsHlsCache::write_video(SrsCodec* codec, SrsHlsMuxer* muxer, int64_t dts, S
|
|||
vf->sid = TS_VIDEO_AVC;
|
||||
vf->key = sample->frame_type == SrsCodecVideoAVCFrameKeyFrame;
|
||||
|
||||
// reopen the muxer for a gop
|
||||
// close current segment, open a new segment,
|
||||
// then write the key frame to the new segment.
|
||||
// new segment when:
|
||||
// 1. base on gop.
|
||||
// 2. some gops duration overflow.
|
||||
if (vf->key && muxer->is_segment_overflow()) {
|
||||
if ((ret = muxer->segment_close()) != ERROR_SUCCESS) {
|
||||
srs_error("m3u8 muxer close segment failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = muxer->segment_open(vf->dts)) != ERROR_SUCCESS) {
|
||||
srs_error("m3u8 muxer open segment failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// TODO: flush audio before or after segment?
|
||||
// segment open, flush the audio.
|
||||
// @see: ngx_rtmp_hls_open_fragment
|
||||
/* start fragment with audio to make iPhone happy */
|
||||
if ((ret = muxer->flush_audio(af, ab)) != ERROR_SUCCESS) {
|
||||
srs_error("m3u8 muxer flush audio failed. ret=%d", ret);
|
||||
if ((ret = reap_segment(muxer, vf->dts)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@ -1004,8 +1016,31 @@ int SrsHlsCache::write_video(SrsCodec* codec, SrsHlsMuxer* muxer, int64_t dts, S
|
|||
return ret;
|
||||
}
|
||||
|
||||
// write success, clear and free the buffer
|
||||
vb->free();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsHlsCache::reap_segment(SrsHlsMuxer* muxer, int64_t segment_start_dts)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
if ((ret = muxer->segment_close()) != ERROR_SUCCESS) {
|
||||
srs_error("m3u8 muxer close segment failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = muxer->segment_open(segment_start_dts)) != ERROR_SUCCESS) {
|
||||
srs_error("m3u8 muxer open segment failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// TODO: flush audio before or after segment?
|
||||
// segment open, flush the audio.
|
||||
// @see: ngx_rtmp_hls_open_fragment
|
||||
/* start fragment with audio to make iPhone happy */
|
||||
if ((ret = muxer->flush_audio(af, ab)) != ERROR_SUCCESS) {
|
||||
srs_error("m3u8 muxer flush audio failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -124,7 +124,7 @@ public:
|
|||
* update the segment duration.
|
||||
* @current_frame_dts the dts of frame, in tbn of ts.
|
||||
*/
|
||||
virtual double update_duration(int64_t current_frame_dts);
|
||||
virtual void update_duration(int64_t current_frame_dts);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -147,14 +147,6 @@ private:
|
|||
private:
|
||||
int file_index;
|
||||
std::string m3u8;
|
||||
private:
|
||||
/**
|
||||
* for pure audio HLS application,
|
||||
* the video count used to count the video,
|
||||
* if zero and audio buffer overflow, reap the ts,
|
||||
* just like we got a keyframe.
|
||||
*/
|
||||
u_int32_t video_count;
|
||||
private:
|
||||
/**
|
||||
* m3u8 segments.
|
||||
|
@ -219,6 +211,14 @@ private:
|
|||
int64_t audio_buffer_start_pts;
|
||||
// time jitter for aac
|
||||
SrsHlsAacJitter* aac_jitter;
|
||||
private:
|
||||
/**
|
||||
* for pure audio HLS application,
|
||||
* the video count used to count the video,
|
||||
* if zero and audio buffer overflow, reap the ts,
|
||||
* just like we got a keyframe.
|
||||
*/
|
||||
u_int32_t video_count;
|
||||
public:
|
||||
SrsHlsCache();
|
||||
virtual ~SrsHlsCache();
|
||||
|
@ -237,6 +237,13 @@ public:
|
|||
*/
|
||||
virtual int write_video(SrsCodec* codec, SrsHlsMuxer* muxer, int64_t dts, SrsCodecSample* sample);
|
||||
private:
|
||||
/**
|
||||
* reopen the muxer for a new hls segment,
|
||||
* close current segment, open a new segment,
|
||||
* then write the key frame to the new segment.
|
||||
* so, user must reap_segment then flush_video to hls muxer.
|
||||
*/
|
||||
virtual int reap_segment(SrsHlsMuxer* muxer, int64_t segment_start_dts);
|
||||
virtual int cache_audio(SrsCodec* codec, SrsCodecSample* sample);
|
||||
virtual int cache_video(SrsCodec* codec, SrsCodecSample* sample);
|
||||
};
|
||||
|
|
|
@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
// current release version
|
||||
#define VERSION_MAJOR "0"
|
||||
#define VERSION_MINOR "9"
|
||||
#define VERSION_REVISION "23"
|
||||
#define VERSION_REVISION "24"
|
||||
#define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION
|
||||
// server info.
|
||||
#define RTMP_SIG_SRS_KEY "srs"
|
||||
|
|
Loading…
Reference in a new issue