1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. Anuncie Aqui
    Anuncie aqui você Também: fdantas@4each.com.br

[Python] How to restream IPTV playlist with Nginx RTMP, FFmpeg, and Python without recording,...

Discussão em 'Python' iniciado por Stack, Abril 1, 2025.

  1. Stack

    Stack Membro Participativo

    I have an IPTV playlist from a provider that allows only one user to connect and watch. I want to restream this playlist through my own server without recording it and in a lightweight manner. I’m using Nginx RTMP, FFmpeg, and Python TCP for the setup, but I keep getting an HTTP 403 error when trying to access the stream.

    Here’s a summary of my setup:

    Nginx RTMP: Used for streaming.

    FFmpeg: Used to handle the video stream.

    Python TCP: Trying to handle the connection between my server and the IPTV source.

    #!/usr/bin/env python3

    import sys
    import socket
    import threading
    import requests
    import time

    def accept_connections(server_socket, clients, clients_lock):
    """
    Continuously accept new client connections, perform a minimal read of the
    client's HTTP request, send back a valid HTTP/1.1 response header, and
    add the socket to the broadcast list.
    """
    while True:
    client_socket, addr = server_socket.accept()
    print(f"[+] New client connected from {addr}")
    threading.Thread(
    target=handle_client,
    args=(client_socket, addr, clients, clients_lock),
    daemon=True
    ).start()

    def handle_client(client_socket, addr, clients, clients_lock):
    """
    Read the client's HTTP request minimally, send back a proper HTTP/1.1 200 OK header,
    and then add the socket to our broadcast list.
    """
    try:
    # Read until we reach the end of the request headers
    request_data = b""
    while b"\r\n\r\n" not in request_data:
    chunk = client_socket.recv(1024)
    if not chunk:
    break
    request_data += chunk

    # Send a proper HTTP response header to satisfy clients like curl
    response_header = (
    "HTTP/1.1 200 OK\r\n"
    "Content-Type: application/octet-stream\r\n"
    "Connection: close\r\n"
    "\r\n"
    )
    client_socket.sendall(response_header.encode("utf-8"))

    with clients_lock:
    clients.append(client_socket)
    print(f"[+] Client from {addr} is ready to receive stream.")
    except Exception as e:
    print(f"[!] Error handling client {addr}: {e}")
    client_socket.close()

    def read_from_source_and_broadcast(source_url, clients, clients_lock):
    """
    Continuously connect to the source URL (following redirects) using custom headers
    so that it mimics a curl-like request. In case of connection errors (e.g. connection reset),
    wait a bit and then try again.

    For each successful connection, stream data in chunks and broadcast each chunk
    to all connected clients.
    """
    # Set custom headers to mimic curl
    headers = {
    "User-Agent": "curl/8.5.0",
    "Accept": "*/*"
    }

    while True:
    try:
    print(f"[+] Fetching from source URL (with redirects): {source_url}")
    with requests.get(source_url, stream=True, allow_redirects=True, headers=headers) as resp:
    if resp.status_code >= 400:
    print(f"[!] Got HTTP {resp.status_code} from the source. Retrying in 5 seconds.")
    time.sleep(5)
    continue

    # Stream data and broadcast each chunk
    for chunk in resp.iter_content(chunk_size=4096):
    if not chunk:
    continue
    with clients_lock:
    for c in clients[:]:
    try:
    c.sendall(chunk)
    except Exception as e:
    print(f"[!] A client disconnected or send failed: {e}")
    c.close()
    clients.remove(c)
    except requests.exceptions.RequestException as e:
    print(f"[!] Source connection error, retrying in 5 seconds: {e}")
    time.sleep(5)

    def main():
    if len(sys.argv) != 3:
    print(f"Usage: {sys.argv[0]} <source_url> <port>")
    sys.exit(1)

    source_url = sys.argv[1]
    port = int(sys.argv[2])

    # Create a TCP socket to listen for incoming connections
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_socket.bind(("0.0.0.0", port))
    server_socket.listen(5)
    print(f"[+] Listening on port {port}...")

    # List of currently connected client sockets
    clients = []
    clients_lock = threading.Lock()

    # Start a thread to accept incoming client connections
    t_accept = threading.Thread(
    target=accept_connections,
    args=(server_socket, clients, clients_lock),
    daemon=True
    )
    t_accept.start()

    # Continuously read from the source URL and broadcast to connected clients
    read_from_source_and_broadcast(source_url, clients, clients_lock)

    if __name__ == "__main__":
    main()


    When i write command python3 proxy_server.py 'http://channelurl' 9999 I getting error.

    [+] Listening on port 9999...
    [+] Fetching from source URL (with redirects): http://ate91060.cdn-akm.me:80/dc31a19e5a6a/fc5e38e28e/325973
    [!] Got HTTP 403 from the source. Retrying in 5 seconds.
    ^CTraceback (most recent call last):
    File "/home/namepirate58/nginx-1.23.1/proxy_server.py", line 127, in <module>
    main()
    File "/home/namepirate58/nginx-1.23.1/proxy_server.py", line 124, in main
    read_from_source_and_broadcast(source_url, clients, clients_lock)
    File "/home/namepirate58/nginx-1.23.1/proxy_server.py", line 77, in read_from_source_and_broadcast
    time.sleep(5)
    KeyboardInterrupt

    Continue reading...

Compartilhe esta Página