diff --git a/data/channels.json b/data/channels.json index d56ce6e..598d748 100644 --- a/data/channels.json +++ b/data/channels.json @@ -44,7 +44,27 @@ "id": "9", "name": "Rai News 24", "url": "https://cachehsi1a.netplus.ch/live/eds/rainews/browser-dash/rainews.mpd" + }, + { + "id": "10", + "name": "Rai Sport", + "url": "https://m3u.iranvids.com/rai-sport01/output.m3u8", + "origin": "https://babaktv.com", + "referer": "https://babaktv.com" + }, + { + "id": "11", + "name": "Rai Premium", + "url": "https://m3u.iranvids.com/rai-premium/output.m3u8", + "origin": "https://babaktv.com", + "referer": "https://babaktv.com" + }, + { + "id": "12", + "name": "Rai Movie", + "url": "https://m3u.iranvids.com/rai-movie/output.m3u8", + "origin": "https://babaktv.com", + "referer": "https://babaktv.com" } - ] } \ No newline at end of file diff --git a/src/stream_link_server.py b/src/stream_link_server.py index 9565a52..653d91d 100644 --- a/src/stream_link_server.py +++ b/src/stream_link_server.py @@ -35,11 +35,14 @@ def load_channels(): with open(channels_path, 'r') as f: return {str(c['id']): c for c in json.load(f)['channels']} -async def generate_streamlink_process(url) -> Process: +async def generate_streamlink_process(url, headers=None) -> Process: """ Run Streamlink as an async subprocess and pipe its output to the response. + Args: + url: Stream URL + headers: Optional dict of HTTP headers """ - process = await create_subprocess_exec( + cmd = [ 'streamlink', '--ffmpeg-fout', 'mpegts', '--hls-live-restart', @@ -48,22 +51,30 @@ async def generate_streamlink_process(url) -> Process: '--hls-playlist-reload-attempts', '3', '--stream-segment-threads', '3', '--ringbuffer-size', '32M', - '--stdout', - url, - 'best', + ] + + # Add headers if specified + if headers: + for key, value in headers.items(): + cmd.extend(['--http-header', f'{key}={value}']) + + cmd.extend(['--stdout', url, 'best']) + + process = await create_subprocess_exec( + *cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) return process -async def stream_generator(process: Process, url: str): +async def stream_generator(process: Process, url: str, headers=None): """Generate streaming content asynchronously""" CHUNK_SIZE = 32768 try: while True: if process.returncode is not None: # Process has terminated, restart it - process = await generate_streamlink_process(url) + process = await generate_streamlink_process(url, headers) continue try: @@ -79,7 +90,7 @@ async def stream_generator(process: Process, url: str): process.terminate() except: pass - process = await generate_streamlink_process(url) + process = await generate_streamlink_process(url, headers) finally: try: process.terminate() @@ -105,10 +116,17 @@ async def stream_channel(channel_id: str, auth: bool = Depends(verify_credential channel = channels[channel_id] url = channel['url'] + # Build headers dict only including specified headers + headers = {} + if 'origin' in channel: + headers['Origin'] = channel['origin'] + if 'referer' in channel: + headers['Referer'] = channel['referer'] + try: - process = await generate_streamlink_process(url) + process = await generate_streamlink_process(url, headers if headers else None) return StreamingResponse( - stream_generator(process, url), + stream_generator(process, url, headers if headers else None), media_type='video/mp2t' ) except Exception as e: