Added Docker files, and removed RTMP server additions, added NGinx files (didn't added source NGinx files, docker will add them)
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,2 +1,3 @@
|
|||||||
hls
|
hls
|
||||||
venv/
|
venv/
|
||||||
|
sockets
|
||||||
17
core/Dockerfile
Normal file
17
core/Dockerfile
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
FROM python:3.10
|
||||||
|
|
||||||
|
# Set working directory
|
||||||
|
WORKDIR /core
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
COPY requirements.txt requirements.txt
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
# Copy application code
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Expose Flask's port
|
||||||
|
EXPOSE 5000
|
||||||
|
|
||||||
|
# Start the Flask app
|
||||||
|
CMD ["python", "app.py"]
|
||||||
1
database/requirements.txt
Normal file
1
database/requirements.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
flask
|
||||||
22
docker-compose.yml
Normal file
22
docker-compose.yml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
version: '3.9'
|
||||||
|
services:
|
||||||
|
nginx:
|
||||||
|
build:
|
||||||
|
context: ./nginx
|
||||||
|
ports:
|
||||||
|
- "1935:1935" # RTMP
|
||||||
|
depends_on:
|
||||||
|
- flask
|
||||||
|
networks:
|
||||||
|
- app_network
|
||||||
|
|
||||||
|
flask:
|
||||||
|
build:
|
||||||
|
context: ./core
|
||||||
|
ports:
|
||||||
|
- "5000:5000"
|
||||||
|
networks:
|
||||||
|
- app_network
|
||||||
|
|
||||||
|
networks:
|
||||||
|
app_network:
|
||||||
26
nginx/Dockerfile
Normal file
26
nginx/Dockerfile
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
FROM ubuntu:22.04
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
build-essential \
|
||||||
|
libpcre3 libpcre3-dev \
|
||||||
|
libssl-dev \
|
||||||
|
zlib1g-dev \
|
||||||
|
wget git
|
||||||
|
|
||||||
|
# Download and build NGINX with RTMP
|
||||||
|
RUN wget http://nginx.org/download/nginx-1.25.2.tar.gz && \
|
||||||
|
tar -xzvf nginx-1.25.2.tar.gz && \
|
||||||
|
git clone https://github.com/arut/nginx-rtmp-module.git && \
|
||||||
|
cd nginx-1.25.2 && \
|
||||||
|
./configure --add-module=../nginx-rtmp-module --with-http_ssl_module && \
|
||||||
|
make && make install
|
||||||
|
|
||||||
|
# Copy custom NGINX configuration
|
||||||
|
COPY nginx.conf /etc/nginx/nginx.conf
|
||||||
|
|
||||||
|
# Expose RTMP and HTTP ports
|
||||||
|
EXPOSE 1935
|
||||||
|
|
||||||
|
# Start NGINX
|
||||||
|
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
|
||||||
12
nginx/nginx.conf
Normal file
12
nginx/nginx.conf
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
rtmp {
|
||||||
|
server {
|
||||||
|
listen 1935;
|
||||||
|
chunk_size 4096;
|
||||||
|
|
||||||
|
application live {
|
||||||
|
live on;
|
||||||
|
record off;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
import socket, threading, os, time, traceback, struct
|
|
||||||
|
|
||||||
class RTMPClientState:
|
|
||||||
"""Enumeration of RTMP client states."""
|
|
||||||
EPOCH = 0
|
|
||||||
|
|
||||||
class RTMPServer:
|
|
||||||
def __init__(self, host='192.168.1.15', port=1935):
|
|
||||||
self.host = host
|
|
||||||
self.port = port
|
|
||||||
self.server_socket = None
|
|
||||||
self.is_running = True
|
|
||||||
self.clients = []
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
"""Starts a basic server to display incoming packets."""
|
|
||||||
# Create a TCP socket
|
|
||||||
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
self.server_socket.bind((self.host, self.port))
|
|
||||||
self.server_socket.listen(1)
|
|
||||||
print(f"RTMP Server started on {self.host}:{self.port}. Waiting for connections...")
|
|
||||||
|
|
||||||
while self.is_running:
|
|
||||||
try:
|
|
||||||
client_socket, address = self.server_socket.accept()
|
|
||||||
print(f"Connection accepted from {address}")
|
|
||||||
client_thread = threading.Thread(target=self.handle_client, args=(client_socket,))
|
|
||||||
client_thread.daemon = True
|
|
||||||
client_thread.start()
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error accepting connection: {e}")
|
|
||||||
print(traceback.format_exc())
|
|
||||||
break
|
|
||||||
|
|
||||||
def handle_client(self, client_socket):
|
|
||||||
"""
|
|
||||||
Handle an incoming RTMP client connection.
|
|
||||||
|
|
||||||
:param client_socket: The client socket object.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
# Perform RTMP handshake
|
|
||||||
if not self._attempt_handshake(client_socket):
|
|
||||||
print("Handshake failed.")
|
|
||||||
client_socket.close()
|
|
||||||
return
|
|
||||||
|
|
||||||
print("Handshake successful. Ready to handle RTMP stream.")
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error handling client: {e}")
|
|
||||||
print(traceback.format_exc())
|
|
||||||
finally:
|
|
||||||
client_socket.close()
|
|
||||||
|
|
||||||
def _attempt_handshake(self, client_socket):
|
|
||||||
"""Performs the RTMP handshake with the client."""
|
|
||||||
# Receive C0 and C1 packets and validate
|
|
||||||
c0 = int.from_bytes(client_socket.recv(1))
|
|
||||||
if c0 != 3:
|
|
||||||
print("Invalid RTMP version.")
|
|
||||||
return False
|
|
||||||
|
|
||||||
c1 = client_socket.recv(1536)
|
|
||||||
time_epoch = int.from_bytes(c1[:4])
|
|
||||||
zeros = int.from_bytes(c1[4:8])
|
|
||||||
random_bytes = c1[8:]
|
|
||||||
|
|
||||||
if zeros != 0:
|
|
||||||
print("Invalid C1 packet.")
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Send S0
|
|
||||||
s0 = bytes([3])
|
|
||||||
client_socket.send(s0)
|
|
||||||
|
|
||||||
# Send S1
|
|
||||||
s1 = bytearray(c1)
|
|
||||||
server_random = os.urandom(1528)
|
|
||||||
current_timestamp = struct.pack(">I" ,int(time.time()))
|
|
||||||
s1[:4] = current_timestamp
|
|
||||||
s1[8:] = server_random
|
|
||||||
client_socket.send(bytes(s1))
|
|
||||||
|
|
||||||
# Receive C2
|
|
||||||
c2 = client_socket.recv(1536)
|
|
||||||
if c2[8:] != server_random:
|
|
||||||
print("Invalid C2 packet.")
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# debug
|
|
||||||
print(f"Version: {c0}")
|
|
||||||
print(f"Epoch time: {time_epoch}")
|
|
||||||
print(f"Zeros: {zeros}")
|
|
||||||
#print(f"Random bytes: {random_bytes}")
|
|
||||||
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
"""
|
|
||||||
Stop the RTMP server.
|
|
||||||
"""
|
|
||||||
self.is_running = False
|
|
||||||
if self.server_socket:
|
|
||||||
self.server_socket.close()
|
|
||||||
print("RTMP Server stopped.")
|
|
||||||
|
|
||||||
|
|
||||||
def start_rtmp_server(host='127.0.0.1', port=1935):
|
|
||||||
"""Starts a basic RTMP server to display incoming packets."""
|
|
||||||
try:
|
|
||||||
# Create a TCP socket
|
|
||||||
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
server_socket.bind((host, port))
|
|
||||||
server_socket.listen(1)
|
|
||||||
print(f"RTMP server started on {host}:{port}. Waiting for connections...")
|
|
||||||
|
|
||||||
# Accept a connection
|
|
||||||
conn, addr = server_socket.accept()
|
|
||||||
print(f"Connection established with {addr}")
|
|
||||||
|
|
||||||
while True:
|
|
||||||
# Receive RTMP C0 and C1 packets
|
|
||||||
data = conn.recv(1)
|
|
||||||
if not data:
|
|
||||||
print("Connection closed by client.")
|
|
||||||
break
|
|
||||||
|
|
||||||
# Display the received RTMP packets
|
|
||||||
print(f"Version: {int.from_bytes(data)}")
|
|
||||||
break
|
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("\nServer shutting down.")
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error: {e}")
|
|
||||||
finally:
|
|
||||||
server_socket.close()
|
|
||||||
print("Server socket closed.")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
c = RTMPServer()
|
|
||||||
try:
|
|
||||||
c.start()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("Shutting down RTMP Server...")
|
|
||||||
c.stop()
|
|
||||||
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
from subprocess import Popen, PIPE
|
|
||||||
|
|
||||||
def generate_stream(STREAM_PATH, STREAM_NAME):
|
|
||||||
"""Function to run FFmpeg to convert the stream and create HLS"""
|
|
||||||
# FFmpeg command to receive the stream and convert to HLS
|
|
||||||
command = [
|
|
||||||
'ffmpeg', '-i', 'udp://127.0.0.1:1935/live', '-c:v', 'libx264', '-preset', 'veryfast',
|
|
||||||
'-c:a', 'aac', '-ar', '44100', '-ac', '2', '-f', 'hls', '-hls_time', '4', '-hls_list_size', '5',
|
|
||||||
'-hls_segment_filename', f'{STREAM_PATH}/{STREAM_NAME}%03d.ts', f"{STREAM_PATH}/{STREAM_NAME}.m3u8"
|
|
||||||
]
|
|
||||||
|
|
||||||
Popen(command, stdout=PIPE, stderr=PIPE)
|
|
||||||
Reference in New Issue
Block a user