Added support for origin and referer headers

This commit is contained in:
2025-02-25 22:29:08 -06:00
parent b102f1eeb4
commit e74d99004f
2 changed files with 49 additions and 11 deletions

View File

@@ -44,7 +44,27 @@
"id": "9", "id": "9",
"name": "Rai News 24", "name": "Rai News 24",
"url": "https://cachehsi1a.netplus.ch/live/eds/rainews/browser-dash/rainews.mpd" "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"
} }
] ]
} }

View File

@@ -35,11 +35,14 @@ def load_channels():
with open(channels_path, 'r') as f: with open(channels_path, 'r') as f:
return {str(c['id']): c for c in json.load(f)['channels']} 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. 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', 'streamlink',
'--ffmpeg-fout', 'mpegts', '--ffmpeg-fout', 'mpegts',
'--hls-live-restart', '--hls-live-restart',
@@ -48,22 +51,30 @@ async def generate_streamlink_process(url) -> Process:
'--hls-playlist-reload-attempts', '3', '--hls-playlist-reload-attempts', '3',
'--stream-segment-threads', '3', '--stream-segment-threads', '3',
'--ringbuffer-size', '32M', '--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, stdout=subprocess.PIPE,
stderr=subprocess.PIPE stderr=subprocess.PIPE
) )
return process return process
async def stream_generator(process: Process, url: str): async def stream_generator(process: Process, url: str, headers=None):
"""Generate streaming content asynchronously""" """Generate streaming content asynchronously"""
CHUNK_SIZE = 32768 CHUNK_SIZE = 32768
try: try:
while True: while True:
if process.returncode is not None: if process.returncode is not None:
# Process has terminated, restart it # Process has terminated, restart it
process = await generate_streamlink_process(url) process = await generate_streamlink_process(url, headers)
continue continue
try: try:
@@ -79,7 +90,7 @@ async def stream_generator(process: Process, url: str):
process.terminate() process.terminate()
except: except:
pass pass
process = await generate_streamlink_process(url) process = await generate_streamlink_process(url, headers)
finally: finally:
try: try:
process.terminate() process.terminate()
@@ -105,10 +116,17 @@ async def stream_channel(channel_id: str, auth: bool = Depends(verify_credential
channel = channels[channel_id] channel = channels[channel_id]
url = channel['url'] 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: try:
process = await generate_streamlink_process(url) process = await generate_streamlink_process(url, headers if headers else None)
return StreamingResponse( return StreamingResponse(
stream_generator(process, url), stream_generator(process, url, headers if headers else None),
media_type='video/mp2t' media_type='video/mp2t'
) )
except Exception as e: except Exception as e: