@@ -37,7 +37,7 @@ using namespace std;
3737#include < srs_app_http_hooks.hpp>
3838#include < srs_app_statistic.hpp>
3939
40- #define SRS_SECRET_IN_HLS " srs_secret "
40+ #define SRS_CONTEXT_IN_HLS " hls_ctx "
4141
4242SrsVodStream::SrsVodStream (string root_dir) : SrsHttpFileServer(root_dir)
4343{
@@ -47,12 +47,11 @@ SrsVodStream::SrsVodStream(string root_dir) : SrsHttpFileServer(root_dir)
4747SrsVodStream::~SrsVodStream ()
4848{
4949 _srs_hybrid->timer5s ()->unsubscribe (this );
50- std::map<std::string, SrsRequest* >::iterator it;
51- for (it = map_secret_req_ .begin (); it != map_secret_req_ .end (); ++it) {
52- srs_freep (it->second );
50+ std::map<std::string, SrsM3u8CtxInfo >::iterator it;
51+ for (it = map_ctx_info_ .begin (); it != map_ctx_info_ .end (); ++it) {
52+ srs_freep (it->second . req );
5353 }
54- map_secret_req_.clear ();
55- map_secret_validity_.clear ();
54+ map_ctx_info_.clear ();
5655}
5756
5857srs_error_t SrsVodStream::serve_flv_stream (ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath, int offset)
@@ -186,7 +185,7 @@ srs_error_t SrsVodStream::serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMe
186185 return err;
187186}
188187
189- srs_error_t SrsVodStream::serve_m3u8_secret (ISrsHttpResponseWriter * w, ISrsHttpMessage * r, std::string fullpath)
188+ srs_error_t SrsVodStream::serve_m3u8_ctx (ISrsHttpResponseWriter * w, ISrsHttpMessage * r, std::string fullpath)
190189{
191190 srs_error_t err = srs_success;
192191
@@ -196,27 +195,33 @@ srs_error_t SrsVodStream::serve_m3u8_secret(ISrsHttpResponseWriter * w, ISrsHttp
196195 SrsRequest* req = hr->to_request (hr->host ())->as_http ();
197196 SrsAutoFree (SrsRequest, req);
198197
199- string secret = r ->query_get (SRS_SECRET_IN_HLS );
200- if (!secret .empty () && secret_is_exist (secret )) {
201- alive (secret );
202- return SrsHttpFileServer::serve_m3u8_secret (w, r, fullpath);
198+ string ctx = hr ->query_get (SRS_CONTEXT_IN_HLS );
199+ if (!ctx .empty () && ctx_is_exist (ctx )) {
200+ alive (ctx, NULL );
201+ return SrsHttpFileServer::serve_m3u8_ctx (w, r, fullpath);
203202 }
204203
205204 if ((err = http_hooks_on_play (req)) != srs_success) {
206205 return srs_error_wrap (err, " HLS: http_hooks_on_play" );
207206 }
208207
209- if (secret .empty ()) {
208+ if (ctx .empty ()) {
210209 // make sure unique
211210 do {
212- secret = srs_random_str (8 );
213- } while (secret_is_exist (secret ));
211+ ctx = srs_random_str (8 ); // the same as cid
212+ } while (ctx_is_exist (ctx ));
214213 }
215214
216- std::string res = " #EXTM3U\r " ;
217- res += " #EXT-X-STREAM-INF:BANDWIDTH=1,AVERAGE-BANDWIDTH=1\r " ;
218- res += hr->path () + " ?" + SRS_SECRET_IN_HLS + " =" + secret;
215+ std::stringstream ss;
216+ ss << " #EXTM3U" << SRS_CONSTS_LF;
217+ ss << " #EXT-X-STREAM-INF:BANDWIDTH=1,AVERAGE-BANDWIDTH=1" << SRS_CONSTS_LF;
218+ ss << hr->path () << " ?" << SRS_CONTEXT_IN_HLS << " =" << ctx;
219+ if (!hr->query ().empty () && !srs_string_contains (hr->query (), " hls_ctx" ))
220+ {
221+ ss << " &" << hr->query ();
222+ }
219223
224+ std::string res = ss.str ();
220225 int length = res.length ();
221226
222227 w->header ()->set_content_length (length);
@@ -233,25 +238,31 @@ srs_error_t SrsVodStream::serve_m3u8_secret(ISrsHttpResponseWriter * w, ISrsHttp
233238
234239 // update the statistic when source disconveried.
235240 SrsStatistic* stat = SrsStatistic::instance ();
236- if ((err = stat->on_client (secret , req, NULL , SrsRtmpConnPlay)) != srs_success) {
241+ if ((err = stat->on_client (ctx , req, NULL , SrsRtmpConnPlay)) != srs_success) {
237242 return srs_error_wrap (err, " stat on client" );
238243 }
239244
240- // save req for on_disconnect when timeout
241- map_secret_req_.insert (make_pair (secret, req->copy ()));
242- alive (secret);
245+ alive (ctx, req->copy ());
243246
244247 return err;
245248}
246249
247- bool SrsVodStream::secret_is_exist (std::string secret)
250+ bool SrsVodStream::ctx_is_exist (std::string secret)
248251{
249- return (map_secret_validity_ .find (secret) != map_secret_validity_ .end ());
252+ return (map_ctx_info_ .find (secret) != map_ctx_info_ .end ());
250253}
251254
252- void SrsVodStream::alive (std::string secret)
255+ void SrsVodStream::alive (std::string secret, SrsRequest* req )
253256{
254- map_secret_validity_[secret] = srs_get_system_time ();
257+ std::map<std::string, SrsM3u8CtxInfo>::iterator it;
258+ if ((it = map_ctx_info_.find (secret)) != map_ctx_info_.end ()) {
259+ it->second .request_time = srs_get_system_time ();
260+ } else {
261+ SrsM3u8CtxInfo info;
262+ info.req = req;
263+ info.request_time = srs_get_system_time ();
264+ map_ctx_info_.insert (make_pair (secret, info));
265+ }
255266}
256267
257268srs_error_t SrsVodStream::http_hooks_on_play (SrsRequest* req)
@@ -321,19 +332,18 @@ srs_error_t SrsVodStream::on_timer(srs_utime_t interval)
321332{
322333 srs_error_t err = srs_success;
323334
324- std::map<std::string, srs_utime_t >::iterator it;
325- for (it = map_secret_validity_ .begin (); it != map_secret_validity_ .end (); ++it) {
335+ std::map<std::string, SrsM3u8CtxInfo >::iterator it;
336+ for (it = map_ctx_info_ .begin (); it != map_ctx_info_ .end (); ++it) {
326337 string secret = it->first ;
327- SrsRequest* req = map_secret_req_[secret] ;
338+ SrsRequest* req = it-> second . req ;
328339 srs_utime_t hls_window = _srs_config->get_hls_window (req->vhost );
329- if (it->second + (2 * hls_window) < srs_get_system_time ()) {
340+ if (it->second . request_time + (2 * hls_window) < srs_get_system_time ()) {
330341 http_hooks_on_stop (req);
331342 srs_freep (req);
332- map_secret_req_.erase (secret);
333343
334344 SrsStatistic* stat = SrsStatistic::instance ();
335345 stat->on_disconnect (secret);
336- map_secret_validity_ .erase (it);
346+ map_ctx_info_ .erase (it);
337347
338348 break ;
339349 }
0 commit comments