winlin

update api server demo

@@ -331,19 +331,35 @@ class RESTServers(object): @@ -331,19 +331,35 @@ class RESTServers(object):
331 exposed = True 331 exposed = True
332 332
333 def __init__(self): 333 def __init__(self):
  334 + self.__last_update = datetime.datetime.now();
334 self.__server_ip = "192.168.1.142"; 335 self.__server_ip = "192.168.1.142";
335 336
336 ''' 337 '''
  338 + post to update server ip.
  339 + request body: the new raspberry-pi server ip. TODO: FIXME: more info.
  340 + '''
  341 + def POST(self):
  342 + enable_crossdomain()
  343 +
  344 + req = cherrypy.request.body.read()
  345 + self.__server_ip = req;
  346 + self.__last_update = datetime.datetime.now();
  347 +
  348 + return self.__server_ip
  349 +
  350 + '''
337 id canbe: 351 id canbe:
338 - ingest: the ingest demo. 352 + pi: the pi demo, raspberry-pi default demo.
339 action: canbe play or mgmt, play to play the inest stream, mgmt to get api/v1/versions. 353 action: canbe play or mgmt, play to play the inest stream, mgmt to get api/v1/versions.
340 stream: the stream to play, for example, live/livestream for http://server:8080/live/livestream.html 354 stream: the stream to play, for example, live/livestream for http://server:8080/live/livestream.html
341 meeting: the meeting demo. jump to web meeting if index is None. 355 meeting: the meeting demo. jump to web meeting if index is None.
342 local: whether view the local raspberry-pi stream. if "true", redirect to the local(internal) api server. 356 local: whether view the local raspberry-pi stream. if "true", redirect to the local(internal) api server.
343 index: the meeting stream index, dynamic get the streams from root.api.v1.chats.get_url_by_index(index) 357 index: the meeting stream index, dynamic get the streams from root.api.v1.chats.get_url_by_index(index)
  358 + ingest: deprecated, alias for pi.
344 ''' 359 '''
345 def GET(self, id=None, action="play", stream="live/livestream", index=None, local="false"): 360 def GET(self, id=None, action="play", stream="live/livestream", index=None, local="false"):
346 enable_crossdomain() 361 enable_crossdomain()
  362 + # demo, srs meeting urls.
347 if id == "meeting": 363 if id == "meeting":
348 if index is None: 364 if index is None:
349 url = "http://%s:8085"%(self.__server_ip) 365 url = "http://%s:8085"%(self.__server_ip)
@@ -355,24 +371,19 @@ class RESTServers(object): @@ -355,24 +371,19 @@ class RESTServers(object):
355 return "meeting stream not found" 371 return "meeting stream not found"
356 urls = rtmp_url.replace("...vhost...", "?vhost=").replace("rtmp://", "").split("/") 372 urls = rtmp_url.replace("...vhost...", "?vhost=").replace("rtmp://", "").split("/")
357 hls_url = "http://%s:8080/%s/%s.m3u8"%(urls[0].strip(":19350").strip(":1935"), urls[1].split("?")[0], urls[2]) 373 hls_url = "http://%s:8080/%s/%s.m3u8"%(urls[0].strip(":19350").strip(":1935"), urls[1].split("?")[0], urls[2])
358 - return """  
359 -<video width="640" height="360"  
360 - autoplay controls autobuffer  
361 - src="%s"  
362 - type="application/vnd.apple.mpegurl">  
363 -</video>"""%(hls_url);  
364 - else: 374 + return self.__generate_hls(hls_url)
  375 + # raspberry-pi urls.
  376 + elif id == "ingest" or id == "pi":
365 if action == "play": 377 if action == "play":
366 url = "http://%s:8080/%s.html"%(self.__server_ip, stream) 378 url = "http://%s:8080/%s.html"%(self.__server_ip, stream)
367 else: 379 else:
368 url = "http://%s:8080/api/v1/versions"%(self.__server_ip) 380 url = "http://%s:8080/api/v1/versions"%(self.__server_ip)
  381 + # others, default.
  382 + else:
  383 + return "raspberry-pi ip: <a href='http://%s:8080' target='_blank'>%s</a>, last update: %s"%(self.__server_ip, self.__server_ip, self.__last_update)
369 #return "id=%s, action=%s, stream=%s, url=%s, index=%s, local=%s"%(id, action, stream, url, index, local) 384 #return "id=%s, action=%s, stream=%s, url=%s, index=%s, local=%s"%(id, action, stream, url, index, local)
370 raise cherrypy.HTTPRedirect(url) 385 raise cherrypy.HTTPRedirect(url)
371 386
372 - def POST(self):  
373 - enable_crossdomain()  
374 - raise cherrypy.HTTPError(405, "Not allowed.")  
375 -  
376 def DELETE(self, id): 387 def DELETE(self, id):
377 enable_crossdomain() 388 enable_crossdomain()
378 raise cherrypy.HTTPError(405, "Not allowed.") 389 raise cherrypy.HTTPError(405, "Not allowed.")
@@ -384,6 +395,14 @@ class RESTServers(object): @@ -384,6 +395,14 @@ class RESTServers(object):
384 def OPTIONS(self, *args, **kwargs): 395 def OPTIONS(self, *args, **kwargs):
385 enable_crossdomain() 396 enable_crossdomain()
386 397
  398 + def __generate_hls(self, hls_url):
  399 + return """
  400 +<video width="640" height="360"
  401 + autoplay controls autobuffer
  402 + src="%s"
  403 + type="application/vnd.apple.mpegurl">
  404 +</video>"""%(hls_url);
  405 +
387 global_chat_id = os.getpid(); 406 global_chat_id = os.getpid();
388 ''' 407 '''
389 the chat streams, public chat room. 408 the chat streams, public chat room.
@@ -511,21 +530,63 @@ class RESTChats(object): @@ -511,21 +530,63 @@ class RESTChats(object):
511 530
512 # HTTP RESTful path. 531 # HTTP RESTful path.
513 class Root(object): 532 class Root(object):
  533 + exposed = True
  534 +
514 def __init__(self): 535 def __init__(self):
515 self.api = Api() 536 self.api = Api()
  537 + def GET(self):
  538 + enable_crossdomain();
  539 + return json.dumps({"code":Error.success, "urls":{"api":"the api root"}})
  540 + def OPTIONS(self, *args, **kwargs):
  541 + enable_crossdomain();
516 # HTTP RESTful path. 542 # HTTP RESTful path.
517 class Api(object): 543 class Api(object):
  544 + exposed = True
  545 +
518 def __init__(self): 546 def __init__(self):
519 self.v1 = V1() 547 self.v1 = V1()
  548 + def GET(self):
  549 + enable_crossdomain();
  550 + return json.dumps({"code":Error.success,
  551 + "urls": {
  552 + "v1": "the api version 1.0"
  553 + }
  554 + });
  555 + def OPTIONS(self, *args, **kwargs):
  556 + enable_crossdomain();
520 # HTTP RESTful path. to access as: 557 # HTTP RESTful path. to access as:
521 # http://127.0.0.1:8085/api/v1/clients 558 # http://127.0.0.1:8085/api/v1/clients
522 class V1(object): 559 class V1(object):
  560 + exposed = True
  561 +
523 def __init__(self): 562 def __init__(self):
524 self.clients = RESTClients() 563 self.clients = RESTClients()
525 self.streams = RESTStreams() 564 self.streams = RESTStreams()
526 self.sessions = RESTSessions() 565 self.sessions = RESTSessions()
527 self.chats = RESTChats() 566 self.chats = RESTChats()
528 self.servers = RESTServers() 567 self.servers = RESTServers()
  568 + def GET(self):
  569 + enable_crossdomain();
  570 + return json.dumps({"code":Error.success, "urls":{
  571 + "clients": "for srs http callback, to handle the clients requests: connect/disconnect vhost/app.",
  572 + "streams": "for srs http callback, to handle the streams requests: publish/unpublish stream.",
  573 + "sessions": "for srs http callback, to handle the sessions requests: client play/stop stream",
  574 + "chats": "for srs demo meeting, the chat streams, public chat room.",
  575 + "servers": {
  576 + "summary": "for srs raspberry-pi and meeting demo",
  577 + "GET": "get the current raspberry-pi servers info",
  578 + "POST": {
  579 + "body": "the new raspberry-pi server ip."
  580 + },
  581 + "GET id=ingest&action=play&stream=live/livestream": "play the ingest HLS stream on raspberry-pi",
  582 + "GET id=ingest&action=mgmt": "open the HTTP api url of raspberry-pi",
  583 + "GET id=meeting": "redirect to local raspberry-pi meeting url(local ignored)",
  584 + "GET id=meeting&local=false&index=0": "play the first(index=0) meeting HLS stream on demo.chnvideo.com(not local)",
  585 + "GET id=meeting&local=true&index=0": "play the first(index=0) meeting HLS stream on local server(local x86/x64 server), warn: raspberry-pi donot support HLS meeting."
  586 + }
  587 + }});
  588 + def OPTIONS(self, *args, **kwargs):
  589 + enable_crossdomain();
529 590
530 ''' 591 '''
531 main code start. 592 main code start.