Skip to content

Commit

Permalink
Merge branch 'master' of github.com:CarlFK/voctomix-outcasts
Browse files Browse the repository at this point in the history
  • Loading branch information
CarlFK committed Jul 31, 2023
2 parents ac0de5e + dffa417 commit 5464683
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 53 deletions.
5 changes: 1 addition & 4 deletions configs/voctolight.ini
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,7 @@ plugin=stdout

[rpi]
;; GPIO that has the desired light
gpio_red=11

;; GPIOs to reset/initialise
gpios=11,12,13
gpio=11

[serial_dtr]
path=/dev/ttyS0
Expand Down
43 changes: 34 additions & 9 deletions ingest.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,25 @@ def mk_video_src(args, videocaps):
decodebin !
"""

elif args.video_source == 'hdmi2usb':
# https://hdmi2usb.tv
# Note: this code *only* works with 720p
elif args.video_source in ('hdmi2usb', 'uvc-mjpeg'):
video_src = """
v4l2src {attribs} name=videosrc !
"""
video_src += """
queue max-size-time=4000000000 !
image/jpeg,width=1280,height=720 !
image/jpeg,{caps} !
jpegdec !
"""
""".format(caps=extract_caps(videocaps))

elif args.video_source == 'uvc-raw':

video_src = """
v4l2src {attribs} name=videosrc !
"""
video_src += """
video/x-raw,{caps} !
""".format(
caps=extract_caps(videocaps))

elif args.video_source == 'ximage':
# startx=0 starty=0 endx=1919 endy=1079 !
Expand Down Expand Up @@ -98,6 +108,14 @@ def mk_video_src(args, videocaps):
queue !
"""

elif args.video_source == 'rtmp':
video_src = """
rtmpsrc {attribs} !
decodebin name=src
src. !
queue !
"""

elif args.video_source == 'test':

video_src = """
Expand Down Expand Up @@ -157,7 +175,7 @@ def mk_audio_src(args, audiocaps):
queue !
"""

elif args.audio_source == 'file':
elif args.audio_source in ('file', 'rtmp'):
# this only works if video is from ...
# some gst source that gets demux ed, I guess.
audio_src = """
Expand Down Expand Up @@ -200,6 +218,13 @@ def mk_audio_src(args, audiocaps):
return audio_src


def extract_caps(videocaps, caps=("width", "height")):
"""Filter out caps (list of keys) from a videocaps strings"""
parts = videocaps.split(',')
filtered = [cap for cap in parts if cap.split('=')[0] in caps]
return ','.join(filtered)


def mk_client(core_ip, port):

client = "tcpclientsink host={host} port={port}".format(
Expand Down Expand Up @@ -377,8 +402,8 @@ def get_args():
parser.add_argument(
'--video-source', action='store',
choices=[
'dv', 'hdv', 'udp_h264', 'hdmi2usb', 'blackmagic',
'ximage', 'png', 'file', 'test', 'spacescope'],
'dv', 'hdv', 'udp_h264', 'hdmi2usb', 'uvc-mjpeg', 'uvc-raw',
'blackmagic', 'ximage', 'png', 'file', 'rtmp', 'test', 'spacescope'],
default='test',
help="Where to get video from")

Expand All @@ -400,7 +425,7 @@ def get_args():
parser.add_argument(
'--audio-source', action='store',
choices=['dv', 'hdv', 'file',
'alsa', 'pulse', 'blackmagic', 'test', ],
'alsa', 'pulse', 'blackmagic', 'rtmp', 'test',],
default='test',
help="Where to get audio from")

Expand Down
12 changes: 12 additions & 0 deletions lib/plugins/all_plugins.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from .base_plugin import BasePlugin
from .rpi_gpio import RpiGpio
from .serial_dtr import SerialDtr
from .stdout import Stdout
Expand All @@ -10,3 +11,14 @@
'stdout': Stdout,
'tomu': Tomu,
}


def get_plugin(config) -> BasePlugin:
"""Creates an instance of a plugin named in Voctolight's configuration file."""
plugin_name = config.get('light', 'plugin')
plugin_cls = PLUGINS.get(plugin_name, None)

if plugin_cls is None:
raise ValueError(f'{plugin_name} is not a valid plugin name')

return plugin_cls(config)
20 changes: 20 additions & 0 deletions lib/plugins/base_plugin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from abc import ABC, abstractmethod

__all__ = ['BasePlugin']


class BasePlugin(ABC):
"""An abstract plugin class, that all other plugins inherit from."""

def __init__(self, config):
...

@abstractmethod
def tally_on(self) -> None:
"""Called when the tally light should be turned on."""
...

@abstractmethod
def tally_off(self) -> None:
"""Called when the tally light should be turned off."""
...
29 changes: 16 additions & 13 deletions lib/plugins/rpi_gpio.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,32 @@
# Plugin to provide a tally light interface for a Raspberry Pi's GPIO
DO_GPIO = True
"""
Plugin to provide a tally light interface for a Raspberry Pi's GPIO.
It requires RPi.GPIO.
"""

from .base_plugin import BasePlugin

try:
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
except ImportError:
DO_GPIO = False
# We are probably not running on a Raspberry Pi.
GPIO = None

__all__ = ['RpiGpio']

class RpiGpio:
class RpiGpio(BasePlugin):
def __init__(self, config):
if not DO_GPIO:
raise ValueError('RpiGpio will not work on this platform. Is RPi.GPIO installed?')
if not GPIO:
raise NotImplementedError('RpiGpio will not work on this platform. Is RPi.GPIO installed?')

all_gpios = [int(i) for i in config.getlist('rpi', 'gpios')]
self.gpio_port = int(config.get('rpi', 'gpio_red'))
self.gpio_port = int(config.get('rpi', 'gpio'))

GPIO.setup(all_gpios, GPIO.OUT)
GPIO.output(all_gpios, GPIO.HIGH)
GPIO.setup(self.gpio_port, GPIO.OUT)
GPIO.output(self.gpio_port, GPIO.HIGH)

def tally_on(self):
GPIO.output(self.gpio_port, GPIO.LOW)

def tally_off(self):
GPIO.output(self.gpio_port, GPIO.HIGH)

def __del__(self):
GPIO.cleanup()
5 changes: 4 additions & 1 deletion lib/plugins/serial_dtr.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
# Turning on a light opens a serial port, which pulls the DTR line high.
# Turning off a light closes the serial port, pulling DTR low.

from .base_plugin import BasePlugin

__all__ = ['SerialDtr']

class SerialDtr:

class SerialDtr(BasePlugin):
def __init__(self, config):
self.fn = config.get('serial_dtr', 'port')
self.fd = None
Expand Down
14 changes: 9 additions & 5 deletions lib/plugins/stdout.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# Plugin to provide a tally light interface via stdout
__all__ = ['Stdout']
"""
Plugin to provide a tally light interface via stdout.
This is an example that can be used to build other plugins.
"""

class Stdout:
def __init__(self, config):
pass
from .base_plugin import BasePlugin

__all__ = ['Stdout']

class Stdout(BasePlugin):
def tally_on(self):
print('Tally light on')

Expand Down
12 changes: 6 additions & 6 deletions lib/plugins/tomu.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
# Makes a tomu.im USB Simple sample as a tally light.
# https://github.com/im-tomu/tomu-samples/tree/master/usb_simple

__all__ = ['TomuSimpleLed']
from .base_plugin import BasePlugin

DO_USB = True
try:
import usb.core
except ImportError:
DO_USB = False
usb = None


class Tomu:
class Tomu(BasePlugin):
def __init__(self, config):
if not usb:
raise ValueError('USB support not available. Install pyusb')

self.on = int(config.get('tomu', 'on'))
self.off = int(config.get('tomu', 'off'))
if not DO_USB:
raise ValueError('USB support not available. Install pyusb')

self.device = usb.core.find(idVendor=0x1209, idProduct=0x70b1)
if self.device is None:
Expand Down
10 changes: 2 additions & 8 deletions testlight.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from sys import exit

from lib.config import Config
from lib.plugins.all_plugins import PLUGINS
from lib.plugins.all_plugins import get_plugin

def main():
parser = ArgumentParser(
Expand All @@ -13,13 +13,7 @@ def main():
'-c', '--config', type=FileType('r'), help='Use a specific config file')
args = parser.parse_args()
config = Config(cmd_line_config=args.config)

plugin_cls = PLUGINS.get(config.get('light', 'plugin'), None)
if plugin_cls is None:
print('No plugin selected, control will not work!')
exit(1)

plugin = plugin_cls(config)
plugin = get_plugin(config)

try:
while True:
Expand Down
9 changes: 2 additions & 7 deletions voctolight.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from sys import exit

from lib.config import Config
from lib.plugins.all_plugins import PLUGINS
from lib.plugins.all_plugins import get_plugin


class Connection(asyncio.Protocol):
Expand Down Expand Up @@ -122,12 +122,7 @@ def handle_server_config(self, args):
help='Show what would be done in addition to toggling lights')
args = parser.parse_args()
config = Config(cmd_line_config=args.config)
plugin_cls = PLUGINS.get(config.get('light', 'plugin'), None)
if plugin_cls is None:
print('No plugin selected, control will not work!')
exit(1)

actor = plugin_cls(config)
actor = get_plugin(config)
interpreter = Interpreter(actor, config, debug=args.debug)
conn = Connection(interpreter)
conn.connect(config.get('server', 'host'))
Expand Down

0 comments on commit 5464683

Please sign in to comment.