![]() |
TSDuck v3.36-3487
MPEG Transport Stream Toolkit
|
Starting with version 3.25, TSDuck includes Java and Python bindings to some high-level features.
Although subject to enhancements, these bindings will never aim at supporting the full TSDuck feature set since this would be too large. Only a small subset of TSDuck high-level features are targeted.
The Java classes are documented in the Java bindings reference section.
The Python classes are documented in the Python bindings reference section.
Sample Java and Python applications are available in the TSDuck source tree.
Currently, the TSDuck Java and Python bindings provide access to the following features. Equivalences are provided between C++, Java, Python and command line tools.
The first three classes implement high-level features which have direct counterparts as command line tools. The others are support classes which are only required to use the high-level classes.
The DuckContext
class is used to define and accumulate regional or operator preferences. In the TSDuck C++ programming guide, it is referred to as TSDuck execution context. Most of the time, using the default state of a new instance is sufficient.
The application sample Japanese tables, available in Java and Python, demonstrates how it can be necessary to override the defaults in specific cases.
The reporting classes (ts::Report
C++ class hierarchy) are used to report logs, errors and debug. They are consistently used all over TSDuck and are required to use the high level features. There is a large hierarchy of classes in the three languages which can be classified according to two sets of criteria:
TSProcessor
or InputSwitcher
.logMessageHandler
(Java) or log
(Python) to intercept and process the message lines.The asynchronous abstract classes can be useful to collect events, tables and sections in XML, JSON or binary / hexadecimal form in Java or Python applications when using TSProcessor
or InputSwitcher
. Some of the sample Java and Python applications illustrate this mechanism.
Category | C++ class | Java class | Python class |
---|---|---|---|
Synchronous, native | ts::CerrReport | io.tsduck.ErrReport | tsduck.StdErrReport |
ts::NullReport | io.tsduck.NullReport | tsduck.NullReport | |
Asynchronous, native | ts::AsyncReport | io.tsduck.AsyncReport | tsduck.AsyncReport |
Synchronous, abstract | ts::Report | io.tsduck.AbstractSyncReport | tsduck.AbstractSyncReport |
Asynchronous, abstract | ts::AsyncReport | io.tsduck.AbstractAsyncReport | tsduck.AbstractAsyncReport |
The SystemMonitor
class is available in all languages, C++, Java and Python. It can be used at the top-level of an application to implement the --monitor
option as found in tsp
and tsswitch
. An instance of a thread-safe Report
class is used to report monitoring messages.
The SystemMonitor
class is very simple to used. Examples are available in Java and Python.
For developers, TSDuck plugins can signal events which can be handled by the application. Each event is signalled with a user-defined 32-bit event code. An application can register event handlers in the ts::TSProcessor
instance (see the class ts::PluginEventHandlerRegistry
, knowing that ts::TSProcessor
is a subclass of ts::PluginEventHandlerRegistry
). The event handler registration can include various selection criteria such as event code value or originating plugin (see the inner class ts::PluginEventHandlerRegistry::Criteria
).
C++ developers who create their own plugins can signal any kind of event that they later handle in their application. This is illustrated in the C++ sample custom application. In this sample code, everything is customized in the application: the plugin, the event it signals, the associated event data, the application handling of the event.
Since developing a TSDuck plugin is only possible in C++, Java and Python developers have more limited options. Some standard TSDuck plugins such as tables
, psi
or mpe
provide the option --event-code
. Using this option, the plugins signal event using the specified event code for each data they handle (sections or MPE datagrams depending on the plugin).
Java and Python applications can derive from class AbstractPluginEventHandler
to define and register their own event handlers. Thus, binary sections or MPE datagrams can be handled directly from the plugin to the Java or Python application.
Some plugins are even dedicated to application developers and are useless on tsp
command lines. This is the case of the memory
plugin (both an input and an output plugin). This plugin, when used in a TSProcessor
instance, performs direct transport stream input and output from and to the application using memory buffers. The memory buffers are signalled using plugin events. The memory
input plugin is an example of an application-defined event handler returning data to the plugin. See sample code in the TSDuck source code tree.
At high level, Java and Python applications can only run TSProcessor
or InputSwitcher
sessions, just like a shell-script would do with commands tsp
and tsswitch
.
The communication from the Java and Python applications to the plugins is performed using plugin options. These options may contain file names or UDP ports which can be created by the application.
More effectively, most file contents can be provided directly on the command line, avoiding the burden of creating temporary files. For instance, wherever an input XML file name is expected, it is possible to use the XML content instead. Any "XML file name" which starts with "<?xml", it is considered as inline XML content. Similarly, if an input JSON file name starts with "{" or "[", it is considered as inline JSON content.
On reverse side, there is some limited form of communication from the plugins to the Java or Python application. There are basically two ways to handle plugin information in the application: the logging system and plugin events.
Using the logging system: Some plugins support options such as --log-xml-line
, --log-json-line
or --log-hexa-line
. With these options, the extracted data (table, section, MPE datagram) are "displayed" as one single line in the designated format on the logging system. Using user-defined Java or Python asynchronous abstract reporting classes, the application receives all logged lines and can filter and manipulate the data which were extracted and logged by the plugins.
Using plugin events: Some plugins support the option --event-code
. With this option, the extracted data are signalled by the plugin as an event. Using and registering user-defined Java or Python plugin event handlers, the application is directly notified of the data.
Which mechanism, logging system or plugin events, should be used depends on the application.
AbstractAsyncReport
consttructor.The following sample applications can be used as a starting point:
Communication type | Java | Python |
---|---|---|
Logging (XML) | SampleAnalyzeSDT | sample-analyze-sdt.py |
Logging (JSON) | SampleAnalyzeTS | sample-analyze-ts.py |
Logging (bin/hexa) | SampleFilterTablesLog | sample-filter-tables-log.py |
Plugin events (sections) | SampleFilterTablesEvent | sample-filter-tables-event.py |
Plugin events (MPE datagrams) | SampleMPE | sample-mpe.py |
Plugin events (input/output) | SampleMemoryPlugins | sample-memory-plugins.py |
All TSDuck Java classes are defined in a package named io.tsduck
.
A few examples are provided in the directory sample/sample-java
in the TSDuck source code package.
The TSDuck Java bindings are installed with TSDuck in /usr/share/tsduck/java
. All classes are in a JAR file named tsduck.jar
. Simply add this JAR in the environment variable CLASSPATH
to use TSDuck from any Java application:
This is similar to Linux, except that /usr/local/share
is used instead of /usr/share
.
On Windows, Java bindings are optional components of the TSDuck installer. When they are selected for installation, they are installed in the TSDuck area and the environment variable CLASSPATH
is modified at system level to include the JAR file of the TSDuck Java bindings. Thus, any Java program can use TSDuck directly.
All TSDuck bindings are defined in a module named tsduck
. All Python programs using TSDuck shall consequently start with:
A few examples are provided in the directory sample/sample-python
in the TSDuck source code package.
The Python bindings are installed with TSDuck in /usr/share/tsduck/python
. Simply add this directory in the environment variable PYTHONPATH
to use TSDuck from any Python application:
This is similar to Linux, except that /usr/local/share
is used instead of /usr/share
.
On Windows, Python bindings are optional components of the TSDuck installer. When they are selected for installation, they are installed in the TSDuck area and the environment variable PYTHONPATH
is modified at system level to include the root directory of the TSDuck Python bindings. Thus, any Python program can use TSDuck directly.
The code was initially tested with Python 3.7 and higher. Python 2.x is not supported. Intermediate versions may work but without guarantee.
There are usually two ways to call C/C++ from Python:
ctypes
Python module to call C functions,The second option is usually more flexible and more generic. However, the generated binary depends on the version of Python. If such an option is used, the binary installation of TSDuck would require a specific version of Python (or a specific set of versions of it). But each system has it own requirements on Python and it is difficult for a product like TSDuck to impose a specific version of Python.
Consequently, the less flexible ctypes
approach was chosen. The TSDuck binary library contains C++ wrapper functions to some features of TSDuck and these carefully crafted functions are directly called from Python code using ctypes
, regardless of the version of Python. Note, however, that these C++ functions are hidden inside the Python bindings and invisible to the C++ application developer.