Created
May 2, 2013 19:33
-
-
Save 02strich/5504767 to your computer and use it in GitHub Desktop.
DLNA Proxy (including SSDP and Multicast)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import socket, thread, sys | |
| import logging | |
| BUFLEN = 1024 | |
| logger = logging.getLogger(__name__) | |
| class DLNAProxy(object): | |
| MEDIASERVER_IP = "" | |
| def __init__(self, connection, address, timeout): | |
| try: | |
| logger.debug("new connection handler") | |
| self.client = connection | |
| self.client_buffer = '' | |
| self.timeout = timeout | |
| # connect to target server | |
| (soc_family, _, _, _, address) = socket.getaddrinfo(self.MEDIASERVER_IP, 5001)[0] | |
| self.target = socket.socket(soc_family) | |
| self.target.connect(address) | |
| # get request | |
| request = "".join([part[1] for part in self.read_response(self.client)]) | |
| request2 = request.replace("192.168.178.001", self.MEDIASERVER_IP) | |
| logger.debug("--------------------------------------------") | |
| logger.debug(request) | |
| logger.debug("--------------------------------------------") | |
| # send request to target server | |
| self.target.send(request2) | |
| # read response | |
| for text_content, response_part in self.read_response(self.target): | |
| if text_content: | |
| self.client.send(response_part.replace(self.MEDIASERVER_IP, "192.168.178.001")) | |
| else: | |
| self.client.send(response_part) | |
| self.client.close() | |
| self.target.close() | |
| except: | |
| logger.exception("Something went wrong") | |
| def read_response(self, read_socket): | |
| buffer = "" | |
| socket_file = read_socket.makefile() | |
| content_length = 0 | |
| text_content = False | |
| while 1: | |
| line = socket_file.readline() | |
| buffer += line | |
| if "Content-Length" in line: | |
| content_length = int(line.split()[1]) | |
| if "Content-Type" in line: | |
| text_content = "text/xml" in line | |
| if line == "\r\n": | |
| break | |
| logger.debug("Read header: %d", content_length) | |
| yield True, buffer | |
| if content_length > 1024*1024: | |
| data_part = socket_file.read(8*1024) | |
| while data_part: | |
| yield text_content, data_part | |
| data_part = socket_file.read(8*1024) | |
| else: | |
| yield text_content, socket_file.read(content_length) | |
| class DLNAMulticastHelper(object): | |
| MCAST_GRP = '239.255.255.250' | |
| MCAST_PORT = 1900 | |
| def __init__(self, mediaserver_ip): | |
| self.mediaserver_ip = mediaserver_ip | |
| def run(self): | |
| sock_send = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) | |
| sock_send.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2) | |
| sock_send.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) | |
| sock_send.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton("192.168.178.1")) | |
| sock_recv = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) | |
| sock_recv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) | |
| sock_recv.setsockopt(socket.SOL_IP, socket.IP_ADD_MEMBERSHIP, socket.inet_aton(self.MCAST_GRP)+socket.inet_aton("192.168.179.1")) | |
| sock_recv.bind((self.MCAST_GRP, self.MCAST_PORT)) | |
| while True: | |
| dgram, addr = sock_recv.recvfrom(10240) | |
| dgram2 = dgram.replace(self.mediaserver_ip, "192.168.178.1") | |
| sock_send.sendto(dgram2, (self.MCAST_GRP, self.MCAST_PORT)) | |
| if __name__ == '__main__': | |
| logging.basicConfig() | |
| # start multicast helper | |
| multi_helper = DLNAMulticastHelper(sys.argv[1]) | |
| thread.start_new_thread(multi_helper.run, tuple()) | |
| # start HTTP proxy | |
| DLNAProxy.MEDIASERVER_IP = sys.argv[1] | |
| soc = socket.socket(socket.AF_INET) | |
| soc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) | |
| soc.bind(("192.168.178.1", 5001)) | |
| soc.listen(0) | |
| while 1: | |
| thread.start_new_thread(DLNAProxy, soc.accept()+(60,)) |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Assuming you have a different home network layout, you need to replace all references to 192.168.17[89].1 to IPs that fit your setup (those are the IPs used by the proxy not the server). Then you should be able to run this with python2 and providing the IP of your mediaserver as argument, e.g.
python2 dlna_proxy.py 192.168.200.10This had been developed on python2, so adjustments are needed to make it work on python3 (as the error you encountered confirms).