Skip to content

Commit 6626e4c

Browse files
committed
Add "inputs" support to pyCA
Adds support for sending configuration to the agent configuration endpoint in Opencast. Adds a new config option "inputs". It allows users to specifiy for a given event which tracks they would like to show up in the final recording. For example, if the agent is capable of recording both "presenter/source" and "presentation/source", a user may select only "presentation/source" as input.
1 parent 905407a commit 6626e4c

File tree

5 files changed

+91
-8
lines changed

5 files changed

+91
-8
lines changed

etc/pyca.conf

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@
4040
# Default: sqlite:///pyca.db
4141
#database = sqlite:///pyca.db
4242

43+
# Selectable inputs
44+
# A track will only be ingested if the flavor of the track matches one of the
45+
# selected inputs.
46+
# If not specified, all inputs are always selected.
47+
# Default: inputs = ''
48+
#inputs = 'presenter/source, presentation/source'
49+
4350

4451
[capture]
4552

@@ -170,7 +177,7 @@ command = 'ffmpeg -nostats -re -f lavfi -r 25 -i testsrc -f lavfi -i si
170177
# org.opencastproject.server.url setting of Opencast.
171178
# Type: string
172179
# Default: https://develop.opencast.org
173-
url = 'https://develop.opencast.org'
180+
url = 'http://localhost:8080'
174181

175182
# Analogue of -k, --insecure option in curl. Allows insercure SSL connections
176183
# while using HTTPS on the server.

pyca/agentstate.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
:license: LGPL – see license.lgpl for more details.
88
'''
99

10-
from pyca.utils import set_service_status, update_agent_state, timestamp
10+
from pyca.utils import set_service_status, update_agent_state, timestamp, \
11+
update_agent_config
1112
from pyca.utils import terminate
1213
from pyca.config import config
1314
from pyca.db import Service, ServiceStatus
@@ -34,6 +35,7 @@ def control_loop():
3435

3536
if not terminate():
3637
update_agent_state()
38+
update_agent_config()
3739

3840
logger.info('Shutting down agentstate service')
3941
set_service_status(Service.AGENTSTATE, ServiceStatus.STOPPED)

pyca/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
cal_lookahead = integer(min=0, default=14)
2121
backup_mode = boolean(default=false)
2222
database = string(default='sqlite:///pyca.db')
23+
inputs = force_list(default=list())
2324
2425
[capture]
2526
directory = string(default='./recordings')

pyca/ingest.py

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,49 @@
2323
notify = sdnotify.SystemdNotifier()
2424

2525

26+
def inputs_from_event(event):
27+
''' Parse inputs from event attachment
28+
'''
29+
30+
inputs = []
31+
for attachment in event.get_data().get('attach'):
32+
data = attachment.get('data')
33+
if (attachment.get('x-apple-filename') ==
34+
'org.opencastproject.capture.agent.properties'):
35+
for prop in data.split('\n'):
36+
if prop.startswith('capture.device.names'):
37+
param = prop.split('=', 1)
38+
inputs = param[1].split(',')
39+
break
40+
return inputs
41+
42+
43+
def is_track_selected(event, flavor):
44+
''' If inputs are configured, check if track was selected
45+
'''
46+
47+
# inputs not configured -> add all
48+
inputs_conf = config('agent', 'inputs')
49+
if not inputs_conf:
50+
logger.info('No inputs in config')
51+
return True
52+
53+
# Get inputs from event attachment
54+
inputs_event = inputs_from_event(event)
55+
56+
# inputs not in attachment -> add all
57+
if not inputs_event:
58+
logger.info('No inputs in schedule')
59+
return True
60+
61+
# input is selected
62+
if flavor in inputs_event:
63+
return True
64+
65+
# input is not selected
66+
return False
67+
68+
2669
def get_config_params(properties):
2770
'''Extract the set of configuration parameters from the properties attached
2871
to the schedule
@@ -87,12 +130,15 @@ def ingest(event):
87130

88131
# add track
89132
for (flavor, track) in event.get_tracks():
90-
logger.info('Adding track (%s -> %s)', flavor, track)
91-
track = track.encode('ascii', 'ignore')
92-
fields = [('mediaPackage', mediapackage), ('flavor', flavor),
93-
('BODY1', (pycurl.FORM_FILE, track))]
94-
mediapackage = http_request(service_url + '/addTrack', fields,
95-
timeout=0)
133+
if is_track_selected(event, flavor):
134+
logger.info('Adding track (%s -> %s)', flavor, track)
135+
track = track.encode('ascii', 'ignore')
136+
fields = [('mediaPackage', mediapackage), ('flavor', flavor),
137+
('BODY1', (pycurl.FORM_FILE, track))]
138+
mediapackage = http_request(service_url + '/addTrack', fields,
139+
timeout=0)
140+
else:
141+
logger.info('Not adding track (%s -> %s)', flavor, track)
96142

97143
# ingest
98144
logger.info('Ingest recording')

pyca/utils.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,33 @@ def update_agent_state():
261261
register_ca(status=status)
262262

263263

264+
def update_agent_config():
265+
'''Update the current agent configuration in opencast.
266+
'''
267+
268+
if config('agent', 'backup_mode'):
269+
return
270+
service_endpoint = service('capture.admin')
271+
if not service_endpoint:
272+
logger.warning('Missing endpoint for updating agent status.')
273+
return
274+
275+
inputs = ",".join(config('agent', 'inputs'))
276+
params = [(
277+
'configuration',
278+
'{\'capture.device.names\': \'' + inputs + '\'}'
279+
)]
280+
281+
name = urlquote(config('agent', 'name').encode('utf-8'), safe='')
282+
url = f'{service_endpoint[0]}/agents/{name}/configuration'
283+
try:
284+
response = http_request(url, params).decode('utf-8')
285+
if response:
286+
logger.info(response)
287+
except pycurl.error as e:
288+
logger.warning('Could not set configuration of agent %s: %s', name, e)
289+
290+
264291
def terminate(shutdown=None):
265292
'''Mark process as to be terminated.
266293
'''

0 commit comments

Comments
 (0)