""" Basic Idea taken from http://stackoverflow.com/a/8111621/6420372 """ import os import socket import subprocess from select import select import time import contextlib import settings try: import winreg except ImportError: import _winreg as winreg def _get_vlc_path(): views = [(winreg.HKEY_CURRENT_USER, 0), (winreg.HKEY_LOCAL_MACHINE, winreg.KEY_WOW64_64KEY), (winreg.HKEY_LOCAL_MACHINE, winreg.KEY_WOW64_32KEY)] subkey = r'Software\VideoLAN\VLC' access = winreg.KEY_QUERY_VALUE for hroot, flag in views: try: with winreg.OpenKey(hroot, subkey, 0, access | flag) as hkey: value, type_id = winreg.QueryValueEx(hkey, None) if type_id == winreg.REG_SZ: return value except WindowsError: pass raise SystemExit("Error: VLC not found.") def send_command(sock, cmd, get_result=False): try: cmd = (cmd + '\n').encode('ascii') except AttributeError: cmd += b'\n' sent = total = sock.send(cmd) while total < len(cmd): sent = sock.send(cmd[total:]) if sent == 0: raise socket.error('Socket connection broken.') total += sent if get_result: return receive_result(sock) def receive_result(sock): data = bytearray() sock.setblocking(0) while select([sock], [], [], 1.0)[0]: chunk = sock.recv(1024) if chunk == b'': raise socket.error('Socket connection broken.') data.extend(chunk) sock.setblocking(1) return data.decode('utf-8') def _outfile(id_): return os.path.join(settings.DATA_DIR, 'recording_{}_.mp4'.format(id_)) def _sout_options(id_): """ somehow passing them as single options doesn't work :param id_: :return: """ return "--sout=#transcode{" \ "vcodec=h264,vb=1024,fps=" + \ str(settings.CAM_FRAME_RATE) + ",width=640" \ "}:standard{access=file,mux=ts," \ "dst=" + "\"{}\"".format(_outfile(id_)) + "}" def _stream_options(): return ['--dshow-size={}x{}'.format(*settings.CAM_RES), '--dshow-adev=None', '--dshow-fps={}'.format(settings.CAM_FRAME_RATE), '--dshow-vdev=USB_Camera'] @contextlib.contextmanager def vlc(address, port, id_): rc_host = '{0}:{1}'.format(address, port) vlc = subprocess.Popen([_get_vlc_path(), '-I', 'rc', '--rc-host', rc_host, '--rc-quiet', 'dshow://'] + _stream_options() + [_sout_options(id_),'--qt-start-minimized']) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: sock.connect((address, port)) yield sock send_command(sock, 'stop') send_command(sock, 'quit') except socket.error as e: exit("Error: " + e.args[0]) finally: sock.close() # give vlc some time to finish transcoding the stream? time.sleep(5) if vlc.poll() is None: vlc.terminate() if __name__ == '__main__': with vlc('localhost', 12345, 42) as sock: time.sleep(10)