This commit is contained in:
Nirvana
2026-01-24 13:34:29 +01:00
parent f192504fc6
commit b65ed4e1f0
4 changed files with 68 additions and 67 deletions
+14 -13
View File
@@ -13,21 +13,22 @@ LIB_PATH = os.path.join(app_dir, "lib")
if os.path.exists(LIB_PATH) and LIB_PATH not in sys.path:
sys.path.insert(0, LIB_PATH)
from .cache import setup_cache_routes
from .config import setup_config_routes
from .drm import setup_drm_routes
from .epg import setup_epg_routes
from .m3u import setup_m3u_routes
# Now import the route setup functions
from .providers import setup_provider_routes
from .streams import setup_stream_routes
from .m3u import setup_m3u_routes
from .drm import setup_drm_routes
from .cache import setup_cache_routes
from .config import setup_config_routes
from .epg import setup_epg_routes
__all__ = [
'setup_provider_routes',
'setup_stream_routes',
'setup_m3u_routes',
'setup_drm_routes',
'setup_cache_routes',
'setup_config_routes',
'setup_epg_routes'
]
"setup_provider_routes",
"setup_stream_routes",
"setup_m3u_routes",
"setup_drm_routes",
"setup_cache_routes",
"setup_config_routes",
"setup_epg_routes",
]
+2 -2
View File
@@ -289,8 +289,8 @@ def setup_m3u_routes(app, manager, service):
except:
provider_label = provider_name
# Build stream URL
stream_url = f"{base_url}/api/providers/{provider_name}/channels/{channel_id}/stream"
# Build stream URL with /index.mpd
stream_url = f"{base_url}/api/providers/{provider_name}/channels/{channel_id}/stream/index.mpd"
# Add M3U entry
m3u_content += f'#EXTINF:-1 tvg-id="{channel_id}" tvg-logo="{channel_logo}" group-title="{provider_label}",{channel_name}\n'
+6 -6
View File
@@ -20,9 +20,7 @@ def setup_stream_routes(app, manager, service):
try:
# Build the stream URL (which will handle both proxy and non-proxy)
base_url = f"{request.urlparts.scheme}://{request.urlparts.netloc}"
stream_url = (
f"{base_url}/api/providers/{provider}/channels/{channel_id}/stream"
)
stream_url = f"{base_url}/api/providers/{provider}/channels/{channel_id}/stream/index.mpd"
# Add country parameter if provided
country = request.query.get("country")
@@ -32,7 +30,7 @@ def setup_stream_routes(app, manager, service):
return {
"provider": provider,
"channel_id": channel_id,
"manifest_url": stream_url, # Always point to /stream endpoint
"manifest_url": stream_url, # Now points to /stream/index.mpd endpoint
}
except ValueError as val_err:
@@ -48,7 +46,7 @@ def setup_stream_routes(app, manager, service):
response.status = 500
return {"error": f"Internal server error: {str(api_err)}"}
@app.route("/api/providers/<provider>/channels/<channel_id>/stream")
@app.route("/api/providers/<provider>/channels/<channel_id>/stream/index.mpd")
def get_channel_stream(provider, channel_id):
"""
Returns HTTP 302 redirect to the actual manifest or rewritten manifest endpoint.
@@ -330,7 +328,9 @@ def setup_stream_routes(app, manager, service):
response.status = 500
return {"error": f"Internal server error: {str(api_err)}"}
@app.route("/api/providers/<provider>/channels/<channel_id>/stream/decrypted")
@app.route(
"/api/providers/<provider>/channels/<channel_id>/stream/decrypted/index.mpd"
)
def get_channel_stream_decrypted(provider, channel_id):
"""
Returns rewritten manifest for decrypted playback via media proxy.
+46 -46
View File
@@ -585,9 +585,9 @@ class UltimateService:
channel_name = channel.name
channel_logo = channel.logo_url or ""
# Build stream URL
# Build stream URL with /index.mpd
stream_url = (
f"{base_url}/api/providers/{provider_name}/channels/{channel_id}/stream"
f"{base_url}/api/providers/{provider_name}/channels/{channel_id}/stream/index.mpd"
)
# Get provider instance to access provider_label
@@ -621,6 +621,50 @@ class UltimateService:
return entry_content
@staticmethod
def _generate_m3u_decrypted_channel_entry(
base_url,
provider_name,
provider_label,
channel,
clearkey_data,
provider_proxy_url,
):
"""
Generate M3U entry for a ClearKey encrypted channel with decryption URL.
Args:
base_url: Base URL for stream endpoints
provider_name: Name of the provider
provider_label: Display label for the provider
channel: StreamingChannel object
clearkey_data: ClearKey DRM data
provider_proxy_url: Optional provider proxy URL
Returns:
M3U entry as string
"""
entry_content = ""
channel_id = channel.channel_id
channel_name = channel.name
channel_logo = channel.logo_url or ""
# Build decrypted stream URL via media proxy with /index.mpd
# Format: /api/providers/{provider}/channels/{channel_id}/stream/decrypted/index.mpd
stream_url = f"{base_url}/api/providers/{provider_name}/channels/{channel_id}/stream/decrypted/index.mpd"
# Add M3U entry with extended info
entry_content += f'#EXTINF:-1 tvg-id="{channel_id}" tvg-logo="{channel_logo}" group-title="{provider_label}",{channel_name}\n'
# Add KODIPROP for inputstream.adaptive (still needed for DASH playback)
entry_content += "#KODIPROP:inputstream=inputstream.adaptive\n"
# Add stream URL
entry_content += f"{stream_url}\n"
return entry_content
def _generate_m3u_decrypted_content(
self, providers=None, save_to_cache=True, cache_filename=None
):
@@ -765,50 +809,6 @@ class UltimateService:
return m3u_content
def _generate_m3u_decrypted_channel_entry(
self,
base_url,
provider_name,
provider_label,
channel,
clearkey_data,
provider_proxy_url,
):
"""
Generate M3U entry for a ClearKey encrypted channel with decryption URL.
Args:
base_url: Base URL for stream endpoints
provider_name: Name of the provider
provider_label: Display label for the provider
channel: StreamingChannel object
clearkey_data: ClearKey DRM data
provider_proxy_url: Optional provider proxy URL
Returns:
M3U entry as string
"""
entry_content = ""
channel_id = channel.channel_id
channel_name = channel.name
channel_logo = channel.logo_url or ""
# Build decrypted stream URL via media proxy
# Format: /api/providers/{provider}/channels/{channel_id}/stream/decrypted
stream_url = f"{base_url}/api/providers/{provider_name}/channels/{channel_id}/stream/decrypted"
# Add M3U entry with extended info
entry_content += f'#EXTINF:-1 tvg-id="{channel_id}" tvg-logo="{channel_logo}" group-title="{provider_label}",{channel_name}\n'
# Add KODIPROP for inputstream.adaptive (still needed for DASH playback)
entry_content += "#KODIPROP:inputstream=inputstream.adaptive\n"
# Add stream URL
entry_content += f"{stream_url}\n"
return entry_content
def _generate_m3u_decrypted_all(self, save_to_cache: bool = False) -> str:
"""Internal method to generate decrypted M3U for all providers."""
logger.info("Generating decrypted M3U playlist for all providers")