fstream/ffmpstream-server.py

102 lines
2.3 KiB
Python

#!/usr/bin/env python3
import sys
oldexcepthook = sys.excepthook
def newexcepthook(type,value,traceback):
oldexcepthook(type,value,traceback)
input("Press ENTER to quit.")
sys.excepthook = newexcepthook
import os
p = os.path.join
pUp = os.path.dirname
s = False
if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
s = os.path.realpath(sys.executable)
else:
s = os.path.realpath(__file__)
sp = pUp(s)
# script start
import threading
import queue
import socket
import subprocess
threads = {}
threadId = 0
threadsLock = threading.Lock()
serverAddr = ("127.0.0.1",12000)
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
bufferSize = 1000 # buffer size in bytes
proc = subprocess.Popen([
# binary
"ffmpeg",
# input: audio
"-f","dshow","-audio_buffer_size","10","-i","audio=virtual-audio-capturer",
# input: video
"-f","gdigrab","-framerate","30","-i","desktop","-vf","scale=-1:480",
# output-codec: video
"-c:v","libx264","-pix_fmt","yuv420p","-preset","fast","-tune","zerolatency",
# output-codec: audio
"-c:a","aac",
# output properties:
"-bufsize","2M","-maxrate","1M",
# output-file:
"-f","mpegts",
"-"
],stdout=subprocess.PIPE,stdin=subprocess.PIPE)
class outThread(threading.Thread):
def __init__(self,threadId,connection,address):
threading.Thread.__init__(self)
self.threadId = threadId
self.queue = queue.Queue()
self.connection = connection
self.address = address
self.connection.settimeout(15)
def run(self):
try:
while True:
data = self.queue.get()
self.connection.sendall(data)
except:
with threadsLock:
del threads[str(self.threadId)]
raise
class ffmpegThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
while proc.poll() is None:
data = proc.stdout.read(bufferSize)
with threadsLock:
for thread in threads:
thread = threads[thread]
thread.queue.put(data)
def main():
global threadId
serverSocket.bind(serverAddr)
serverSocket.listen(1024)
ffmpegThread().start()
while True:
connection, address = serverSocket.accept()
with threadsLock:
threadId += 1
while str(threadId) in threads:
threadId += 1
thread = outThread(threadId,connection,address)
threads[str(threadId)] = thread
thread.start()
if __name__ == '__main__':
main()