Skip to content

Commit

Permalink
Allow the first filename counter to be calculated
Browse files Browse the repository at this point in the history
Part of the fix for #481 - allow the filesystem output carriage begin count to be overridden in the ebuttd-encoder using a first document datetime and a document duration. The zeroth document is calculated as the difference between the current datetime and the specified datetime divided by the document duration.
  • Loading branch information
nigelmegitt committed May 9, 2018
1 parent 1890be2 commit 61ebf21
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 5 deletions.
3 changes: 3 additions & 0 deletions ebu_tt_live/carriage/filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ def _get_default_clock(self, sequence_identifier, time_base, clock_mode=None):
self._default_clocks[sequence_identifier] = clock_obj
return clock_obj

def set_message_counter(self, message_counter):
self._msg_counter = message_counter

def check_availability_time(
self, sequence_identifier, time_base=None, clock_mode=None, availability_time=None):
"""
Expand Down
25 changes: 25 additions & 0 deletions ebu_tt_live/config/clocks.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from .common import ConfigurableComponent, Namespace
from ebu_tt_live import clocks
from datetime import datetime, timedelta
import re
from ebu_tt_live.errors import ConfigurationError
from ebu_tt_live.strings import ERR_NO_SUCH_COMPONENT

Expand Down Expand Up @@ -42,3 +44,26 @@ def get_clock(clock_type):
type_name=clock_type
)
)

def _int_or_none(value):
try:
return int(value)
except TypeError:
return 0

_datetime_groups_regex = re.compile('([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])T([0-9][0-9]):([0-5][0-9]):([0-5][0-9]|60)(?:\.([0-9]+))?')

def get_date(date):
years, months, days, hours, minutes, seconds, microseconds = map(
lambda x: _int_or_none(x),
_datetime_groups_regex.match(date).groups()
)

return datetime(
year = years,
month = months,
day = days,
hour = hours,
minute = minutes,
second = seconds,
microsecond = microseconds)
36 changes: 32 additions & 4 deletions ebu_tt_live/config/node.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from .common import ConfigurableComponent, Namespace, converters, RequiredConfig
from .clocks import get_clock
from .clocks import get_clock, get_date
from .carriage import get_producer_carriage, get_consumer_carriage
from ebu_tt_live import documents
from ebu_tt_live import bindings
Expand All @@ -10,6 +10,8 @@
from ebu_tt_live.errors import ConfigurationError
from ebu_tt_live.strings import ERR_CONF_NO_SUCH_NODE
from .adapters import ProducerNodeCarriageAdapter, ConsumerNodeCarriageAdapter
from datetime import datetime, timedelta
from math import floor


class NodeBase(ConfigurableComponent):
Expand Down Expand Up @@ -250,10 +252,26 @@ class EBUTTDEncoder(ProducerMixin, ConsumerMixin, NodeBase):

required_config = Namespace()
required_config.add_option('id', default='ebuttd-encoder')
required_config.add_option('media_time_zero', default='current')
required_config.add_option('default_namespace', default=False)
required_config.add_option(
'media_time_zero',
default='current',
doc='The clock equivalent time to use for media time zero, defaults to the current time.')
required_config.add_option(
'default_namespace',
default=False,
doc='Whether to use a default namespace, default false.')
required_config.clock = Namespace()
required_config.clock.add_option('type', default='local', from_string_converter=get_clock)
required_config.override_begin_count = Namespace()
required_config.override_begin_count.add_option(
'first_doc_datetime',
doc='The time when the document numbered 1 was available, format YYYY-mm-DDTHH:MM:SS',
default = datetime.utcnow(),
from_string_converter=get_date)
required_config.override_begin_count.add_option(
'doc_duration',
default=5.0,
doc='The duration of each document in seconds, default 5')

_clock = None

Expand All @@ -263,10 +281,20 @@ def _create_component(self, config):
mtz = self._clock.component.get_time()
else:
mtz = bindings.ebuttdt.LimitedClockTimingType(str(self.config.media_time_zero)).timedelta

begin_count = None

if self.config.override_begin_count:
# override the carriage mech's document count
fdt = self.config.override_begin_count.first_doc_datetime
tn = datetime.utcnow()
begin_count = int(floor((tn - fdt).total_seconds() / self.config.override_begin_count.doc_duration))

self.component = processing_node.EBUTTDEncoder(
node_id=self.config.id,
media_time_zero=mtz,
default_ns=self.config.default_namespace
default_ns=self.config.default_namespace,
begin_count=begin_count
)

def __init__(self, config, local_config):
Expand Down
17 changes: 16 additions & 1 deletion ebu_tt_live/node/encoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
from ebu_tt_live.clocks.media import MediaClock
from ebu_tt_live.documents.converters import EBUTT3EBUTTDConverter
from ebu_tt_live.documents import EBUTTDDocument, EBUTT3Document
#from ebu_tt_live.carriage.filesystem import FilesystemProducerImpl
#from ebu_tt_live.carriage import FilesystemProducerImpl


class EBUTTDEncoder(AbstractCombinedNode):
Expand All @@ -13,9 +15,14 @@ class EBUTTDEncoder(AbstractCombinedNode):
_default_ebuttd_doc = None
_expects = EBUTT3Document
_provides = EBUTTDDocument
# _begin_count is used to override the first output document count number. when
# provided as a constructor value it is stored, and set on the output carriage
# impl once before the first time emit_document is called. Then it is reset
# to None, which is used as the test to see if it needs to be used.
_begin_count = None

def __init__(self, node_id, media_time_zero, default_ns=False, producer_carriage=None,
consumer_carriage=None, **kwargs):
consumer_carriage=None, begin_count=None, **kwargs):
super(EBUTTDEncoder, self).__init__(
producer_carriage=producer_carriage,
consumer_carriage=consumer_carriage,
Expand All @@ -25,6 +32,7 @@ def __init__(self, node_id, media_time_zero, default_ns=False, producer_carriage
self._default_ns = default_ns
media_clock = MediaClock()
media_clock.adjust_time(timedelta(), media_time_zero)
self._begin_count = begin_count
self._ebuttd_converter = EBUTT3EBUTTDConverter(
media_clock=media_clock
)
Expand All @@ -41,6 +49,13 @@ def process_document(self, document, **kwargs):
converted_doc = EBUTTDDocument.create_from_raw_binding(
self._ebuttd_converter.convert_document(document.binding)
)

# If this is the first time, and there's a begin count override, apply it
if self._begin_count is not None:
# Will fail unless the concrete producer carriage impl is a FilesystemProducerImpl
self.producer_carriage.producer_carriage.set_message_counter(self._begin_count)
self._begin_count = None

# Specify the time_base since the FilesystemProducerImpl can't derive it otherwise.
# Hard coded to 'media' because that's all that's permitted in EBU-TT-D. Alternative
# would be to extract it from the EBUTTDDocument but since it's the only permitted
Expand Down

0 comments on commit 61ebf21

Please sign in to comment.