mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
for #301, http ts stream support h.264+mp3. 2.0.106
This commit is contained in:
parent
aaade0f04f
commit
2c42350489
10 changed files with 305 additions and 75 deletions
|
@ -199,6 +199,13 @@ bool SrsHlsMuxer::is_segment_absolutely_overflow()
|
|||
return current->duration >= 2 * hls_fragment;
|
||||
}
|
||||
|
||||
int SrsHlsMuxer::update_acodec(SrsCodecAudio acodec)
|
||||
{
|
||||
srs_assert(current);
|
||||
srs_assert(current->muxer);
|
||||
return current->muxer->update_acodec(acodec);
|
||||
}
|
||||
|
||||
int SrsHlsMuxer::flush_audio(SrsMpegtsFrame* af, SrsSimpleBuffer* ab)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
@ -572,8 +579,6 @@ int SrsHlsCache::on_sequence_header(SrsHlsMuxer* muxer)
|
|||
int SrsHlsCache::write_audio(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t pts, SrsCodecSample* sample)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
audio_buffer_start_pts = pts;
|
||||
|
||||
// write audio to cache.
|
||||
if ((ret = cache->cache_audio(codec, pts, sample)) != ERROR_SUCCESS) {
|
||||
|
@ -591,7 +596,7 @@ int SrsHlsCache::write_audio(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t
|
|||
// in ms, audio delay to flush the audios.
|
||||
int64_t audio_delay = SRS_CONF_DEFAULT_AAC_DELAY;
|
||||
// flush if audio delay exceed
|
||||
if (pts - audio_buffer_start_pts > audio_delay * 90) {
|
||||
if (pts - cache->audio_buffer_start_pts > audio_delay * 90) {
|
||||
if ((ret = muxer->flush_audio(cache->af, cache->ab)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -773,11 +778,25 @@ int SrsHls::on_audio(SrsSharedPtrMessage* __audio)
|
|||
|
||||
sample->clear();
|
||||
if ((ret = codec->audio_aac_demux(audio->payload, audio->size, sample)) != ERROR_SUCCESS) {
|
||||
srs_error("hls codec demux audio failed. ret=%d", ret);
|
||||
if (ret != ERROR_HLS_TRY_MP3) {
|
||||
srs_error("hls aac demux audio failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
if ((ret = codec->audio_mp3_demux(audio->payload, audio->size, sample)) != ERROR_SUCCESS) {
|
||||
srs_error("hls mp3 demux audio failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
SrsCodecAudio acodec = (SrsCodecAudio)codec->audio_codec_id;
|
||||
|
||||
// ts support audio codec: aac/mp3
|
||||
if (acodec != SrsCodecAudioAAC && acodec != SrsCodecAudioMP3) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (codec->audio_codec_id != SrsCodecAudioAAC) {
|
||||
|
||||
// when codec changed, write new header.
|
||||
if ((ret = muxer->update_acodec(acodec)) != ERROR_SUCCESS) {
|
||||
srs_error("http: ts audio write header failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <srs_kernel_codec.hpp>
|
||||
|
||||
class SrsSharedPtrMessage;
|
||||
class SrsCodecSample;
|
||||
class SrsMpegtsFrame;
|
||||
|
@ -141,6 +143,8 @@ public:
|
|||
* @see https://github.com/winlinvip/simple-rtmp-server/issues/151#issuecomment-71155184
|
||||
*/
|
||||
virtual bool is_segment_absolutely_overflow();
|
||||
public:
|
||||
virtual int update_acodec(SrsCodecAudio acodec);
|
||||
virtual int flush_audio(SrsMpegtsFrame* af, SrsSimpleBuffer* ab);
|
||||
virtual int flush_video(SrsMpegtsFrame* af, SrsSimpleBuffer* ab, SrsMpegtsFrame* vf, SrsSimpleBuffer* vb);
|
||||
/**
|
||||
|
@ -174,8 +178,6 @@ private:
|
|||
class SrsHlsCache
|
||||
{
|
||||
private:
|
||||
// the audio cache buffer start pts, to flush audio if full.
|
||||
int64_t audio_buffer_start_pts;
|
||||
SrsTsCache* cache;
|
||||
public:
|
||||
SrsHlsCache();
|
||||
|
|
|
@ -1349,12 +1349,17 @@ int SrsSource::on_audio(SrsCommonMessage* __audio)
|
|||
}
|
||||
}
|
||||
|
||||
// cache the sequence header if h264
|
||||
// donot cache the sequence header to gop_cache, return here.
|
||||
if (SrsFlvCodec::audio_is_sequence_header(msg.payload, msg.size)) {
|
||||
// cache the sequence header of aac, or first packet of mp3.
|
||||
// for example, the mp3 is used for hls to write the "right" audio codec.
|
||||
bool is_aac_sequence_header = SrsFlvCodec::audio_is_sequence_header(msg.payload, msg.size);
|
||||
if (is_aac_sequence_header || !cache_sh_audio) {
|
||||
srs_freep(cache_sh_audio);
|
||||
cache_sh_audio = msg.copy();
|
||||
|
||||
}
|
||||
|
||||
// cache the sequence header if aac
|
||||
// donot cache the sequence header to gop_cache, return here.
|
||||
if (is_aac_sequence_header) {
|
||||
// parse detail audio codec
|
||||
SrsAvcAacCodec codec;
|
||||
SrsCodecSample sample;
|
||||
|
@ -1768,18 +1773,20 @@ int SrsSource::create_consumer(SrsConsumer*& consumer, bool ds, bool dm, bool dg
|
|||
srs_info("dispatch metadata success");
|
||||
|
||||
// copy sequence header
|
||||
// copy audio sequence first, for hls to fast parse the "right" audio codec.
|
||||
// @see https://github.com/winlinvip/simple-rtmp-server/issues/301
|
||||
if (ds && cache_sh_audio && (ret = consumer->enqueue(cache_sh_audio, atc, tba, tbv, ag)) != ERROR_SUCCESS) {
|
||||
srs_error("dispatch audio sequence header failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
srs_info("dispatch audio sequence header success");
|
||||
|
||||
if (ds && cache_sh_video && (ret = consumer->enqueue(cache_sh_video, atc, tba, tbv, ag)) != ERROR_SUCCESS) {
|
||||
srs_error("dispatch video sequence header failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
srs_info("dispatch video sequence header success");
|
||||
|
||||
if (cache_sh_audio && (ret = consumer->enqueue(cache_sh_audio, atc, tba, tbv, ag)) != ERROR_SUCCESS) {
|
||||
srs_error("dispatch audio sequence header failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
srs_info("dispatch audio sequence header success");
|
||||
|
||||
// copy gop cache to client.
|
||||
if (dg && (ret = gop_cache->dump(consumer, atc, tba, tbv, ag)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue