VideoHelp Forum




+ Reply to Thread
Results 1 to 7 of 7
  1. Hi guys. I have a cable operator who also offers access to its iptv channels via Android app. I've managed to determine the logic of obtaining mpd (m3u8) links but the problem is they are protected by x-play-auth header. The header changes with every channel change and so far I've managed to play them using a python script with streamlink in Windows but I have to manually enter the channel number. Is there any way I can set up a proxy to serve the links with appropriate header so that I can use mpd (m3u8) list in TiviMate for example? The working way so far is:
    Code:
    streamlink --http-header x-play-auth="hash-xxxyyyzzzddd..." "https://xxx.yyy.ddd/channel/index.m3u8" best
    Quote Quote  
  2. Hello, first of all you can use the m3u or xtreamcode file in python to download just the live stream, series or video from python I did it in vb.net to download movies or series.
    Quote Quote  
  3. I need it for streaming because its legal ott. The streams don't have DRM but they are protected with x-play-auth header.
    Quote Quote  
  4. With some research, here's a version of how to get the x_play_auth of the channel plus using the TiviMate app:
    1) Login / session creation
    2) Request “play channel” API
    3) API response returns:
    - play_url (m3u8)
    - x-play-auth
    4) Request M3U8 with x-play-auth header
    HTTP request
    POST /api/play
    Authorization: Bearer <access_token>
    Content-Type: application/json

    {
    "channel_id": 101,
    "device_id": "android_tv",
    "profile": "ott"
    }
    API response
    {
    "play_url": "https://xxx.yyy.ddd/channel/index.m3u8",
    "x_play_auth": "hash-xxxyyyzzzddd",
    "expires_in": 30
    }
    Python example (generic)
    Code:
    import requests
    
    API_PLAY = "https://api.xxx.yyy.ddd/play"
    
    def get_x_play_auth(channel_id, access_token):
        headers = {
            "Authorization": f"Bearer {access_token}",
            "Content-Type": "application/json",
            "User-Agent": "AndroidTV"
        }
    
        payload = {
            "channel_id": channel_id,
            "device_id": "android_tv",
            "profile": "ott"
        }
    
        r = requests.post(API_PLAY, headers=headers, json=payload)
        r.raise_for_status()
    
        data = r.json()
        return data["x_play_auth"]
    
    
    x_play_auth = get_x_play_auth(101, ACCESS_TOKEN)
    Code:
    streamlink --http-header x-play-auth=<token> <m3u8> best
    Check the Android app network traffic
    • Look for endpoints named:
    • /play
    • /stream
    • /watch
    • /channel
    • Inspect JSON responses or headers

    The token is returned, not computed.
    Quote Quote  
  5. I've made a python script which lists channels and enables me to type in a channel number and the channel plays fine using the streamlink command. What I'm looking for is to be able to have a full list of channels in tivimate instead of having to type in channel numbers.
    Quote Quote  
  6. You expose a static M3U playlist to TiviMate, and your Python code:
    receives channel requests
    generates x-play-auth
    launches Streamlink (or proxies HLS)
    returns the stream
    Architecture (what actually works)
    TiviMate
    |
    | http://PC-IP:8080/ch/101
    v
    Python Proxy
    |
    | streamlink + x-play-auth
    v
    OTT Provider
    Static M3U playlist for TiviMate
    Create playlist.m3u:
    #EXTM3U
    #EXTINF:-1 tvg-id="101",Channel 1
    http://YOUR_PC_IP:8080/ch/101
    #EXTINF:-1 tvg-id="102",Channel 2
    http://YOUR_PC_IP:8080/ch/102
    #EXTINF:-1 tvg-id="103",Channel 3
    http://YOUR_PC_IP:8080/ch/103
    ..etc
    Python proxy using Streamlink
    1. starts Streamlink when TiviMate requests a channel
      injects x-play-auth
      streams back to TiviMate

    Code:
    from fastapi import FastAPI
    from fastapi.responses import StreamingResponse
    import subprocess
    import time
    
    app = FastAPI()
    
    CHANNEL_URL = "https://xxx.yyy.ddd/channel/index.m3u8"
    
    def get_x_play_auth(channel_id):
        # YOUR existing working logic
        return generate_token(channel_id)
    
    @app.get("/ch/{channel_id}")
    def play_channel(channel_id: int):
        auth = get_x_play_auth(channel_id)
    
        cmd = [
            "streamlink",
            "--http-header", f"x-play-auth={auth}",
            CHANNEL_URL,
            "best",
            "-O"  # output to stdout
        ]
    
        proc = subprocess.Popen(
            cmd,
            stdout=subprocess.PIPE,
            stderr=subprocess.DEVNULL
        )
    
        def stream():
            try:
                while True:
                    data = proc.stdout.read(8192)
                    if not data:
                        break
                    yield data
            finally:
                proc.terminate()
    
        return StreamingResponse(
            stream(),
            media_type="video/MP2T"
        )
    
    Run it:
    uvicorn proxy:app --host 0.0.0.0 --port 8080
    Quote Quote  
  7. Thank you.
    With your pointers and the help of Copilot AI, I was able to accomplish what I needed.
    Quote Quote  



Similar Threads

Visit our sponsor! Try DVDFab and backup Blu-rays!