正在显示
1 个修改的文件
包含
8 行增加
和
451 行删除
| @@ -548,6 +548,7 @@ class ArmServer: | @@ -548,6 +548,7 @@ class ArmServer: | ||
| 548 | data["heartbeat"] = self.heartbeat | 548 | data["heartbeat"] = self.heartbeat |
| 549 | data["heartbeat_h"] = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(self.heartbeat)) | 549 | data["heartbeat_h"] = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(self.heartbeat)) |
| 550 | data["summaries"] = "http://%s:1985/api/v1/summaries"%(self.ip) | 550 | data["summaries"] = "http://%s:1985/api/v1/summaries"%(self.ip) |
| 551 | + data["console"] = "http://ossrs.net/console/ng_index.html#/summaries?host=%s&port=1985"%(self.ip) | ||
| 551 | return data | 552 | return data |
| 552 | 553 | ||
| 553 | ''' | 554 | ''' |
| @@ -579,29 +580,6 @@ class RESTServers(object): | @@ -579,29 +580,6 @@ class RESTServers(object): | ||
| 579 | if not has_dead_node: | 580 | if not has_dead_node: |
| 580 | break | 581 | break |
| 581 | 582 | ||
| 582 | - def __json_dump_nodes(self, peers): | ||
| 583 | - data = [] | ||
| 584 | - for node in peers: | ||
| 585 | - data.append(node.json_dump()) | ||
| 586 | - return data | ||
| 587 | - | ||
| 588 | - def __get_peers_for_play(self, device_id): | ||
| 589 | - peers = [] | ||
| 590 | - for node in self.__nodes: | ||
| 591 | - if node.device_id == device_id: | ||
| 592 | - peers.append(node) | ||
| 593 | - return peers | ||
| 594 | - | ||
| 595 | - def __select_peer(self, peers, device_id): | ||
| 596 | - target = None | ||
| 597 | - for peer in peers: | ||
| 598 | - if target is None or target.clients > peer.clients: | ||
| 599 | - target = peer | ||
| 600 | - if target is None: | ||
| 601 | - return None | ||
| 602 | - target.clients += 1 | ||
| 603 | - return target.ip | ||
| 604 | - | ||
| 605 | ''' | 583 | ''' |
| 606 | post to update server ip. | 584 | post to update server ip. |
| 607 | request body: the new raspberry-pi server ip. TODO: FIXME: more info. | 585 | request body: the new raspberry-pi server ip. TODO: FIXME: more info. |
| @@ -637,183 +615,21 @@ class RESTServers(object): | @@ -637,183 +615,21 @@ class RESTServers(object): | ||
| 637 | self.__lock.release() | 615 | self.__lock.release() |
| 638 | 616 | ||
| 639 | ''' | 617 | ''' |
| 640 | - id canbe: | ||
| 641 | - pi: the pi demo, raspberry-pi default demo. | ||
| 642 | - device_id: the id of device to get. | ||
| 643 | - action: canbe play or mgmt, play to play the inest stream, mgmt to get api/v1/versions. | ||
| 644 | - stream: the stream to play, for example, live/livestream for http://server:8080/live/livestream.html | ||
| 645 | - meeting: the meeting demo. jump to web meeting if index is None. | ||
| 646 | - device_id: the id of device to get. | ||
| 647 | - local: whether view the local raspberry-pi stream. if "true", redirect to the local(internal) api server. | ||
| 648 | - index: the meeting stream index, dynamic get the streams from root.api.v1.chats.get_url_by_index(index) | ||
| 649 | - gslb: the gslb to get edge ip | ||
| 650 | - device_id: the id of device to get. | ||
| 651 | - ingest: deprecated, alias for pi. | 618 | + get all servers which report to this api-server. |
| 652 | ''' | 619 | ''' |
| 653 | - def GET(self, id=None, action="play", stream="live/livestream", index=None, local="false", device_id=None): | 620 | + def GET(self): |
| 654 | enable_crossdomain() | 621 | enable_crossdomain() |
| 655 | 622 | ||
| 656 | try: | 623 | try: |
| 657 | self.__lock.acquire() | 624 | self.__lock.acquire() |
| 658 | 625 | ||
| 659 | self.__refresh_nodes() | 626 | self.__refresh_nodes() |
| 660 | - data = self.__json_dump_nodes(self.__nodes) | ||
| 661 | 627 | ||
| 662 | - server_ip = "demo.chnvideo.com" | ||
| 663 | - ip = cherrypy.request.remote.ip | ||
| 664 | - if type is not None: | ||
| 665 | - peers = self.__get_peers_for_play(device_id) | ||
| 666 | - if len(peers) > 0: | ||
| 667 | - server_ip = self.__select_peer(peers, device_id) | 628 | + data = [] |
| 629 | + for node in self.__nodes: | ||
| 630 | + data.append(node.json_dump()) | ||
| 668 | 631 | ||
| 669 | - # demo, srs meeting urls. | ||
| 670 | - if id == "meeting": | ||
| 671 | - if index is None: | ||
| 672 | - url = "http://%s:8085"%(server_ip) | ||
| 673 | - elif local == "true": | ||
| 674 | - url = "http://%s:8085/api/v1/servers?id=%s&index=%s&local=false"%(server_ip, id, index) | ||
| 675 | - else: | ||
| 676 | - rtmp_url = root.api.v1.chats.get_url_by_index(index) | ||
| 677 | - if rtmp_url is None: | ||
| 678 | - return "meeting stream not found" | ||
| 679 | - urls = rtmp_url.replace("...vhost...", "?vhost=").replace("rtmp://", "").split("/") | ||
| 680 | - hls_url = "http://%s:8080/%s/%s.m3u8"%(urls[0].strip(":19350").strip(":1935"), urls[1].split("?")[0], urls[2]) | ||
| 681 | - return self.__generate_hls(hls_url) | ||
| 682 | - # raspberry-pi urls. | ||
| 683 | - elif id == "ingest" or id == "pi": | ||
| 684 | - if action == "play": | ||
| 685 | - url = "http://%s:8080/%s.html"%(server_ip, stream) | ||
| 686 | - elif action == "rtmp": | ||
| 687 | - url = "../../players/srs_player.html?server=%s&vhost=%s&app=%s&stream=%s&autostart=true"%(server_ip, server_ip, stream.split("/")[0], stream.split("/")[1]) | ||
| 688 | - elif action == "hls": | ||
| 689 | - hls_url = "http://%s:8080/%s.m3u8"%(server_ip, stream); | ||
| 690 | - if stream.startswith("http://"): | ||
| 691 | - hls_url = stream; | ||
| 692 | - return self.__generate_hls(hls_url.replace(".m3u8.m3u8", ".m3u8")) | ||
| 693 | - else: | ||
| 694 | - url = "http://%s:8080/api/v1/versions"%(server_ip) | ||
| 695 | - elif id == "gslb": | ||
| 696 | - return json.dumps({"code":Error.success, "data": { | ||
| 697 | - "edge":server_ip, "client":ip, | ||
| 698 | - "peers":self.__json_dump_nodes(peers), | ||
| 699 | - "streams": { | ||
| 700 | - "pi": { | ||
| 701 | - "livestream": { | ||
| 702 | - "sales-pi-hls": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-sales-arm&stream=live/livestream", | ||
| 703 | - "dev-pi-hls": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-dev-arm&stream=live/livestream" | ||
| 704 | - }, | ||
| 705 | - "cztv": { | ||
| 706 | - "sales-pi-hls": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-sales-arm&stream=live/rtmp_cztv01-sd", | ||
| 707 | - "dev-pi-hls": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-dev-arm&stream=live/rtmp_cztv01-sd" | ||
| 708 | - } | ||
| 709 | - }, | ||
| 710 | - "hiwifi": { | ||
| 711 | - "hls": { | ||
| 712 | - "dev-livestream": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-dev-hiwifi&stream=live/livestream", | ||
| 713 | - "sales-livestream": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-sales-hiwifi&stream=live/livestream" | ||
| 714 | - }, | ||
| 715 | - "rtmp":{ | ||
| 716 | - "dev-livestream": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=rtmp&device_id=chnvideo-dev-hiwifi&stream=live/livestream", | ||
| 717 | - "sales-livestream": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=rtmp&device_id=chnvideo-sales-hiwifi&stream=live/livestream" | ||
| 718 | - }, | ||
| 719 | - "meiyi": { | ||
| 720 | - "rtmp": { | ||
| 721 | - "avatar": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=rtmp&device_id=chnvideo-sales-hiwifi&stream=live/avatar", | ||
| 722 | - "MenInBlack3": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=rtmp&device_id=chnvideo-sales-hiwifi&stream=live/MenInBlack3", | ||
| 723 | - "skyfall": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=rtmp&device_id=chnvideo-sales-hiwifi&stream=live/skyfall", | ||
| 724 | - "SpiderMan": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=rtmp&device_id=chnvideo-sales-hiwifi&stream=live/SpiderMan", | ||
| 725 | - "thehobbit": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=rtmp&device_id=chnvideo-sales-hiwifi&stream=live/thehobbit", | ||
| 726 | - "thorthedarkworld": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=rtmp&device_id=chnvideo-sales-hiwifi&stream=live/thorthedarkworld", | ||
| 727 | - "transformers": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=rtmp&device_id=chnvideo-sales-hiwifi&stream=live/transformers" | ||
| 728 | - }, | ||
| 729 | - "hls": { | ||
| 730 | - "avatar": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-sales-hiwifi&stream=live/avatar", | ||
| 731 | - "MenInBlack3": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-sales-hiwifi&stream=live/MenInBlack3", | ||
| 732 | - "skyfall": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-sales-hiwifi&stream=live/skyfall", | ||
| 733 | - "SpiderMan": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-sales-hiwifi&stream=live/SpiderMan", | ||
| 734 | - "thehobbit": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-sales-hiwifi&stream=live/thehobbit", | ||
| 735 | - "thorthedarkworld": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-sales-hiwifi&stream=live/thorthedarkworld", | ||
| 736 | - "transformers": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-sales-hiwifi&stream=live/transformers" | ||
| 737 | - } | ||
| 738 | - } | ||
| 739 | - }, | ||
| 740 | - "cubieboard": { | ||
| 741 | - "meiyi": { | ||
| 742 | - "rtmp": { | ||
| 743 | - "livesteam": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=rtmp&device_id=chnvideo-meiyi-cubieboard&stream=live/livestream", | ||
| 744 | - "stream1": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=rtmp&device_id=chnvideo-meiyi-cubieboard&stream=live/stream1", | ||
| 745 | - "stream2": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=rtmp&device_id=chnvideo-meiyi-cubieboard&stream=live/stream2", | ||
| 746 | - "stream3": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=rtmp&device_id=chnvideo-meiyi-cubieboard&stream=live/stream3", | ||
| 747 | - "stream4": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=rtmp&device_id=chnvideo-meiyi-cubieboard&stream=live/stream4", | ||
| 748 | - "stream5": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=rtmp&device_id=chnvideo-meiyi-cubieboard&stream=live/stream5", | ||
| 749 | - "stream6": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=rtmp&device_id=chnvideo-meiyi-cubieboard&stream=live/stream6", | ||
| 750 | - "stream7": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=rtmp&device_id=chnvideo-meiyi-cubieboard&stream=live/stream7" | ||
| 751 | - }, | ||
| 752 | - "hls": { | ||
| 753 | - "livesteam": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-meiyi-cubieboard&stream=live/livestream", | ||
| 754 | - "stream1": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-meiyi-cubieboard&stream=live/stream1", | ||
| 755 | - "stream2": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-meiyi-cubieboard&stream=live/stream2", | ||
| 756 | - "stream3": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-meiyi-cubieboard&stream=live/stream3", | ||
| 757 | - "stream4": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-meiyi-cubieboard&stream=live/stream4", | ||
| 758 | - "stream5": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-meiyi-cubieboard&stream=live/stream5", | ||
| 759 | - "stream6": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-meiyi-cubieboard&stream=live/stream6", | ||
| 760 | - "stream7": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-meiyi-cubieboard&stream=live/stream7" | ||
| 761 | - } | ||
| 762 | - }, | ||
| 763 | - "meiyi-house": { | ||
| 764 | - "rtmp": { | ||
| 765 | - "livesteam": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=rtmp&device_id=chnvideo-meiyi-cubieboard-house&stream=live/livestream" | ||
| 766 | - }, | ||
| 767 | - "hls": { | ||
| 768 | - "livesteam": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-meiyi-cubieboard-house&stream=live/livestream" | ||
| 769 | - } | ||
| 770 | - }, | ||
| 771 | - "meiyi-bk": { | ||
| 772 | - "rtmp": { | ||
| 773 | - "livesteam": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=rtmp&device_id=chnvideo-meiyi-cubieboard-bk&stream=live/livestream", | ||
| 774 | - "stream1": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=rtmp&device_id=chnvideo-meiyi-cubieboard-bk&stream=live/stream1", | ||
| 775 | - "stream2": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=rtmp&device_id=chnvideo-meiyi-cubieboard-bk&stream=live/stream2", | ||
| 776 | - "stream3": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=rtmp&device_id=chnvideo-meiyi-cubieboard-bk&stream=live/stream3", | ||
| 777 | - "stream4": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=rtmp&device_id=chnvideo-meiyi-cubieboard-bk&stream=live/stream4", | ||
| 778 | - "stream5": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=rtmp&device_id=chnvideo-meiyi-cubieboard-bk&stream=live/stream5", | ||
| 779 | - "stream6": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=rtmp&device_id=chnvideo-meiyi-cubieboard-bk&stream=live/stream6", | ||
| 780 | - "stream7": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=rtmp&device_id=chnvideo-meiyi-cubieboard-bk&stream=live/stream7" | ||
| 781 | - }, | ||
| 782 | - "hls": { | ||
| 783 | - "livesteam": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-meiyi-cubieboard-bk&stream=live/livestream", | ||
| 784 | - "stream1": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-meiyi-cubieboard-bk&stream=live/stream1", | ||
| 785 | - "stream2": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-meiyi-cubieboard-bk&stream=live/stream2", | ||
| 786 | - "stream3": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-meiyi-cubieboard-bk&stream=live/stream3", | ||
| 787 | - "stream4": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-meiyi-cubieboard-bk&stream=live/stream4", | ||
| 788 | - "stream5": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-meiyi-cubieboard-bk&stream=live/stream5", | ||
| 789 | - "stream6": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-meiyi-cubieboard-bk&stream=live/stream6", | ||
| 790 | - "stream7": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-meiyi-cubieboard-bk&stream=live/stream7" | ||
| 791 | - } | ||
| 792 | - }, | ||
| 793 | - "meiyi-dev1": { | ||
| 794 | - "rtmp": { | ||
| 795 | - "livesteam": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=rtmp&device_id=chnvideo-meiyi-cubieboard-dev1&stream=live/livestream" | ||
| 796 | - }, | ||
| 797 | - "hls": { | ||
| 798 | - "livesteam": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-meiyi-cubieboard-dev1&stream=live/livestream" | ||
| 799 | - } | ||
| 800 | - }, | ||
| 801 | - "meiyi-dev2": { | ||
| 802 | - "rtmp": { | ||
| 803 | - "livesteam": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=rtmp&device_id=chnvideo-meiyi-cubieboard-dev2&stream=live/livestream" | ||
| 804 | - }, | ||
| 805 | - "hls": { | ||
| 806 | - "livesteam": "http://demo.chnvideo.com:8085/api/v1/servers?id=ingest&action=hls&device_id=chnvideo-meiyi-cubieboard-dev2&stream=live/livestream" | ||
| 807 | - } | ||
| 808 | - } | ||
| 809 | - } | ||
| 810 | - } | ||
| 811 | - }}) | ||
| 812 | - # others, default. | ||
| 813 | - else: | ||
| 814 | - return json.dumps(data) | ||
| 815 | - #return "id=%s, action=%s, stream=%s, url=%s, index=%s, local=%s"%(id, action, stream, url, index, local) | ||
| 816 | - raise cherrypy.HTTPRedirect(url) | 632 | + return json.dumps(data) |
| 817 | finally: | 633 | finally: |
| 818 | self.__lock.release() | 634 | self.__lock.release() |
| 819 | 635 | ||
| @@ -827,248 +643,6 @@ class RESTServers(object): | @@ -827,248 +643,6 @@ class RESTServers(object): | ||
| 827 | 643 | ||
| 828 | def OPTIONS(self, *args, **kwargs): | 644 | def OPTIONS(self, *args, **kwargs): |
| 829 | enable_crossdomain() | 645 | enable_crossdomain() |
| 830 | - | ||
| 831 | - def __generate_hls(self, hls_url): | ||
| 832 | - return SrsUtility().hls_html(hls_url) | ||
| 833 | - | ||
| 834 | -class SrsUtility: | ||
| 835 | - def hls_html(self, hls_url): | ||
| 836 | - return """ | ||
| 837 | -<h1>%s</h1> | ||
| 838 | -<video width="640" height="360" | ||
| 839 | - autoplay controls autobuffer | ||
| 840 | - src="%s" | ||
| 841 | - type="application/vnd.apple.mpegurl"> | ||
| 842 | -</video>"""%(hls_url, hls_url); | ||
| 843 | - | ||
| 844 | -global_cdn_id = os.getpid(); | ||
| 845 | -class CdnNode: | ||
| 846 | - def __init__(self): | ||
| 847 | - global global_cdn_id | ||
| 848 | - global_cdn_id += 1 | ||
| 849 | - | ||
| 850 | - self.id = str(global_cdn_id) | ||
| 851 | - self.ip = None | ||
| 852 | - self.origin = None | ||
| 853 | - self.os = None | ||
| 854 | - self.srs_status = None | ||
| 855 | - | ||
| 856 | - self.public_ip = cherrypy.request.remote.ip | ||
| 857 | - self.heartbeat = time.time() | ||
| 858 | - | ||
| 859 | - self.clients = 0 | ||
| 860 | - | ||
| 861 | - def dead(self): | ||
| 862 | - dead_time_seconds = 10 | ||
| 863 | - if time.time() - self.heartbeat > dead_time_seconds: | ||
| 864 | - return True | ||
| 865 | - return False | ||
| 866 | - | ||
| 867 | - def json_dump(self): | ||
| 868 | - data = {} | ||
| 869 | - data["id"] = self.id | ||
| 870 | - data["ip"] = self.ip | ||
| 871 | - data["origin"] = self.origin | ||
| 872 | - data["os"] = self.os | ||
| 873 | - data["srs_status"] = self.srs_status | ||
| 874 | - data["public_ip"] = self.public_ip | ||
| 875 | - data["heartbeat"] = self.heartbeat | ||
| 876 | - data["heartbeat_h"] = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(self.heartbeat)) | ||
| 877 | - data["clients"] = self.clients | ||
| 878 | - data["summaries"] = "http://%s:1985/api/v1/summaries"%(self.ip) | ||
| 879 | - return data | ||
| 880 | - | ||
| 881 | -''' | ||
| 882 | -the cdn nodes list | ||
| 883 | -''' | ||
| 884 | -class RESTNodes(object): | ||
| 885 | - exposed = True | ||
| 886 | - | ||
| 887 | - def __init__(self): | ||
| 888 | - self.__nodes = [] | ||
| 889 | - # @remark, if there is shared data, such as the self.__nodes, | ||
| 890 | - # we must use lock for cherrypy, or the cpu of cherrypy will high | ||
| 891 | - # and performance suffer. | ||
| 892 | - self.__lock = threading.Lock() | ||
| 893 | - | ||
| 894 | - def __get_node(self, id): | ||
| 895 | - for node in self.__nodes: | ||
| 896 | - if node.id == id: | ||
| 897 | - return node | ||
| 898 | - return None | ||
| 899 | - | ||
| 900 | - def __refresh_nodes(self): | ||
| 901 | - while len(self.__nodes) > 0: | ||
| 902 | - has_dead_node = False | ||
| 903 | - for node in self.__nodes: | ||
| 904 | - if node.dead(): | ||
| 905 | - self.__nodes.remove(node) | ||
| 906 | - has_dead_node = True | ||
| 907 | - if not has_dead_node: | ||
| 908 | - break | ||
| 909 | - | ||
| 910 | - def __get_peers(self, target_node): | ||
| 911 | - peers = [] | ||
| 912 | - for node in self.__nodes: | ||
| 913 | - if str(node.id).strip() == str(target_node.id).strip(): | ||
| 914 | - continue | ||
| 915 | - if node.public_ip == target_node.public_ip and node.srs_status == "running" and node.origin != target_node.ip: | ||
| 916 | - peers.append(node) | ||
| 917 | - return peers | ||
| 918 | - | ||
| 919 | - def __get_peers_for_play(self, ip): | ||
| 920 | - peers = [] | ||
| 921 | - for node in self.__nodes: | ||
| 922 | - if node.public_ip == ip and node.srs_status == "running": | ||
| 923 | - peers.append(node) | ||
| 924 | - return peers | ||
| 925 | - | ||
| 926 | - def __json_dump_nodes(self, peers): | ||
| 927 | - data = [] | ||
| 928 | - for node in peers: | ||
| 929 | - data.append(node.json_dump()) | ||
| 930 | - return data | ||
| 931 | - | ||
| 932 | - def __select_peer(self, peers, ip): | ||
| 933 | - target = None | ||
| 934 | - for peer in peers: | ||
| 935 | - if target is None or target.clients > peer.clients: | ||
| 936 | - target = peer | ||
| 937 | - if target is None: | ||
| 938 | - return None | ||
| 939 | - target.clients += 1 | ||
| 940 | - return target.ip | ||
| 941 | - | ||
| 942 | - def GET(self, type=None, format=None, origin=None, vhost=None, port=None, stream=None, node_id=None): | ||
| 943 | - enable_crossdomain() | ||
| 944 | - | ||
| 945 | - try: | ||
| 946 | - self.__lock.acquire() | ||
| 947 | - | ||
| 948 | - self.__refresh_nodes() | ||
| 949 | - data = self.__json_dump_nodes(self.__nodes) | ||
| 950 | - | ||
| 951 | - ip = cherrypy.request.remote.ip | ||
| 952 | - if type is not None: | ||
| 953 | - server = origin | ||
| 954 | - peers = self.__get_peers_for_play(ip) | ||
| 955 | - if len(peers) > 0: | ||
| 956 | - server = self.__select_peer(peers, ip) | ||
| 957 | - if type == "hls": | ||
| 958 | - hls_url = "http://%s:%s/%s.m3u8"%(server, port, stream) | ||
| 959 | - hls_url = hls_url.replace(".m3u8.m3u8", ".m3u8") | ||
| 960 | - if format == "html": | ||
| 961 | - return SrsUtility().hls_html(hls_url) | ||
| 962 | - else: | ||
| 963 | - #return hls_url | ||
| 964 | - raise cherrypy.HTTPRedirect(hls_url) | ||
| 965 | - elif type == "rtmp": | ||
| 966 | - rtmp_url = "rtmp://%s:%s/%s?vhost=%s/%s"%(server, port, stream.split("/")[0], vhost, stream.split("/")[1]) | ||
| 967 | - if format == "html": | ||
| 968 | - html = "%s?server=%s&port=%s&vhost=%s&app=%s&stream=%s&autostart=true"%( | ||
| 969 | - "http://demo.chnvideo.com:8085/srs/trunk/research/players/srs_player.html", | ||
| 970 | - server, port, vhost, stream.split("/")[0], stream.split("/")[1]) | ||
| 971 | - #return html | ||
| 972 | - raise cherrypy.HTTPRedirect(html) | ||
| 973 | - return rtmp_url | ||
| 974 | - elif type == "gslb": | ||
| 975 | - return json.dumps({"code":Error.success, "data": { | ||
| 976 | - "edge":server, "client":ip, | ||
| 977 | - "peers":self.__json_dump_nodes(peers), | ||
| 978 | - "streams": { | ||
| 979 | - "cztv": { | ||
| 980 | - "hls": "http://demo.chnvideo.com:8085/api/v1/nodes?type=hls&format=html&origin=demo.chnvideo.com&port=8080&stream=live/rtmp_cztv01-sd", | ||
| 981 | - "rtmp": "http://demo.chnvideo.com:8085/api/v1/nodes?type=rtmp&format=html&origin=demo.chnvideo.com&vhost=android&port=1935&stream=live/rtmp_cztv01-sd" | ||
| 982 | - }, | ||
| 983 | - "livestream": { | ||
| 984 | - "hls": "http://demo.chnvideo.com:8085/api/v1/nodes?type=hls&format=html&origin=demo.chnvideo.com&port=8080&stream=live/livestream", | ||
| 985 | - "rtmp": "http://demo.chnvideo.com:8085/api/v1/nodes?type=rtmp&format=html&origin=demo.chnvideo.com&vhost=demo.srs.com&port=1935&stream=live/livestream" | ||
| 986 | - }, | ||
| 987 | - "apk": "http://demo.chnvideo.com/android.srs.apk" | ||
| 988 | - } | ||
| 989 | - }}) | ||
| 990 | - | ||
| 991 | - return json.dumps({"code":Error.success, "data": data}) | ||
| 992 | - finally: | ||
| 993 | - self.__lock.release() | ||
| 994 | - | ||
| 995 | - def PUT(self): | ||
| 996 | - enable_crossdomain() | ||
| 997 | - | ||
| 998 | - try: | ||
| 999 | - self.__lock.acquire() | ||
| 1000 | - | ||
| 1001 | - req = cherrypy.request.body.read() | ||
| 1002 | - trace("put to nodes, req=%s"%(req)) | ||
| 1003 | - try: | ||
| 1004 | - json_req = json.loads(req) | ||
| 1005 | - except Exception, ex: | ||
| 1006 | - code = Error.system_parse_json | ||
| 1007 | - trace("parse the request to json failed, req=%s, ex=%s, code=%s"%(req, ex, code)) | ||
| 1008 | - return json.dumps({"code":code, "data": None}) | ||
| 1009 | - | ||
| 1010 | - id = str(json_req["id"]) | ||
| 1011 | - node = self.__get_node(id) | ||
| 1012 | - if node is None: | ||
| 1013 | - code = Error.cdn_node_not_exists | ||
| 1014 | - trace("cdn node not exists, req=%s, id=%s, code=%s"%(req, id, code)) | ||
| 1015 | - return json.dumps({"code":code, "data": None}) | ||
| 1016 | - | ||
| 1017 | - node.heartbeat = time.time() | ||
| 1018 | - node.srs_status = str(json_req["srs_status"]) | ||
| 1019 | - node.ip = str(json_req["ip"]) | ||
| 1020 | - if "origin" in json_req: | ||
| 1021 | - node.origin = str(json_req["origin"]); | ||
| 1022 | - node.public_ip = cherrypy.request.remote.ip | ||
| 1023 | - # reset if restart. | ||
| 1024 | - if node.srs_status != "running": | ||
| 1025 | - node.clients = 0 | ||
| 1026 | - | ||
| 1027 | - self.__refresh_nodes() | ||
| 1028 | - peers = self.__get_peers(node) | ||
| 1029 | - peers_data = self.__json_dump_nodes(peers) | ||
| 1030 | - | ||
| 1031 | - res = json.dumps({"code":Error.success, "data": {"id":node.id, "peers":peers_data}}) | ||
| 1032 | - trace(res) | ||
| 1033 | - return res | ||
| 1034 | - finally: | ||
| 1035 | - self.__lock.release() | ||
| 1036 | - | ||
| 1037 | - def POST(self): | ||
| 1038 | - enable_crossdomain() | ||
| 1039 | - | ||
| 1040 | - try: | ||
| 1041 | - self.__lock.acquire() | ||
| 1042 | - | ||
| 1043 | - req = cherrypy.request.body.read() | ||
| 1044 | - trace("post to nodes, req=%s"%(req)) | ||
| 1045 | - try: | ||
| 1046 | - json_req = json.loads(req) | ||
| 1047 | - except Exception, ex: | ||
| 1048 | - code = Error.system_parse_json | ||
| 1049 | - trace("parse the request to json failed, req=%s, ex=%s, code=%s"%(req, ex, code)) | ||
| 1050 | - return json.dumps({"code":code, "data": None}) | ||
| 1051 | - | ||
| 1052 | - node = CdnNode() | ||
| 1053 | - node.ip = str(json_req["ip"]); | ||
| 1054 | - node.os = str(json_req["os"]); | ||
| 1055 | - if "origin" in json_req: | ||
| 1056 | - node.origin = str(json_req["origin"]); | ||
| 1057 | - node.srs_status = str(json_req["srs_status"]) | ||
| 1058 | - self.__nodes.append(node) | ||
| 1059 | - | ||
| 1060 | - self.__refresh_nodes() | ||
| 1061 | - peers = self.__get_peers(node) | ||
| 1062 | - peers_data = self.__json_dump_nodes(peers) | ||
| 1063 | - | ||
| 1064 | - res = json.dumps({"code":Error.success, "data": {"id":node.id, "peers":peers_data}}) | ||
| 1065 | - trace(res) | ||
| 1066 | - return res | ||
| 1067 | - finally: | ||
| 1068 | - self.__lock.release() | ||
| 1069 | - | ||
| 1070 | - def OPTIONS(self, *args, **kwargs): | ||
| 1071 | - enable_crossdomain() | ||
| 1072 | 646 | ||
| 1073 | global_chat_id = os.getpid(); | 647 | global_chat_id = os.getpid(); |
| 1074 | ''' | 648 | ''' |
| @@ -1235,7 +809,6 @@ class V1(object): | @@ -1235,7 +809,6 @@ class V1(object): | ||
| 1235 | self.proxy = RESTProxy() | 809 | self.proxy = RESTProxy() |
| 1236 | self.chats = RESTChats() | 810 | self.chats = RESTChats() |
| 1237 | self.servers = RESTServers() | 811 | self.servers = RESTServers() |
| 1238 | - self.nodes = RESTNodes() | ||
| 1239 | def GET(self): | 812 | def GET(self): |
| 1240 | enable_crossdomain(); | 813 | enable_crossdomain(); |
| 1241 | return json.dumps({"code":Error.success, "urls":{ | 814 | return json.dumps({"code":Error.success, "urls":{ |
| @@ -1244,26 +817,10 @@ class V1(object): | @@ -1244,26 +817,10 @@ class V1(object): | ||
| 1244 | "sessions": "for srs http callback, to handle the sessions requests: client play/stop stream", | 817 | "sessions": "for srs http callback, to handle the sessions requests: client play/stop stream", |
| 1245 | "dvrs": "for srs http callback, to handle the dvr requests: dvr stream.", | 818 | "dvrs": "for srs http callback, to handle the dvr requests: dvr stream.", |
| 1246 | "chats": "for srs demo meeting, the chat streams, public chat room.", | 819 | "chats": "for srs demo meeting, the chat streams, public chat room.", |
| 1247 | - "nodes": { | ||
| 1248 | - "summary": "for srs cdn node", | ||
| 1249 | - "POST ip=node_ip&os=node_os": "register a new node", | ||
| 1250 | - "GET": "get the active edge nodes", | ||
| 1251 | - "GET type=gslb&origin=demo.chnvideo.com": "get the gslb edge ip", | ||
| 1252 | - "GET type=hls&format=html&origin=demo.chnvideo.com&port=8080&stream=live/livestream": "get the play url, html for hls", | ||
| 1253 | - "GET type=rtmp&format=html&origin=demo.chnvideo.com&vhost=demo.srs.com&port=1935&stream=live/livestream": "get the play url, for rtmp" | ||
| 1254 | - }, | ||
| 1255 | "servers": { | 820 | "servers": { |
| 1256 | "summary": "for srs raspberry-pi and meeting demo", | 821 | "summary": "for srs raspberry-pi and meeting demo", |
| 1257 | "GET": "get the current raspberry-pi servers info", | 822 | "GET": "get the current raspberry-pi servers info", |
| 1258 | - "GET id=gslb&device_id=chnvideo-sales-arm": "get the gslb edge ip", | ||
| 1259 | - "POST ip=node_ip&device_id=device_id": "the new raspberry-pi server info.", | ||
| 1260 | - "GET id=ingest&action=play&stream=live/livestream": "play the ingest HLS stream on raspberry-pi", | ||
| 1261 | - "GET id=ingest&action=rtmp&stream=live/livestream": "play the ingest RTMP stream on raspberry-pi", | ||
| 1262 | - "GET id=ingest&action=hls&stream=live/livestream": "play the ingest HLS stream on raspberry-pi", | ||
| 1263 | - "GET id=ingest&action=mgmt": "open the HTTP api url of raspberry-pi", | ||
| 1264 | - "GET id=meeting": "redirect to local raspberry-pi meeting url(local ignored)", | ||
| 1265 | - "GET id=meeting&local=false&index=0": "play the first(index=0) meeting HLS stream on demo.chnvideo.com(not local)", | ||
| 1266 | - "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." | 823 | + "POST ip=node_ip&device_id=device_id": "the new raspberry-pi server info." |
| 1267 | } | 824 | } |
| 1268 | }}); | 825 | }}); |
| 1269 | def OPTIONS(self, *args, **kwargs): | 826 | def OPTIONS(self, *args, **kwargs): |
-
请 注册 或 登录 后发表评论