Skip to content

Instantly share code, notes, and snippets.

@knthls
Last active December 6, 2017 08:24
Show Gist options
  • Save knthls/d67f06cbb87f85c4f39ffa2ba2ef66df to your computer and use it in GitHub Desktop.
Save knthls/d67f06cbb87f85c4f39ffa2ba2ef66df to your computer and use it in GitHub Desktop.
"""
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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment