diff --git a/README.md b/README.md index 6187b8f5a..bada9943f 100755 --- a/README.md +++ b/README.md @@ -487,6 +487,8 @@ Supported operating systems and hardware: [#301](https://github.com/winlinvip/simple-rtmp-server/issues/301). 1. Support push MPEG-TS over UDP to SRS, read [#250](https://github.com/winlinvip/simple-rtmp-server/issues/250). +1. Rewrite HLS(h.264+aac/mp3) streaming, read +[#304](https://github.com/winlinvip/simple-rtmp-server/issues/304). 1. [no-plan] Support <500ms latency, FRSC(Fast RTMP-compatible Stream Channel tech). 1. [no-plan] Support RTMP 302 redirect [#92](https://github.com/winlinvip/simple-rtmp-server/issues/92). 1. [no-plan] Support multiple processes, for both origin and edge @@ -525,6 +527,7 @@ Supported operating systems and hardware: ### SRS 2.0 history +* v2.0, 2015-02-15, for [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304), rewrite hls/ts code, support h.264+mp3 for hls. 2.0.117. * v2.0, 2015-02-12, for [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304), use stringstream to generate m3u8, add hls_td_ratio. 2.0.116. * v2.0, 2015-02-11, dev code ZhouGuowen for 2.0.115. * v2.0, 2015-02-10, for [#311](https://github.com/winlinvip/simple-rtmp-server/issues/311), set pcr_base to dts. 2.0.114. diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf index 0b4d964c0..5b31bc022 100644 --- a/trunk/conf/full.conf +++ b/trunk/conf/full.conf @@ -492,6 +492,13 @@ vhost with-hls.srs.com { # @remark the hls_mount must endswith .m3u8. # default: [vhost]/[app]/[stream].m3u8 hls_mount [vhost]/[app]/[stream].m3u8; + # the default audio codec of hls. + # when codec changed, write the PAT/PMT table, but maybe ok util next ts. + # so user can set the default codec for mp3. + # the available audio codec: aac, mp3 + # default: aac + # TODO: FIXME: update wiki for it. + hls_acodec aac; } } # the vhost with hls disabled. diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index 56d44f7ef..dcedbee28 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -1480,7 +1480,7 @@ int SrsConfig::check_config() for (int j = 0; j < (int)conf->directives.size(); j++) { string m = conf->at(j)->name.c_str(); if (m != "enabled" && m != "hls_path" && m != "hls_fragment" && m != "hls_window" && m != "hls_on_error" - && m != "hls_storage" && m != "hls_mount" && m != "hls_td_ratio" + && m != "hls_storage" && m != "hls_mount" && m != "hls_td_ratio" && m != "hls_acodec" ) { ret = ERROR_SYSTEM_CONFIG_INVALID; srs_error("unsupported vhost hls directive %s, ret=%d", m.c_str(), ret); @@ -3332,6 +3332,23 @@ string SrsConfig::get_hls_mount(string vhost) return conf->arg0(); } +string SrsConfig::get_hls_acodec(string vhost) +{ + SrsConfDirective* hls = get_hls(vhost); + + if (!hls) { + return SRS_CONF_DEFAULT_HLS_ACODEC; + } + + SrsConfDirective* conf = hls->get("hls_acodec"); + + if (!conf) { + return SRS_CONF_DEFAULT_HLS_ACODEC; + } + + return conf->arg0(); +} + SrsConfDirective* SrsConfig::get_dvr(string vhost) { SrsConfDirective* conf = get_vhost(vhost); diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index 3534c3126..2787cb9c9 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -55,6 +55,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define SRS_CONF_DEFAULT_HLS_ON_ERROR SRS_CONF_DEFAULT_HLS_ON_ERROR_IGNORE #define SRS_CONF_DEFAULT_HLS_STORAGE "disk" #define SRS_CONF_DEFAULT_HLS_MOUNT "[vhost]/[app]/[stream].m3u8" +#define SRS_CONF_DEFAULT_HLS_ACODEC "aac" #define SRS_CONF_DEFAULT_DVR_PATH "./objs/nginx/html" #define SRS_CONF_DEFAULT_DVR_PLAN_SESSION "session" #define SRS_CONF_DEFAULT_DVR_PLAN_SEGMENT "segment" @@ -922,6 +923,10 @@ public: * get the HLS mount url for HTTP server. */ virtual std::string get_hls_mount(std::string vhost); + /** + * get the HLS default audio codec. + */ + virtual std::string get_hls_acodec(std::string vhost); // dvr section private: /** diff --git a/trunk/src/app/srs_app_hls.cpp b/trunk/src/app/srs_app_hls.cpp index 97be63679..16ca9da31 100644 --- a/trunk/src/app/srs_app_hls.cpp +++ b/trunk/src/app/srs_app_hls.cpp @@ -131,14 +131,14 @@ string SrsHlsCacheWriter::cache() return data; } -SrsHlsSegment::SrsHlsSegment(bool write_cache, bool write_file) +SrsHlsSegment::SrsHlsSegment(bool write_cache, bool write_file, SrsCodecAudio ac) { duration = 0; sequence_no = 0; segment_start_dts = 0; is_sequence_header = false; writer = new SrsHlsCacheWriter(write_cache, write_file); - muxer = new SrsTSMuxer(writer); + muxer = new SrsTSMuxer(writer, ac); } SrsHlsSegment::~SrsHlsSegment() @@ -243,9 +243,22 @@ int SrsHlsMuxer::segment_open(int64_t segment_start_dts) // when segment open, the current segment must be NULL. srs_assert(!current); + + // load the default acodec from config. + SrsCodecAudio default_acodec = SrsCodecAudioAAC; + std::string default_acodec_str = _srs_config->get_hls_acodec(req->vhost); + if (default_acodec_str == "mp3") { + default_acodec = SrsCodecAudioMP3; + srs_info("hls: use default mp3 acodec"); + } else if (default_acodec_str == "aac") { + default_acodec = SrsCodecAudioAAC; + srs_info("hls: use default aac acodec"); + } else { + srs_warn("hls: use aac for other codec=%s", default_acodec_str.c_str()); + } // new segment. - current = new SrsHlsSegment(should_write_cache, should_write_file); + current = new SrsHlsSegment(should_write_cache, should_write_file, default_acodec); current->sequence_no = _sequence_no++; current->segment_start_dts = segment_start_dts; diff --git a/trunk/src/app/srs_app_hls.hpp b/trunk/src/app/srs_app_hls.hpp index ab6e35e23..3cb0407b9 100644 --- a/trunk/src/app/srs_app_hls.hpp +++ b/trunk/src/app/srs_app_hls.hpp @@ -144,7 +144,7 @@ public: // whether current segement is sequence header. bool is_sequence_header; public: - SrsHlsSegment(bool write_cache, bool write_file); + SrsHlsSegment(bool write_cache, bool write_file, SrsCodecAudio ac); virtual ~SrsHlsSegment(); public: /** diff --git a/trunk/src/kernel/srs_kernel_ts.cpp b/trunk/src/kernel/srs_kernel_ts.cpp index 22ea53bbc..ed894e96b 100644 --- a/trunk/src/kernel/srs_kernel_ts.cpp +++ b/trunk/src/kernel/srs_kernel_ts.cpp @@ -2916,13 +2916,12 @@ int SrsTsPayloadPMT::psi_encode(SrsStream* stream) return ret; } -SrsTSMuxer::SrsTSMuxer(SrsFileWriter* w) +SrsTSMuxer::SrsTSMuxer(SrsFileWriter* w, SrsCodecAudio ac) { writer = w; context = NULL; - // default to aac. - acodec = SrsCodecAudioAAC; + acodec = ac; // default to avc(h.264) vcodec = SrsCodecVideoAVC; } @@ -3296,7 +3295,7 @@ int SrsTsEncoder::initialize(SrsFileWriter* fs) _fs = fs; srs_freep(muxer); - muxer = new SrsTSMuxer(fs); + muxer = new SrsTSMuxer(fs, SrsCodecAudioAAC); if ((ret = muxer->open("")) != ERROR_SUCCESS) { return ret; diff --git a/trunk/src/kernel/srs_kernel_ts.hpp b/trunk/src/kernel/srs_kernel_ts.hpp index 1ebdb12b3..58e303b37 100644 --- a/trunk/src/kernel/srs_kernel_ts.hpp +++ b/trunk/src/kernel/srs_kernel_ts.hpp @@ -1547,7 +1547,7 @@ private: SrsFileWriter* writer; std::string path; public: - SrsTSMuxer(SrsFileWriter* w); + SrsTSMuxer(SrsFileWriter* w, SrsCodecAudio ac); virtual ~SrsTSMuxer(); public: /**