1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

enhance hls, increase piece one by one.

This commit is contained in:
winlin 2015-03-31 16:58:20 +08:00
parent b9c21b1e8f
commit 76c1957260
3 changed files with 101 additions and 4 deletions

View file

@ -563,6 +563,7 @@ vhost with-hls.srs.com {
# whether use floor for the hls_ts_file path generation. # whether use floor for the hls_ts_file path generation.
# if on, use floor(timestamp/hls_fragment) as the variable [timestamp], # if on, use floor(timestamp/hls_fragment) as the variable [timestamp],
# and use enahanced algorithm to calc deviation for segment. # and use enahanced algorithm to calc deviation for segment.
# @remark when floor on, recommend the hls_segment>=2*gop.
# default: off # default: off
hls_ts_floor off; hls_ts_floor off;
# the hls entry prefix, which is base url of ts url. # the hls entry prefix, which is base url of ts url.
@ -740,7 +741,8 @@ vhost hooks.callback.srs.com {
# "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live", # "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live",
# "stream": "livestream", # "stream": "livestream",
# "cwd": "/usr/local/srs", # "cwd": "/usr/local/srs",
# "file": "./objs/nginx/html/live/livestream.1420254068776-100.ts" # "file": "./objs/nginx/html/live/livestream.1420254068776-100.ts",
# "seq_no": 100
# } # }
# if valid, the hook must return HTTP code 200(Stauts OK) and response # if valid, the hook must return HTTP code 200(Stauts OK) and response
# an int value specifies the error code(0 corresponding to success): # an int value specifies the error code(0 corresponding to success):

View file

@ -333,6 +333,99 @@ class RESTDvrs(object):
return code return code
'''
handle the hls requests: hls stream.
'''
class RESTHls(object):
exposed = True
def GET(self):
enable_crossdomain()
hls = {}
return json.dumps(hls)
'''
for SRS hook: on_dvr, on_dvr_reap_segment
on_dvr:
when srs reap a dvr file, call the hook,
the request in the POST data string is a object encode by json:
{
"action": "on_dvr",
"client_id": 1985,
"ip": "192.168.1.10", "vhost": "video.test.com", "app": "live",
"stream": "livestream",
"cwd": "/usr/local/srs",
"file": "./objs/nginx/html/live/livestream.1420254068776.flv"
}
on_dvr_reap_segment:
when api dvr specifes the callback when reap flv segment, call the hook,
the request in the POST data string is a object encode by json:
{
"action": "on_dvr_reap_segment",
"client_id": 1985,
"vhost": "video.test.com", "app": "live",
"stream": "livestream",
"cwd": "/usr/local/srs",
"file": "./objs/nginx/html/live/livestream.1420254068776.flv"
}
if valid, the hook must return HTTP code 200(Stauts OK) and response
an int value specifies the error code(0 corresponding to success):
0
'''
def POST(self):
enable_crossdomain()
# return the error code in str
code = Error.success
req = cherrypy.request.body.read()
trace("post to dvrs, req=%s"%(req))
try:
json_req = json.loads(req)
except Exception, ex:
code = Error.system_parse_json
trace("parse the request to json failed, req=%s, ex=%s, code=%s"%(req, ex, code))
return str(code)
action = json_req["action"]
if action == "on_dvr":
code = self.__on_dvr(json_req)
if action == "on_dvr_reap_segment":
code = self.__on_dvr_reap_segment(json_req)
else:
trace("invalid request action: %s"%(json_req["action"]))
code = Error.request_invalid_action
return str(code)
def OPTIONS(self, *args, **kwargs):
enable_crossdomain()
def __on_dvr(self, req):
code = Error.success
trace("srs %s: client id=%s, ip=%s, vhost=%s, app=%s, stream=%s, cwd=%s, file=%s"%(
req["action"], req["client_id"], req["ip"], req["vhost"], req["app"], req["stream"],
req["cwd"], req["file"]
))
# TODO: process the on_dvr event
return code
def __on_dvr_reap_segment(self, req):
code = Error.success
trace("srs %s: client id=%s, vhost=%s, app=%s, stream=%s, cwd=%s, file=%s"%(
req["action"], req["client_id"], req["vhost"], req["app"], req["stream"],
req["cwd"], req["file"]
))
# TODO: process the on_dvr event
return code
''' '''
handle the sessions requests: client play/stop stream handle the sessions requests: client play/stop stream
''' '''
@ -1133,6 +1226,7 @@ class V1(object):
self.streams = RESTStreams() self.streams = RESTStreams()
self.sessions = RESTSessions() self.sessions = RESTSessions()
self.dvrs = RESTDvrs() self.dvrs = RESTDvrs()
self.hls = RESTHls()
self.chats = RESTChats() self.chats = RESTChats()
self.servers = RESTServers() self.servers = RESTServers()
self.nodes = RESTNodes() self.nodes = RESTNodes()

View file

@ -331,17 +331,18 @@ int SrsHlsMuxer::segment_open(int64_t segment_start_dts)
std::string ts_file = hls_ts_file; std::string ts_file = hls_ts_file;
ts_file = srs_path_build_stream(ts_file, req->vhost, req->app, req->stream); ts_file = srs_path_build_stream(ts_file, req->vhost, req->app, req->stream);
if (hls_ts_floor) { if (hls_ts_floor) {
int64_t floor_ts = (int64_t)(srs_get_system_time_ms() / (1000 * hls_fragment)); // we always ensure the piece is increase one by one.
std::stringstream ts_floor; std::stringstream ts_floor;
ts_floor << floor_ts; ts_floor << (int64_t)(previous_floor_ts + 1);
ts_file = srs_string_replace(ts_file, "[timestamp]", ts_floor.str()); ts_file = srs_string_replace(ts_file, "[timestamp]", ts_floor.str());
// dup/jmp detect for ts in floor mode. // dup/jmp detect for ts in floor mode.
int64_t floor_ts = (int64_t)(srs_get_system_time_ms() / (1000 * hls_fragment));
if (previous_floor_ts && previous_floor_ts != floor_ts - 1) { if (previous_floor_ts && previous_floor_ts != floor_ts - 1) {
srs_warn("hls: dup or jmp for floor ts, previous=%"PRId64", current=%"PRId64", ts=%s, deviation=%.2f", srs_warn("hls: dup or jmp for floor ts, previous=%"PRId64", current=%"PRId64", ts=%s, deviation=%.2f",
previous_floor_ts, floor_ts, ts_file.c_str(), hls_fragment_deviation); previous_floor_ts, floor_ts, ts_file.c_str(), hls_fragment_deviation);
} }
previous_floor_ts = floor_ts; previous_floor_ts++;
} }
ts_file = srs_path_build_timestamp(ts_file); ts_file = srs_path_build_timestamp(ts_file);
if (true) { if (true) {