tiny-dlna 0.2.0__tar.gz → 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tiny-dlna
3
- Version: 0.2.0
3
+ Version: 0.4.0
4
4
  Summary: a tiny DLNA receiver
5
5
  Home-page: https://github.com/mitnk/tiny-dlna
6
6
  Author: mitnk
@@ -0,0 +1,30 @@
1
+ # Tiny DLNA
2
+
3
+ ## Install
4
+
5
+ ```
6
+ $ pip install tiny-dlna
7
+ ```
8
+
9
+ ## Tiny DLNA Render
10
+
11
+ Just to support subtitles.
12
+
13
+ ```
14
+ $ tiny-render
15
+ ```
16
+
17
+ This will activate a DLNA receiver named "Tiny Render", which can stream videos
18
+ from apps like 虎牙直播, Bilibili, and other video platforms. Additionally, you
19
+ can also use `nano-dlna` to play local videos (like in your RaspberryPi) on it.
20
+
21
+ > Note: [mpv](https://mpv.io/) needs to be installed on your system.
22
+
23
+ ## Tiny DLNA Cli
24
+
25
+ To do.
26
+
27
+ ## Related projects
28
+
29
+ - https://github.com/xfangfang/Macast
30
+ - https://github.com/gabrielmagno/nano-dlna
@@ -23,7 +23,7 @@ Usages
23
23
 
24
24
  setup(
25
25
  name='tiny-dlna',
26
- version='0.2.0',
26
+ version='0.4.0',
27
27
  description='a tiny DLNA receiver',
28
28
  long_description=DESC,
29
29
  url='https://github.com/mitnk/tiny-dlna',
@@ -1,24 +1,27 @@
1
+ import datetime
1
2
  import logging
2
3
  import socket
3
4
 
4
5
  SSDP_MULTICAST = '239.255.255.250'
5
6
  SSDP_PORT = 1900
6
- LOCATION = "http://192.168.1.228:5000/description.xml"
7
- USN = 'uuid:dlna-tiny-render-t001::upnp:rootdevice'
7
+ RENDER_PORT = 55000
8
+ LOCATION = f'http://192.168.1.228:{RENDER_PORT}/description.xml'
9
+ UUID = 'd095ee0c-7bed-43d0-bf98-f815496e8383'
10
+ logger = logging.getLogger('ssdp')
8
11
 
9
- ssdp_response = (
10
- 'HTTP/1.1 200 OK\r\n'
11
- 'CACHE-CONTROL: max-age=1800\r\n'
12
- 'EXT:\r\n'
13
- f'LOCATION: {LOCATION}\r\n'
14
- 'HOSTNAME: 192.168.1.228\r\n'
15
- 'SERVER: Custom/1.0 UPnP/1.0 DLNADOC/1.50\r\n'
16
- f'ST: urn:schemas-upnp-org:service:AVTransport:1\r\n'
17
- f'USN: {USN}\r\n'
18
- '\r\n'
19
- )
12
+ def build_m_search_response():
13
+ now = datetime.datetime.utcnow()
14
+ date_str = now.strftime("%a, %d %b %Y %H:%M:%S GMT")
20
15
 
21
- logger = logging.getLogger('ssdp')
16
+ text = 'HTTP/1.1 200 OK\r\n'
17
+ text += f'USN: uuid:{UUID}::urn:schemas-upnp-org:service:AVTransport:1\r\n'
18
+ text += f'Location: {LOCATION}\r\n'
19
+ text += 'ST: urn:schemas-upnp-org:service:AVTransport:1\r\n'
20
+ text += 'EXT: \r\n'
21
+ text += 'Server: Werkzeug/3.0.3 Python/3.11.0\r\n'
22
+ text += 'Cache-Control: max-age=70\r\n'
23
+ text += f'Date: {date_str}\r\n\r\n'
24
+ return text.encode('utf-8')
22
25
 
23
26
  def ssdp_listener():
24
27
  sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
@@ -33,7 +36,7 @@ def ssdp_listener():
33
36
  data, addr = sock.recvfrom(1024)
34
37
  if b'M-SEARCH' in data and b'ssdp:discover' in data:
35
38
  logger.info(f'Received M-SEARCH from {addr}, sending response...')
36
- sock.sendto(ssdp_response.encode('utf-8'), addr)
39
+ sock.sendto(build_m_search_response(), addr)
37
40
 
38
41
  if __name__ == '__main__':
39
42
  ssdp_listener()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tiny-dlna
3
- Version: 0.2.0
3
+ Version: 0.4.0
4
4
  Summary: a tiny DLNA receiver
5
5
  Home-page: https://github.com/mitnk/tiny-dlna
6
6
  Author: mitnk
@@ -7,11 +7,38 @@ import time
7
7
  import xml.etree.ElementTree as ET
8
8
 
9
9
  from flask import Flask, request, Response
10
- from ssdp import ssdp_listener
10
+ from ssdp import ssdp_listener, RENDER_PORT, UUID
11
11
 
12
12
  app = Flask(__name__)
13
13
  logger = logging.getLogger('tiny_render')
14
14
 
15
+
16
+ XML_DESC_PTN = """<?xml version="1.0" encoding="UTF-8"?>
17
+ <root xmlns:dlna="urn:schemas-dlna-org:device-1-0" xmlns="urn:schemas-upnp-org:device-1-0">
18
+ <specVersion>
19
+ <major>1</major>
20
+ <minor>0</minor>
21
+ </specVersion>
22
+ <device>
23
+ <deviceType>urn:schemas-upnp-org:device:MediaRenderer:1</deviceType>
24
+ <friendlyName>{}</friendlyName>
25
+ <manufacturer>mitnk</manufacturer>
26
+ <modelName>Tiny-Render</modelName>
27
+ <modelDescription>AVTransport Media Renderer</modelDescription>
28
+ <UDN>uuid:{}</UDN>
29
+ <dlna:X_DLNADOC xmlns:dlna="urn:schemas-dlna-org:device-1-0">DMR-1.50</dlna:X_DLNADOC>
30
+ <serviceList>
31
+ <service>
32
+ <serviceType>urn:schemas-upnp-org:service:AVTransport:1</serviceType>
33
+ <serviceId>urn:upnp-org:serviceId:AVTransport</serviceId>
34
+ <SCPDURL>AVTransport/scpd.xml</SCPDURL>
35
+ <controlURL>AVTransport/control</controlURL>
36
+ <eventSubURL>AVTransport/event</eventSubURL>
37
+ </service>
38
+ </serviceList>
39
+ </device>
40
+ </root>"""
41
+
15
42
  XML_AVSET_DONE = """
16
43
  <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
17
44
  <s:Body>
@@ -95,44 +122,8 @@ _DATA = {
95
122
 
96
123
  @app.route('/description.xml')
97
124
  def description():
98
- xml = """<?xml version="1.0"?>
99
- <root xmlns="urn:schemas-upnp-org:device-1-0" xmlns:dlna="urn:schemas-dlna-org:device-1-0">
100
- <specVersion>
101
- <major>1</major>
102
- <minor>0</minor>
103
- </specVersion>
104
- <device>
105
- <deviceType>urn:schemas-upnp-org:device:MediaRenderer:1</deviceType>
106
- <friendlyName>Tiny Render</friendlyName>
107
- <manufacturer>mitnk</manufacturer>
108
- <modelName>T001</modelName>
109
- <UDN>uuid:dlna-tiny-render-t001</UDN>
110
- <dlna:X_DLNADOC xmlns:dlna="urn:schemas-dlna-org:device-1-0">DMR-1.50</dlna:X_DLNADOC>
111
- <serviceList>
112
- <service>
113
- <serviceType>urn:schemas-upnp-org:service:AVTransport:1</serviceType>
114
- <serviceId>urn:upnp-org:serviceId:AVTransport</serviceId>
115
- <SCPDURL>AVTransport/82d8-eb72-b097/scpd.xml</SCPDURL>
116
- <controlURL>AVTransport/82d8-eb72-b097/control</controlURL>
117
- <eventSubURL>AVTransport/82d8-eb72-b097/event</eventSubURL>
118
- </service>
119
- <service>
120
- <serviceType>urn:schemas-upnp-org:service:ConnectionManager:1</serviceType>
121
- <serviceId>urn:upnp-org:serviceId:ConnectionManager</serviceId>
122
- <SCPDURL>ConnectionManager/82d8-eb72-b097/scpd.xml</SCPDURL>
123
- <controlURL>ConnectionManager/82d8-eb72-b097/control</controlURL>
124
- <eventSubURL>ConnectionManager/82d8-eb72-b097/event</eventSubURL>
125
- </service>
126
- <service>
127
- <serviceType>urn:schemas-upnp-org:service:RenderingControl:1</serviceType>
128
- <serviceId>urn:upnp-org:serviceId:RenderingControl</serviceId>
129
- <SCPDURL>RenderingControl/82d8-eb72-b097/scpd.xml</SCPDURL>
130
- <controlURL>RenderingControl/82d8-eb72-b097/control</controlURL>
131
- <eventSubURL>RenderingControl/82d8-eb72-b097/event</eventSubURL>
132
- </service>
133
- </serviceList>
134
- </device>
135
- </root>"""
125
+ friendly_name = app.config['FRIENDLY_NAME']
126
+ xml = XML_DESC_PTN.format(friendly_name, UUID)
136
127
  return Response(xml, mimetype="text/xml")
137
128
 
138
129
  def to_track_time(seconds):
@@ -199,7 +190,7 @@ def get_metadata(request):
199
190
  }
200
191
 
201
192
 
202
- @app.route('/AVTransport/82d8-eb72-b097/control', methods=['POST'])
193
+ @app.route('/AVTransport/control', methods=['POST'])
203
194
  def control():
204
195
  if is_setav(request):
205
196
  metadata = get_metadata(request)
@@ -260,9 +251,10 @@ class SSDPServer(threading.Thread):
260
251
  def main():
261
252
  import argparse
262
253
 
263
- parser = argparse.ArgumentParser(prog='tiny-dlna')
264
- parser.add_argument('--http-log', action='store_true')
265
- parser.add_argument('--verbose', '-v', action='store_true')
254
+ parser = argparse.ArgumentParser(prog='tiny-render')
255
+ parser.add_argument('--http-log', action='store_true', help='Enable server logs')
256
+ parser.add_argument('--verbose', '-v', action='store_true', help='Enable debug logs')
257
+ parser.add_argument('--name', type=str, default='Tiny Render', help='Change render name')
266
258
 
267
259
  args = parser.parse_args()
268
260
 
@@ -280,7 +272,11 @@ def main():
280
272
 
281
273
  ssdp = SSDPServer()
282
274
  ssdp.start()
283
- app.run(host="0.0.0.0", port=5000, debug=False)
275
+
276
+ friendly_name = args.name
277
+ app.config['FRIENDLY_NAME'] = friendly_name
278
+ logging.info(f'Starting DLNA Receiver: {friendly_name}')
279
+ app.run(host="0.0.0.0", port=RENDER_PORT, debug=False)
284
280
 
285
281
 
286
282
  if __name__ == "__main__":
tiny-dlna-0.2.0/README.md DELETED
@@ -1,13 +0,0 @@
1
- # Tiny DLNA Render
2
-
3
- Just to support subtitles.
4
-
5
- ```
6
- $ pip install tiny-dlna
7
- $ tiny-render
8
- ```
9
-
10
- ## Related projects
11
-
12
- - https://github.com/xfangfang/Macast
13
- - https://github.com/gabrielmagno/nano-dlna
File without changes