|
4 | 4 | This module provides the HTTP request handler for a DLNA media server, |
5 | 5 | implementing the necessary DLNA and UPnP protocols for media streaming. |
6 | 6 | """ |
| 7 | + |
7 | 8 | import html |
8 | 9 | import traceback |
9 | 10 | import os |
| 11 | +import socket |
10 | 12 | import struct |
11 | 13 | import subprocess |
12 | 14 | import uuid |
@@ -116,6 +118,11 @@ def setup(self): |
116 | 118 | super().setup() |
117 | 119 | # Set socket timeout to prevent hanging connections |
118 | 120 | self.connection.settimeout(self.timeout) |
| 121 | + # Set TCP_NODELAY on the socket |
| 122 | + self.connection.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) |
| 123 | + buffer_size = 32 * 1024 * 1024 # 32MB buffer |
| 124 | + self.connection.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, buffer_size) |
| 125 | + self.connection.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, buffer_size) |
119 | 126 |
|
120 | 127 | def log_message(self, format, *args): # pylint: disable=redefined-builtin |
121 | 128 | """Override BaseHTTPRequestHandler's log_message to only log when verbose mode is enabled""" |
@@ -843,7 +850,7 @@ def serve_media_file(self, filename, head_only=False): |
843 | 850 | if self.verbose: |
844 | 851 | print(f"MEDIA ACCESS: {self.path} from {client_addr}") |
845 | 852 | print(f"MEDIA HEADERS: {dict(self.headers)}") |
846 | | - |
| 853 | + |
847 | 854 | # Set the current playing file for DLNA clients |
848 | 855 | # Get filename after the last slash for display |
849 | 856 | self.now_playing = os.path.basename(decoded_filename) |
@@ -985,9 +992,7 @@ def serve_media_file(self, filename, head_only=False): |
985 | 992 | try: |
986 | 993 | with open(file_path, "rb") as f: |
987 | 994 | # Use larger chunks for better performance with large files |
988 | | - chunk_size = ( |
989 | | - 65536 # 64KB chunks for better streaming performance |
990 | | - ) |
| 995 | + chunk_size = 512 * 1024 # 512KB chunks |
991 | 996 |
|
992 | 997 | # Set a timeout for socket operations to prevent blocking |
993 | 998 | self.wfile.flush() |
@@ -1138,7 +1143,7 @@ def handle_range_request(self, file_path, file_size, mime_type, range_header): |
1138 | 1143 |
|
1139 | 1144 | # Use smaller chunks for range requests to improve resume/seek performance |
1140 | 1145 | # Large chunks can cause choppy playback when resuming video |
1141 | | - base_chunk_size = 8192 # 8KB base chunk size for range requests |
| 1146 | + base_chunk_size = 512 * 1024 # 512KB |
1142 | 1147 |
|
1143 | 1148 | while remaining > 0: |
1144 | 1149 | # For range requests, use smaller chunks for better streaming |
@@ -2049,8 +2054,10 @@ def _get_media_duration(self, file_path, mime_type): |
2049 | 2054 | } |
2050 | 2055 |
|
2051 | 2056 | # Try to get duration using ffprobe if available (skip if fast mode is enabled) |
2052 | | - if not self.fast and mime_type and ( |
2053 | | - mime_type.startswith("video/") or mime_type.startswith("audio/") |
| 2057 | + if ( |
| 2058 | + not self.fast |
| 2059 | + and mime_type |
| 2060 | + and (mime_type.startswith("video/") or mime_type.startswith("audio/")) |
2054 | 2061 | ): |
2055 | 2062 | try: |
2056 | 2063 | # Try ffprobe first (most reliable) |
|
0 commit comments