Important notes about latest ATV and Android 11+ AOSP platforms:
See "Important notes about latest ATV and Android 11+ AOSP platforms"
section here:
- http://files.dune-hd.com/sdk/doc/html/dune_devel_info.html#important_notes_about_latest_atv_and_android_11_aosp_platforms
Overview
The mechanism of plugins provides a possibility to integrate applications
into the native Dune GUI. When an application is packaged as a plugin, it
can appear in the native Dune GUI just an an icon in Dune menu.
Such applications can be implemented using a variety of technologies
supported by Dune HD STB:
- It can be an application based on the native Dune HD GUI framework and
implemented using PHP language and PHP API provided by Dune HD STB.
- It can include some web server functionality (e.g. CGI scripts running
on the STB) providing HTTP API for external systems or providing a way
for HTML or FlashLite application to execute native code on the STB.
- It can include any Linux software executed on demand or running in the
background, and it can even include custom Linux kernel modules (e.g.
drivers for certain USB hardware or kernel modules implementing
certain DRM systems).
- The application can also use a mix of different technologies.
- There is also a possibility to use DirectFB/Qt-based custom GUI
implementation, but this requires to use special firmware versions
("Native GUI SDK" firmware versions) and is not supported by standard
firmware versions.
- It can be a full-screen HTML application (on models which support HTML
applications).
- It can be a full-screen FlashLite application (on models which support
FlashLite applications).
A big part of the plugins mechanism is the PHP API for implementation of
GUI functionality based on the native Dune HD GUI framework. This approach
allows quick implementation of GUI functionality tightly integrated into
the native Dune GUI. It is especially suitable for quick creation of simple
IPTV/VOD applications. The following possibilities are provided:
- HTML coding is NOT involved; the standard GUI (native Dune HD media
player GUI) is used automatically. The PHP code is only responsible
for the interaction with the server part of the service (typically
via HTTP requests), and customizing the GUI look/behavior in some
ways.
- OSD GUI for IPTV and VOD playback is provided automatically
(including TV channels navigation, TV channel categories, favorite
channels management, EPG, series navigation, etc).
- Plugin can easily visualize hierarchical catalogs of content (TV
channel categories, VOD categories, etc).
- Plugin can show various user interaction dialogs (login, movie
purchase confirmation, settings, etc).
Plugin examples
IPTV/VOD applications implemented using PHP:
- http://files.dune-hd.com/sdk/plugins/dune_plugin_demo2.2011_12_22.zip
- http://files.dune-hd.com/sdk/plugins/dune_plugin_demo2_with_ad.zip
Simple digital signage application (endless playback of a media_url)
implemented using PHP:
- http://files.dune-hd.com/sdk/plugins/dune_plugin_simple_presenter.2013_07_19.zip
HTML applications packaged as plugins:
- See "HTML plugin examples" section here:
- http://files.dune-hd.com/sdk/doc/html/html_apps.html
An application demonstrating deep Linux integration (daemon automatically
started on STB boot, HTTP API allowing to control the daemon and access the
data in Linux filesystem, simple HTML application interacting with this
HTTP API via AJAX):
- http://files.dune-hd.com/sdk/plugins/dune_plugin_linux_code_demo.2014_03_20.zip
Historical note
When the mechanism of plugins was first introduced in Dune HD STB, it was
originally intended for the implementation of custom GUI applications using
the provided PHP API, and it was required that each plugin included at
least some PHP code. This was the reason why plugins were originally called
"PHP plugins". Later, various features allowing to use the mechanism of
plugins w/o the need to use PHP code were added, but the term "PHP plugin"
was still used. The documentation below refers to the term "PHP plugin",
but all the features which are not directly related to the use of PHP
language are also applicable to plugins which do not actually use any PHP
code.
Implementing GUI functionality using PHP API
The mechanism of PHP plugins allows to extend Dune GUI with custom
applications implemented using PHP programming language and PHP API
provided by Dune HD STB. PHP plugins created using this mechanism are
stored in the STB flash memory and are running on the STB.
This PHP API does not allow PHP plugins to directly render an arbitrary TV
GUI and directly handle events from the remote control in arbitrary ways.
Instead, there is a high-level GUI framework with a fixed set of
possibilities, and PHP plugins may use these possibilities for custom GUI
creation.
The main goal of the PHP plugins mechanism is to allow to implement custom
IPTV/VOD applications, but it also could be used for other similar
purposes.
The possibilities provided by the PHP plugins mechanism include:
- Showing custom screens listing various objecs (e.g. TV channels,
movies, categories, etc). The possibilities for the customizing the
GUI of these screens are similar to those provided by the
"dune_folder.txt" mechanism (see
http://dune-hd.com/support/misc/dune_folder_howto.txt).
- Showing "movie information" screens.
- Showing custom screens and dialogs with some GUI controls for user
input (e.g. text fields, buttons, etc).
- Launching playback of TV and VOD content in a special mode (with
special TV and VOD OSD GUI).
The advantages for implementing custom applications (e.g. custom IPTV/VOD
applications) using PHP plugins mechanism are the following:
- Reduced implementation effort.
- No need to implement the GUI from the scratch, a high-level GUI
framework allows to very quickly and easily implement standard
IPTV and VOD functionality.
- Just feed the proper data into the GUI and everything is working
automatically.
- Smooth integration into Dune GUI.
- The look and feel of the custom application is the same as the
look and feel of other STB functions.
- Choosing a different GUI skin automatically affects the custom
application as well.
- All features of Dune GUI are automatically provided for the custom
application.
- High-quality graphics with FullHD (1920x1080) resolution.
- Fast GUI.
- Animation effects.
- GUI structure with 4 screen areas (path bar, widget zone with
date/time and weather information, main content box, optional
details panel at the right).
- Ability to integrate custom screens into STB Setup menu.
- PHP plugin is stored in the STB flash memory and runs on the STB.
- This allows to integrate with the existing server-side IPTV
middleware APIs, w/o the need to host anything on the web server.
- This allows to reduce the amount of the functionality that should
be hosted/executed on the web server.
- This allows to implement client-side caching and improve the
performance in other ways.
Installing plugins
One STB may have one or several plugins installed. plugins may be
preinstalled (included into STB firmware), or installed by the user (using
plugin installer).
For manual installation of a plugin, a special "plugin installer" file is
needed. The plugin installer file is just a ZIP archive containing
"dune_plugin.xml" file at the top level and other files (according to
plugins needs).
To install a plugin, just launch the plugin installer file
(dune_plugin*.zip) from any media (e.g. from USB flash drive). The plugin
will be installed into the flash memory of the STB. If plugin with the same
name was already installed manually, then an option will appear allowing to
overwrite plugin or cancel installation. Note, that the preinstalled
(included into STB firmware) plugins cannot be overwritten.
Note, the STB typically requires "Flash memory storage" (a special
partition in the flash memory of the STB) or "System storage" (an external
storage device used for system needs) to be activated in order to manually
install plugins. If neither is activated yet, the STB will propose to
activate "Flash memory storage" during plugin installation. For more
information about "Flash memory storage" and "System storage", please see
http://dune-hd.com/support/usb_flash_drive .
All installed plugins are listed in "Setup / Misc / Plugins" menu. This
menu allows to delete the previously manually installed plugins (select the
plugin, press ENTER, choose "Delete").
Providing additional plugins via "dune_plugins" folder
There is a special possibility which allows to add plugins to
the list of registered plugins, using a special "dune_plugins" folder. This
folder should be located at the top-level of the "main" storage device.
This folder should contain one or several subfolders, where each subfolder
should contain the data of one plugin (i.e. the dune_plugin.xml and other
plugin data).
NOTE: In order to ensure that the storage device is recognized as the
"main" one, it should be either the only storage device connected to the
player at the moment, or the only storage device connected to the player at
the moment when the player is switched on.
NOTE: This possibility is not recommended for normal users; it is mostly
intended for the development needs (e.g. when it is needed to edit the
plugin PHP code and look at the result).
NOTE: to apply changes made in "dune_plugins" folder one should press POWER
remote button twice: first to turn STB into standby mode and second to turn
it on again.
Redirecting plugin logs to "dune_plugin_logs" folder
There is a special possibility which allows to redirect logs produced by
all plugins which were installed manually to the special "dune_plugin_logs"
folder. This folder should be located at the top-level of the "main"
storage device. Normally, all logs are written to some temporary folder not
accessible from the outside. If "dune_plugin_logs" exists all logs from the
non-built-in plugins will be written to this folder.
NOTE: In order to ensure that the storage device is recognized as the
"main" one, it should be either the only storage device connected to the
player at the moment, or the only storage device connected to the player at
the moment when the player is switched on.
NOTE: This possibility is not recommended for normal users; it is mostly
intended for the development needs. It is recommended to use HDD instead of
Flash drive as "main" storage device for writing logs to.
Plugin files structure
The plugin contains the following files:
1. dune_plugin.xml (required)
- This is plugin manifest in XML format. This is the only file required
by the STB in order to load the plugin. All other plugin files (if
any) are specified in the plugin manifest, and can have any names.
2. For PHP plugins: the PHP program containing hd_create_plugin() function.
(required)
- The path to the file with this PHP program is specified in
"dune_plugin.xml".
3. Translation tables
- The files translations/dune_language_<lang>.txt will be automatically
loaded to the global STB translation table on STB start or when
interface language is changed by user. The keys provided in
translation files can be accessed using special syntax in public
string of PHP API.
See the "Interface language translations" section for more details.
4. Some resources accessible by HTTP in web and web/cgi-bin directories.
- These resources will be accessible using the following url schema:
http://<STB-address>/plugins/<plugin-name>/<path-from-www>
http://<STB-address>/cgi-bin/plugins/<plugin-name>/<path-from-cgi-bin>
See "HTTP server extension" section for more details.
5. Any other files, e.g. some resources (e.g. images/icons) (optional)
- These files may be referenced by "dune_plugin.xml" or other files, or
used in other ways by the PHP program.
Plugin manifest
The sample manifest of plugin called 'sample' may look as following:
<dune_plugin>
<name>sample</name>
<caption>Sample</caption>
<type>php</type>
<params>
<program>sample.php</program>
</params>
<entry_points>
<entry_point>
<parent_media_url>root://applications</parent_media_url>
<section_index>0</section_index>
<is_default_section>yes<is_default_section>
<icon_url>plugin_file://icons/logo_big.png</icon_url>
<small_icon_url>plugin_file://icons/logo_small.png</small_icon_url>
<caption>Sample Section</caption>
<actions>
<key_enter>
<type>plugin_handle_user_input</type>
<params>
<handler_id>root</handler_id>
<control_id>enter_from_section_screen</control_id>
</params>
</key_enter>
</actions>
</entry_point>
<entry_point>
<parent_media_url>root://tv</parent_media_url>
<media_url>main_tv</media_url>
<caption>Sample.TV</caption>
<icon_url>plugin_file://icons/sample_tv.png</icon_url>
<icon_margins><left>0</left><top>30</top><right>0</right><bottom>20</bottom></icon_url>
<icon_fit_scale_factor>1.0</icon_fit_scale_factor>
<badge_icon_url>gui_skin://large_icons/4.png</badge_icon_url>
<small_icon_url>plugin_file://icons/logo_small.png</small_icon_url>
<override_default_badge>no</override_default_badge>
<actions>
<key_enter>
<type>plugin_open_folder</type>
</key_enter>
<key_play>
<type>plugin_tv_play</type>
</key_play>
</actions>
<popup_menu>
<menu_items>
<item>
<caption>Clear TV Cache</caption>
<action>
<type>plugin_handle_user_input</type>
<params>
<op>clear_cache</op>
</params>
</action>
</item>
</menu_items>
</popup_menu>
<show_by_default>yes</show_by_default>
<show_cookie_name>show_tv_entry_point</show_cookie_name>
<ip_address_required>yes</ip_address_required>
<valid_time_required>yes</valid_time_required>
</entry_point>
<entry_point>
<parent_media_url>root://applications</parent_media_url>
<media_url>main_vod</media_url>
<caption>Sample.VOD</caption>
<icon_url>plugin_file://icons/sample_vod.png</icon_url>
<small_icon_url>plugin_file://icons/logo_small.png</small_icon_url>
<actions>
<key_enter>
<type>plugin_open_folder</type>
</key_enter>
</actions>
<show_by_default>yes</show_by_default>
<show_cookie_name>show_vod_entry_point</show_cookie_name>
<ip_address_required>yes</ip_address_required>
<valid_time_required>yes</valid_time_required>
</entry_point>
</entry_points>
<auto_resume>
<enable>yes</enable>
<ip_address_required>yes</ip_address_required>
<valid_time_required>yes</valid_time_required>
</auto_resume>
<operation_timeout>
<default>20</default>
<get_epg_day>30</get_epg_day>
</operation_timeout>
</dune_plugin>
Details:
- dune_plugin->name: plugin identifier. It should be nonempty and may
contain only alphanumeric and ('-', '.', '_') characters. Length is
limited by 64.
- dune_plugin->caption: caption used in Setup / Misc / Plugins
- dune_plugin->type and dune_plugin->params: the type of engine used to
execute plugin and it's parameters. Currently only the 'php' type is
supported having single mandatory 'program' parameter pointing to the
main php file of plugin.
- dune_plugin->entry_points: list of the plugin entry points in the Dune
menu. Each dune_plugin->entry_points->entry_point may contain the
following fields:
- 'parent_media_url': the URL of folder containing this entry
point. Now the following folders are allowed to contain plugin
items:
root://tv
root://applications
setup://applications
root://video (*) available in firmware 130424_b6+
root://music_and_radio (*) available in firmware 130424_b6+
root://news_and_weather (*) available in firmware 130424_b6+
root://social_networks (*) available in firmware 130424_b6+
root://games (*) available in firmware 130424_b6+
root://setup (*) available in firmware 130424_b6+
- 'section_index' (*) available in firmware 120901+
'is_default_section' (*) available in firmware 120901+
Specify the visualization of entry point in cas main screen style is
"Folders". Other main screen styles are not affected.
If 'section_index' is specified, then entry point is shown on the main
screen (together with sections 'TV', 'Applications', 'Sources', 'Setup'
etc...). The value of 'section_index' specifies the index number. The
'is_default_section' allows to force the entry point to be focused when
main screen is entered first time.
NOTE: in firmware versions other than 130906_b8+ the options
'section_index' and 'is_default_section' take effect only if
'parent_media_url' is root://applications.
- 'caption': entry point caption.
- 'icon_url'
'icon_margins' (*) available in firmware 120606+
'icon_fit_scale_factor' (*) available in firmware 120606+
'badge_icon_url' (*) available in firmware 120901+
'override_default_badge' (*) available in firmware 141005_b9+
visualization parameters of entry point in parent folder. For more
details see the description of similar ViewItemParams properties in
"Regular folder GUI customization" section.
- 'small_icon_url'
Specifies URL to small icon of plugin. Depending on appearance
settings, the plugin small icon can be shown in path box and, more
rarely, in content box of type 'List'.
The URLs of type plugin_file:// and gui_skin:// are supported.
NOTE: Available in firmware 131106_b6+
- 'media_url': identifier of menu node of the plugin menu hierarchy
Identifier should be unique in scope of plugin. The 'media_url'
will be used in some plugin operations.
- 'actions': the event->action mapping. The list of pairs: event_id =>
action specification. If entry point is focused and the specified key
is pressed then the corresponding action will be executed by Dune GUI.
See the "Plugin PHP program main features overview" section for more
details about how the Dune GUI works with the entry points.
See the "GUI Actions" section for more details about the concept of GUI
action and for the list of available GUI actions.
- 'popup_menu': the list of additional popup menu items to be addded to
the context menu of entry point.
- 'show_by_default' and 'show_cookie_name': this is a way for
plugin to show/hide entry points.
The 'show_cookie_name' is a name of plugin cookie (e.g. the
persistent property name) whose value is used as boolean
expression. The expression is evaluated to decide whether to
show entry point in Dune menu. The expression syntax is the
following:
yes
no
lang(<lang1>,...,<langN>).
The 'show_by_default' is used if 'show_cookie_name' is not set.
- 'show_action'
Allows to specify GUI action to be executed each time GUI framework
determines whether entry point is shown or not. The exit status of
action is used to decide whether to show entry point: zero status is
"yes", other status is "no". It is not recommended to use this way of
hiding entry points, use 'show_cookie_name' instead when possible.
NOTE: Available in firmware 130315_b6+
- 'ip_address_required': yes | no. If 'yes' is specified and the IP address
is not available yet then opening of this entry point will cause the
WaitIpAddress dialog to appear until the IP address is got or user
presses Cancel button or dialog is cancelled by timeout.
- 'valid_time_required': yes | no. If 'yes' is specified and the valid time
is not synchronized from internet yet then opening of this entry point
will cause the WaitValidTime dialog to appear until the valid time is
got or user presses Cancel button or dialog is cancelled by timeout.
- auto_resume: the specification of auto-resume feature which is disabled
by default. The following fields supported:
- enable: yes/no. This enables auto-resume feature. The default
implementations supporting all use-cases (live TV playback,
archive TV playback, VOD playback) will be used.
- action: GUI action. This GUI action will be executed in case of
auto-resume instead of the default algorithm.
- ip_address_required: yes/no. If yes => the wait_ip_address dialog is
shown if needed in auto-resume use-case.
- valid_time_required: yes/no. If yes => the wait_valid_time dialog is
shown if needed in auto-resume use-case.
- operation_timeout: allows to change the default timeout for plugin
operations. The operation timeout is 10 seconds by default. The default
operation timeout can be changed to N using <default>N<default>. Also the
operation timeout can be specified for each operation type. To change the
timeout for operation 'op' to N use construction: <op>N</op>. Exapmle:
<operation_timeout>
<default>20</default>
<get_epg_day>30</get_epg_day>
<handle_user_input>40</handle_user_input>
</operation_timeout>
As a result, all operations has timeout 20 seconds, except the
get_epg_day() (30 seconds) and handle_user_input() (40 seconds).
High-level design overview for PHP plugins
There is central Dune GUI component, that does all the job to handle remote
control, draw graphics, show video streams and so on.
The Dune GUI can also manage multiple PHP plugins.
Every PHP plugin runs in a separate process, where PHP engine is
initialized.
The Dune GUI communicates to PHP plugins using IPC (inter-process
communication), in particular: UNIX pipes. The protocol is in plain text
and uses JSON to represent structured data.
The communication is actually one-way: Dune GUI makes a request (or a
call) and asynchronously waits for a PHP plugin to reply. If the PHP plugin
failed to reply within pre-defined timeout, an error is reported.
PHP plugins are not able to initiate a call to Dune GUI.
Basically, a call from the Dune GUI to a PHP plugin can be formulated
by the following meta-declaration:
string call_plugin(in string call_ctx_json);
- The Dune GUI prepares a structure of some sort, where it specifies
operation code and operation parameters (so called "input-data");
- This structure is then encoded (serialized) to a string using JSON;
- The string is passed to the PHP plugin using IPC;
- PHP plugin deserializes the string to a structure, retrieves operation
code and operations parameters, executes the operation to get another
structure (so called "output-data") to be passed back to the Dune GUI;
- The output structure is again serialized to a string using JSON, and
is passed back to the Dune GUI;
- The Dune GUI deserializes the string into a structure and uses the data
to do needed actions.
Thus, ultimately, the PHP plugin need to implement the only one function:
string call_plugin(in string call_ctx_json);
(actual name see below in the "System PHP files" section)
However, it's too cumbersome and error-prone to implement the same logic
for every plugin over and over again, so SDK provides a framework, which
does all the job of marshalling data and invoking the right operation.
System PHP files
STB includes several system PHP files which are automatically sourced by
the PHP engine instance before plugin PHP program loading. PHP definitions
and symbols provided by these system PHP files are automatically available
to plugin PHP program.
In the STB firmware, these PHP files are located in "/firmware_ext/php"
directory.
These files basically defines an interface between Dune GUI and plugin PHP
programs.
The files are:
- bootstrap.php
- Setups error reporting within PHP engine so that all errors are
logged to the internal log file.
- Setups correct (current) timezone.
- Provides the following global functions:
- hd_print($text_message)
This function should be used instead of PHP functions 'echo',
'print', 'printf' etc.
By using this function developer makes sure the text gets to the
log file in the proper format.
This function uses global $HD_NEW_LINE contant, which is an empty
string ('') by default.
- hd_silence_warnings()
This function should be used to temporarily disable warning from
system PHP functions.
- hd_restore_warnings()
This function restores warning logging after
hd_silence_warnings().
- The following global functions are also defined in bootstrap.php,
but usually should not be used explicitly in PHP plugins:
- hd_error_handler()
- hd_shutdown_handler()
- hd_error_silencer()
- dune_plugin.php
- Defines high-level interface between the Dune GUI and plugin PHP
programs -- DunePlugin interface -- a set of operations, which
the Dune GUI can call against the PHP program.
If default framework (see below) is in use, all calls from the Dune
GUI to a plugin PHP program are dispatched to an instance of
DunePlugin interface.
- dune_plugin_fw.php
- Provides low-level interface (in terms of strings) between the Dune
GUI and plugin PHP programs.
- Provides utility functions.
- dune_api.php
- Contains definitions of various string constants which are
helpful for passing the data between the plugin PHP program and
Dune GUI.
Plugin PHP program basics
Every plugin PHP program eventually must do the following steps:
- Provide a class derived from DunePluginFw;
- Implement DunePluginFw::call_plugin() in the derived class;
- Assign an instance of the new class to DunePluginFw::$instance;
DunePlugin interface
On the high-level, the interface between the Dune GUI and a plugin PHP
program is specified by the DunePlugin interface, declared in
dune_plugin.php file.
Currently the DunePlugin interface looks as follows:
interface DunePlugin
{
// PluginFolderView
public function get_folder_view(
/* [in] String */ $media_url,
/* [inout] Map: Key -> Value */ &$plugin_cookies);
// PluginFolderView
public function get_next_folder_view(
/* [in] String */ $media_url,
/* [inout] Map: Key -> Value */ &$plugin_cookies);
// PluginTvInfo
public function get_tv_info(
/* [in] String */ $media_url,
/* [inout] Map: Key -> Value */ &$plugin_cookies);
// String
public function get_tv_stream_url(
/* [in] String */ $playback_url,
/* [inout] Map: Key -> Value */ &$plugin_cookies);
// PluginVodInfo
public function get_vod_info(
/* [in] String */ $media_url,
/* [inout] Map: Key -> Value */ &$plugin_cookies);
// String
public function get_vod_stream_url(
/* [in] String */ $media_url,
/* [inout] Map: Key -> Value */ &$plugin_cookies);
// PluginRegularFolderRange
public function get_regular_folder_items(
/* [in] String */ $media_url,
/* [in] int */ $from_ndx,
/* [inout] Map: Key -> Value */ &$plugin_cookies);
// List<PluginTvEpgProgram>
public function get_day_epg(
/* [in] String */ $channel_id,
/* [in] int */ $day_start_tm_sec,
/* [inout] Map: Key -> Value */ &$plugin_cookies);
// String
public function get_tv_playback_url(
/* [in] String */ $channel_id,
/* [in] int */ $archive_tm_sec,
/* [in] String */ $protect_code,
/* [inout] Map: Key -> Value */ &$plugin_cookies);
// void
public function change_tv_favorites(
/* [in] String */ $op_type,
/* [in] String */ $channel_id,
/* [inout] Map: Key -> Value */ &$plugin_cookies);
// GuiAction
public function handle_user_input(
/* [in] Map: Key -> Value */ &$user_input,
/* [inout] Map: Key -> Value */ &$plugin_cookies);
}
The output type of plugin operation:
class PluginOutputData
{
Boolean has_data;
PluginOutputDataType data_type;
Object data;
Map<String, String> plugin_cookies;
Boolean is_error;
GuiAction error_action;
}
Each plugin operation should return one of the following:
- normal output: 'is_error' is false, 'error_action is null, 'has_data'
is true, 'data' contains the normal output data of type specified in
'data_type';
- error output: 'is_error' is true, error_action may be set to some GUI
action to be executed.
Plugin PHP program lifecycle
Each PHP plugin is executed in its own instance of PHP engine (running in a
its own separate process). The PHP engine instance for each PHP plugin is
created when the PHP plugin is used for the first time.
PHP plugin always handles just one call from Dune GUI at a time. Multiple
calls from Dune GUI to PHP plugin are always serialized.
Typically, subsequent calls from Dune GUI to PHP plugin are delivered to
the same PHP engine instance. Thus, global PHP variables are preserved
between subsequent calls.
However, each PHP engine instance may be destroyed/recreated at any moment
(between calls from Dune GUI to PHP plugin) when this is needed by Dune
GUI. When this happens, global PHP variables are not preserved.
So, PHP plugin must not assume that global PHP variables are preserved
between subsequent calls from Dune GUI to PHP plugin. PHP plugin is allowed
to use global PHP variables e.g. for the implementation of some caches (may
be helpful for performance reasons), but it must be prepared that these
global variables disappear between subsequent calls and implement a proper
strategy for repopulating the caches when needed.
When possible, PHP plugin should be designed as a stateless program. When
some transient global state is needed and it is critical to preserve this
state between subsequent calls to PHP plugin, this should be implemented in
a special way, e.g.:
- The state should be encoded in parameters which are passed between
PHP plugin and Dune GUI, so Dune GUI keeps the state.
- The state should be stored in the directory for temporary transient
data (RAM disk in the STB).
- The state should be stored on the Internet server (if PHP plugin
interacts with some Internet server).
Plugin PHP program environment
1. Cookies.
- each plugin has a list of persistent string settings known as plugin
cookies. This map(string => string) is passed by reference to each plugin
operation. So, operations may use cookie values and can modify them.
The cookies keep their values between operations and even survive the
STB restart.
NOTE: plugin cookies are not supposed to keep large amount of data
2. System properties.
- the PHP plugin code has access to the DuneSystem::$properties array.
Currently the following properties are provided:
'plugin_name' - current plugin name;
'install_dir_path' - path to directory where plugin is installed to;
'tmp_dir_path' - path to directory under /tmp which is designed for
storing plugin's temporary data. Dune GUI ensures that directory
exists.
'data_dir_path' - path to directory for storing persistent data.
NOTE: this directory is not available on STBs without System
Storage and Flash Memory Storage. In the latter case
'data_dir_path' is unset.
'plugin_www_url' - the common HTTP prefix for WWW-files included into
plugin (for local access);
'plugin_cgi_url' - the common HTTP prefix for CGI scripts included
into plugin (for local access).
In particular, the 'plugin_www_url' and 'plugin_cgi_url' contains
strings:
http://127.0.0.1/plugins/<plugin_name>/
http://127.0.0.1/cgi-bin/plugins/<plugin_name>/
NOTE: After each write into persistent location, "sync" UNIX command or
system call should be performed immediately.
Plugin PHP program main features overview
Each method in DunePlugin interface corresponds to the so-called plugin
operation. Each operation has input type (simple) and output type
(sometimes considerably complex). The output data should be returned from
DunePlugin method as PHP array. The keys for output PHP arrays are defined
in the dune_api.php.
The PHP plugin may extend the base Dune functionality in the following
ways:
- extend Dune menu hierarchy (the Dune menus also known as 'folders').
Some of general Dune folders (in particular, the 'TV', 'Applications'
and 'Setup->Applications') may be extended by adding new elements which
are called 'plugin entry points'. Each entry point is owned by one
plugin. Typically entry points contain folder hierarchy managed by
plugin.
- launch plugin-TV playback. Plugin-TV playback is the special playback
mode allowing to play TV channels, browse list of channels united into
categories (also known as groups), browse channel EPG etc.
- launch plugin-VOD playback. Plugin-VOD playback is the special playback
mode allowing to play movie or a series (list of episodes united by
single title).
The default look and behaviour of general Dune folders is extended by
plugins in the following way:
- new folder element is added for each registered plugin and each entry
point in plugin manifest. The icon URL and caption for each entry point
are taken from manifest;
- the owner plugin takes control over user input when entry point is
focused. Currently plugin may override the standard behaviour of the
following remote keys in general folders: ENTER, PLAY.
The technique used by plugins to affect the behaviour of Dune GUI is base
on the concept of GUI actions. For more details about GUI actions see the
"GUI actions" section.
Briefly the GUI action is the instruction for Dune GUI what to do when user
presses remote button in particular state of GUI. GUI action is typically
created in PHP code as array with the following fields:
- handler_string_id : [string] type of action
- data: [array] PHP array of type-specific action parameters.
There is a number of GUI action types including:
- PLUGIN_OPEN_FOLDER. Browses into some GUI element. Opens a new folder
(submenu) fully managed by plugin. Such folders are called 'plugin
folders'.
- PLUGIN_TV_PLAY. Launches the plugin-TV playback.
- PLUGIN_VOD_PLAY. Launches the plugin-VOD playback.
Also there is one special action type called HANDLE_USER_INPUT. Execution
of HANDLE_USER_INPUT involves:
- running some arbitrary plugin code. Specifically, the
handle_user_input() plugin operation is executed having current Dune
GUI state as a parameter;
- immediate execution of another GUI action specified by plugin.
Actually, the return value of handle_user_input() operation is
executed as GUI action.
The plugin folder has string identifier which is non-obviously called
'media_url'. So let's assume that every plugin folder (including entry
point) has 'media_url' value unique in scope of plugin.
The plugin folders are divided into 3 general types:
1. Regular folder.
The most common type of folder used to show the list of objects of any
kind as table with fixed number of rows and columns. Each table cell may
contain image and text. The visualization of regular folder can be
adjusted using large number of settings. Also plugin may specify several
variants of folder representation; these variants can be switched by
pressing A_RED remote button. Let's call variant of regular folder
representation 'folder view'.
The regular plugin folder behaves similar to general Dune folders but
the effect of pressing several remote keys should be explicitly
specified by plugin; otherwise they will be ignored. These remote keys
are: ENTER, PLAY, INFO, POPUP_MENU, B_GREEN, C_YELLOW, D_BLUE. In other
words plugin may assign GUI actions to the listed keys.
The regular folders can be divided into:
- simple (preloaded): the whole content of folder is returned at once;
- lazy loaded with known size: the number of folder elements is known
but it is considerably big and folder content is loaded by chunks
when user scrolls;
- lazy loaded with unknown size: the same as before but the number of
total elements is unknown until end is reached.
The most regular folders are simple; however Dune plugin framework
have support for lazy-loading of regular folders.
2. Control folder.
The folder type designed to be used in setup. The control folder looks
as vertical list of GUI controls and constant text strings.
The following controls are supported:
- button.
- combobox
- text field
Plugin may assign specific GUI actions to the following events:
- button pressed;
- combobox value changed;
- text field value changed.
The HANDLE_USER_INPUT GUI action should be used to apply/save changes.
3. Movie folder.
The special layout for representing the detailed information about
movie. The following movie properties can be shown in such folder:
- movie name
- movie name in the original language
- poster image
- list of genres
- country
- year
- director(s)
- actors
etc..
The layout also includes one or two buttons:
- mandatory button 'PLAY' in the left-bottom corner with the following
predefined handling. When pressed the number of movie series is
cheched:'
- (number_of_series > 1) => folder with list of series is opened;
- (number_of_series = 1) => VOD-playback is launched for movie.
- optional button with custom caption and GUI action in the
right-bottom corner. This button may be used to implement 'Add to
favorites' and 'Remove from favorites' use-cases.
To support the folder hierarchy the plugin PHP program should implement at
least the DunePlugin::get_folder_view($media_url).
To support the multiple folder views the plugin PHP program should
implement DunePlugin::get_next_folder_view($media_url).
To support lazy-loading of regular folders the plugin PHP program should
implement DunePlugin::get_regular_folder_items($media_url) consistently
with the DunePlugin::get_folder_view($media_url).
To apply/save changes in setup settings the plugin PHP program should
implement DunePlugin::handle_user_input($params).
The TV playback has optional features:
- EPG browsing;
- archive playback;
- protected channels;
etc.
Both TV and VOD playback modes have optional feature:
- variable stream URLs.
To support minimal TV playback the plugin PHP program should implement
DunePlugin::get_tv_info($media_url) and
DunePlugin::get_tv_playback_url($media_url, $archive_tm_sec, $protect_code).
To support EPG browsing the plugin PHP program should implement
DunePlugin::get_day_epg($channel_id, $day_start_tm_sec);
To support archive playback the DunePlugin::get_tv_playback_url(...) should
accept non-zero $archive_tm_sec argument (consistently with the returned
data from get_tv_info());
To support protected channels feature the
DunePlugin::get_tv_playback_url(...) should accept non-empty $protect_code.
To support variable TV stream URLs the plugin PHP progam should implement
DunePlugin::get_tv_stream_url($playback_url).
To support VOD playback the plugin PHP program should implement
DunePlugin::get_vod_info($media_url).
To support variable VOD stream URLs the plugin PHP progam should implement
DunePlugin::get_vod_stream_url($playback_url).
Typical PHP program notes
The typical plugin PHP consists of the following.
1. The manifest file dune_plugin.xml containing:
- plugin name
- plugin caption
- plugin type (php) and the main PHP program file (<plugin_name>.php)
- the list of entry points
- the auto_resume specification
If plugin provides IPTV service then it adds entry point to the TV menu.
This entry point reacts as PLUGIN_OPEN_FOLDER to the ENTER remote key and
PLUGIN_TV_PLAY to the PLAY remote key.
If plugin provides some non-IPTV services then it adds one or more entry
points to the Applications menu.
Also typical plugin adds one entry point to the Setup->Applications menu.
The plugins providing playback of video/audio streams should usually turn
on the 'auto_resume' feature to allow the automatic resume of playback
state after STB restart.
2. Folder hierarchy.
Usually the TV entry point contains 2-level regular folder hierarchy:
- 1st level contains list of TV channel categories. Each category item
acts as folder when ENTER pressed. The TV playback is launched when
PLAY is pressed;
- 2ns level contains channels. Each channel item react as TV_PLAY to the
both ENTER and PLAY remote keys.
The entry points providing access to VOD services may have folder hierarchy
of arbitrary depth splitting the movie database into categories. Each
category is represented as regular folder having subcategories and movies
as elements. The movie element opens the folder or Movie type. Movie
playback can be launched from inside the movie folder.
3. Playback.
Typically the TV playback is launched:
- by pressing ENTER/PLAY remote button on the regular folder
element representing channel;
- by pressing PLAY on the regular folder element representing channel
category;
- by pressing PLAY on the TV entry point.
Typically the VOD playback is launched:
- by pressing ENTER/PLAY remote button on the regular folder element
representing movie or movie series;
- by pressing ENTER/PLAY on the PLAY button in the movie folder.
Also the TV/VOD playback can be launched automatically on STB power-on in
the autoresume use-case.
4. Setup screen.
The entry point to the setup screen is located in Setup->Applications menu.
Setup screen is implemented as plugin folder of 'Control folder' type.
Typically setup screen contains 'Show in main screen' combobox with Yes/No
values.
The HANDLE_USER_INPUT GUI action and the corresponding handle_user_input()
plugin operation should be used to apply changes and save settings in the
persistent location.
Typically the plugin cookies are used to keep setup settings locally.
Plugin operations
The short description of the plugin operations.
NOTE: see the dune_api.php for the complete list of fields for each output
data type.
1. Get_folder_view()
// PluginFolderView
public function get_folder_view(
/* [in] String */ $media_url,
/* [inout] Map: Key -> Value */ &$plugin_cookies);
Returns current folder content representation data for the plugin menu
folder identified by $media_url.
This operation is called when Dune GUI executes PLUGIN_OPEN_FOLDER GUI
action.
Output data:
class PluginFolderView
{
PluginFolderViewKind view_kind;
union (PluginFolderViewKind) data;
Boolean multiple_views_supported;
PluginArchiveDef archive;
}
The 'archive' is the optional specification of the plugin archive used
with this folder. See "Plugin archives" section for more details about
plugin archives.
The 'multiple_views_supported' specifies whether the multiple views are
are available for this folder. See description of GET_NEXT_FOLDER_VIEW
plugin operation for more details.
The 'view_kind' can be one of the following:
- PLUGIN_FOLDER_VIEW_REGULAR
- PLUGIN_FOLDER_VIEW_CONTROLS
- PLUGIN_FOLDER_VIEW_MOVIE
The 'data' is specific for view_kind:
- regular folders: PluginRegularFolderView
- control folders: PluginControlsFolderView
- movie folders: PluginMovieFolderView
Regular folder data
~~~~~~~~~~~~~~~~~~~
class PluginRegularFolderView
{
ViewParams view_params;
ViewItemParams base_view_item_params;
ViewItemParams not_loaded_view_item_params;
GuiActionMap actions;
GuiTimerDef timer;
Boolean async_icon_loading;
Boolean async_icon_loading_pipelining;
int async_icon_loading_max_connects;
PluginRegularFolderRange initial_range;
}
The 'initial_range' specifies the initial range of folder elements.
The initial range for simple (preloaded) folders should contain all
folder elements. The initial range for lazy-loaded folders should
contain the first chunk of data or even the empty list. See the
description of Get_regular_folder_items() plugin operation.
The 'view_params' specifies the whole folder representation paramsters
such as num_cols, num_rows, async_icon_loading etc..
The 'async_icon_loading' specifies whether to use asynchronous icon
loading by default. See "Asynchronous image loading" section for more
details.
The 'async_icon_loading_pipelining' specifies value used as
CURLMOPT_PIPELINING for asynchronous image loading (see libcurl
documentation for more details). The default value is true.
NOTE: Available in firmware 120616+.
The 'async_icon_loading_max_connects' specifies value used as
CURLMOPT_MAXCONNECTS for asynchronous image loading (see
libcurl documentation for more details). The default value is 8.
NOTE: Available in firmware 120616+.
The 'base_view_item_params' specifies the default values for
representation parameters of each folder element.
The 'not_loaded_view_item_params' specifies the representation of the
special state of each folder element. It is used when element's image
is (1) not yet loaded or (2) loaded with error (loading failed).
NOTE: currently this value is ignored if
ViewParams::async_icon_loading == false.
The 'actions' specifies the {event -> GUI action} mapping for interaction
with user.
The 'timer' allows to specify timer event delay. The timer event will
be generated only once, but timer can be reset using ChangeBehaviour
GUI action.
Control folder data
~~~~~~~~~~~~~~~~~~~
class PluginControlsFolderView
{
Array<GuiControlDef> defs;
int initial_sel_ndx;
PluginFolderViewParams params;
}
class PluginFolderViewParams
{
Boolean paint_path_box;
Boolean paint_content_box_background;
String background_url;
}
The 'defs' specifies list of GUI control definitions. See the
"GUI controls" section for more details.
The 'initial_sel_ndx' specifies the 0-based index of GUI control to
gain focus first. The special value of -1 value indicates that default
(first) GUI control should be focused first.
Movie folder data
~~~~~~~~~~~~~~~~~
class PluginMovieFolderView
{
PluginMovie movie;
String left_button_caption;
GuiAction left_button_action;
Boolean has_right_button; String
String right_button_caption;
GuiAction right_button_action;
Boolean has_multiple_series;
Boolean series_media_url;
VAlign poster_valign;
PluginFolderViewParams params;
}
class PluginFolderViewParams
{
Boolean paint_path_box;
Boolean paint_content_box_background;
String background_url;
}
The 'movie' specifies a number of movie properties. See the list of
movie properties below.
The 'left_button_caption' specifies caption of the left button. This
property is optional, the 'Play' is used by default.
The 'left_button_action' specifies GUI action assigned with left
button. This value is optional, the VOD_PLAY gui action is used by
default.
The 'has_right_button' specifies whether button in the right-bottom
corner of movie folder page should be painted.
The 'right_button_caption' specifies caption of the right button.
The 'right_button_action' specifies GUI action assigned with right
button.
The 'has_multiple_series' specifies the effect of pressing ENTER remote
key on the PLAY GUI button located in the left-bottom corner of movie
folder page:
- when FALSE => PLUGIN_VOD_PLAY GUI action is executed
- when TRUE => PLUGIN_OPEN_FOLDER GUI action is executed with
explicit media_url taken from 'series_media_url' parameter.
This scheme is designed to implement use-case of series, i.e. movie
divided into series. In this case pressing ENTER remote key should have
effect of opening the list of series.
The 'series_media_url' is used with 'has_multiple_series' = true. It
identifies the folder which should be opened when user press ENTER
remote button having PLAY button focused.
The 'poster_valign' specifies vertical alignment of poster. It is used
when poster aspect ratio does not respect the default poster
placeholder.
NOTE: Available in firmware 120610+.
class PluginMovie
{
String name;
String name_original;
String description;
String poster_url;
int length_min;
int year;
String directors_str;
String scenarios_str;
String actors_str;
String genres_str;
String rate_imdb;
String rate_kinopoisk;
String rate_mpaa;
String country;
String budget;
Map<String,String> details;
Map<String,String> rate_details;
}
- The 'details': additional pars in the main (scrollable) area.
- The 'rate_details': additional lines in the ratings area (under
poster).
2. Get_next_folder_view()
// PluginFolderView
public function get_next_folder_view(
/* [in] String */ $media_url,
/* [inout] Map: Key -> Value */ &$plugin_cookies);
Returns next folder view for the plugin menu folder identified by
$media_url.
Some regular folders may have several views (e.g. with different
num_rows, num_cols, different size of icons etc..). Such views can be
switched by pressing A_RED remote button. To enable this feature for
particular folder, plugin should specify
PluginFolderView::multiple_views_supported == true. In this case
pressing A_RED will cause Get_next_folder_view() to be called.
See Get_folder_view() plugin operation description for more details.
3. Get_regular_folder_items()
// PluginRegularFolderRange
public function get_regular_folder_items(
/* [in] String */ $media_url,
/* [in] int */ $from_ndx,
/* [inout] Map: Key -> Value */ &$plugin_cookies);
Returns the specified chunk of folder element for the folder identified
by $media_url.
This is part of lazy-loading feature of regular folders.
Dune GUI never calls this operation for simple (preloaded) folder.
The Get_regular_folder_items() operation is called for lazy-loaded
folder each time some not yet loaded elements should be visualized
(typically when user scrolls though the folder elements). The folders
element are cached in memory until folder is exitted.
See Get_folder_view() operation description for more details.
4. Get_tv_info()
// PluginTvInfo
public function get_tv_info(
/* [in] String */ $media_url,
/* [inout] Map: Key -> Value */ &$plugin_cookies);
Returns data needed to launch plugin TV playback. The $media_url
argument is used as hint about what channel should be played first.
This operation is called when Dune GUI executes PLUGIN_TV_PLAY GUI
action.
The output data of get_tv_info:
class PluginTvInfo
{
unixtime_t server_time;
List<PluginTvGroup> groups;
List<PluginTvChannel> channels;
Boolean show_group_channels_only;
Boolean favorites_supported;
List<String> favorite_channel_ids;
String favorites_icon_url;
String initial_group_id;
String initial_channel_id;
Boolean initial_favorites;
unixtime_t initial_archive_tm;
GuiActionMap actions;
GuiTimerDef timer;
Boolean ip_address_required;
Boolean valid_time_required;
EpgMode epg_mode;
PluginFontSize epg_font_size;
Boolean epg_day_use_local_tz;
int epg_day_shift_sec;
Boolean custom_protect_code_handling;
Boolean subtitles_osd_enabled;
PluginArchiveDef archive;
}
The 'server_time' specify the current time to be used during TV
playback. The local time is used if server time is non-positive.
The 'groups' and 'channels' specify the list of channels and the list
of channel groups. See the description of group and channel properties
below.
The 'show_group_channels_only' specifies the way channels are grouped.
The plugin TV browser OSD consists of 3 columns:
- 1st column contains list of groups;
- 2nd column contains list of channels for the selected group;
- 3rd column contains list of EPG programs for the selected
channel and the choosen day.
- if ['show_group_channels_only' == false] the 2nd column contains
all channels sorted by groups not depending on what group is
selected. This mode requires the 1-to-N relationship between
groups and channels, i.e. each channel should belong to exactly
one group. The group selection in 1st column is adjusted
automatically when user scrolls channel list in 2nd column.
- if ['show_group_channels_only' == true] the 2nd column contains
channels of the selected group only. This mode suports N-to-N
relationship between groups and channals: channal can be included
into multiple groups. As a consequence user has to move focus
between 2nd and 1st columns by pressing LEFT/RIGHT to select
channel from another group.
When 'favorites_supported' enables *favorites* feature including:
- special "favorites" group added to the list of groups;
- special key handling for modification of the list of favorite
channels. In particular Dune GUI calls Change_tv_favorites()
operation when user press D_BLUE, B_GREEN, C_YELLOW remote keys.
The implementation of Change_tv_favorites() should write the
list of favorite channels to the persistent storage (e.g. by
means of cookies).
The 'favorite_channel_ids' specify the list of favorite channels.
The 'favorites_icon_url' specify the icon for "favorites" group.
The 'initial_group_id', 'initial_channel_id', 'initial_favorites' and
'initial_archive_tm' specify the initial state of playback and selection.
All these properties are optional; if property is unset then it is
automatically set to the appropriate value.
If positive value given, the 'initial_archive_tm' specify that archive
playback should be started from the given timestamp (GMT unixtime).
The 'actions' specifies the {event -> GUI action} mapping for interaction
with user.
NOTE: Available in firmware 131029_b9+.
The 'timer' allows to specify timer event delay. The timer event will
be generated only once, but timer can be reset using ChangeBehaviour
GUI action.
NOTE: Available in firmware 131029_b9+.
The 'ip_address_required' and 'valid_time_required' specify the
additional requirements for the TV playback. See the desciption of the
similar fields in plugin manifest for more details. In particular, it
is common that some plugins do not require valid current time for
browsing groups/channels in Dune menu but they do requre valid time for
TV playback.
The 'epg_mode' it can take 3 values:
- "disabled":
the get_day_epg() calls are avoided, but EPG-column is still
shown with "No program available." text. This mode should be
used if no EPG is available at all. The concrete
behaviour may be changed in future.
(*) update in firmware 130726_b6+: EPG column not shown at all
- "use_day_request": the default mode.
- "get_from_stream": not implemented yet.
The 'epg_font_size' specify EPG font size.
PHP constants available: FONT_SIZE_NORMAL, FONT_SIZE_SMALL
The 'epg_day_use_local_tz', 'epg_day_shift_sec' specify a start of EPG
day. If epg_day_use_local_tz is false, EPG day is started from 00:00
(GMT) + epg_day_shift_sec, otherwise it is started from 00:00 (current
time zone) + epg_day_shift_sec.
NOTE: Available in firmware 121114+.
The 'custom_protect_code_handling' enables the more flexible protect
code handling for channels with 'is_protected'=true: if
get_tv_playback_url() return string 'protected' then protect-code
dialog is shown, if return other string => stream is considered
non-protected.
NOTE: Available in firmware 121116+.
The 'subtitles_osd_enabled' enables/disables the subtitles OSD feature:
OSD control which shows the list of available subtitles and allows to
switch between them. Enabled by default.
NOTE: Available in firmware 140521_b9+.
NOTE: The subtitles OSD was not available for plugins in earlier
firmware versions.
Each group has the following properties:
class PluginTvGroup
{
String id;
String caption;
String icon_url;
}
The 'id' specifies group identifier.
The 'caption' and 'icon_url' specify group representation.
Each channel has the following properties:
class PluginTvChannel
{
String id;
String caption;
List<String> group_ids;
String icon_url;
int number;
Boolean have_archive;
Boolean is_protected;
Boolean recording_enabled;
int buffering_ms;
int timeshift_hours;
int past_epg_days;
int future_epg_days;
int epg_icon_width;
int epg_icon_height;
int epg_icon_x_offset;
int epg_icon_y_offset;
int archive_past_sec;
int archive_delay_sec;
Boolean playback_url_is_stream_url;
}
The 'id' specifies channel identifier.
The 'caption' and 'icon_url' specify channel representation.
The 'group_ids' specifies groups this channel belongs to. There should be
at least one group specified. Some plugins allow channel to belong to
multiple groups, the others are not. See the description of
PluginTvInfo::show_group_channels_only for more details.
The 'number' allows to assign the concrete number to TV channel. If
number <= 0 => the number will be assigned automaticaly to the first
unused positive integer.
The 'have_archive' enables archive feature for this channel. If
enabled, the corresponding support in the implementation of
Get_tv_playback_url() operation whould be provided. See "Plugin TV
archive playback" section for more details about TV archive playback.
The 'is_protected' marks this channel as protected, i.e. restricted for
users who do not know the key. If plugin have some protected channels,
the corresponding support in the Get_tv_playback_url() should be
provided.
The 'recording_enabled' specifies whether recording is enabled for this
channel.
The 'buffering_ms' specify the prebuffering time for channel playback.
The 'timeshift_hours' specify the timeshift in hours. NOTE: not
implemented yet.
The 'past_epg_days', 'future_epg_days' specify the limits of
scrolling the EPG. The default values are 14.
The 'epg_icon_width', 'epg_icon_height': positive integers, dimensions
for the EPG program icons.
The 'epg_icon_x_offset', 'epg_icon_y_offset': signed integers allowing
to adjust position of EPG program icons.
See description of PluginTvEpgProgram::icon_url for more details.
NOTE: the 'epg_icon_*' properties available in firmware 150527_r10+.
The 'archive_past_sec' specifies the maximum time interval from current
moment and the last moment in the past the archive is available for.
See "Plugin TV archive playback" section feature for more details about
TV archive playback.
The 'archive_delay_sec' specifies the time interval in seconds between
the current moment and the nearest moment in past the archive is
available for. See "Plugin TV archive playback" section feature for
more details about TV archive playback.
So EPG program is considered to have archive if it has
EpgProgram::have_archive flag set or if EpgProgram::start_tm_sec
belongs to range [ current_time - PluginTvChannel::archive_past_sec,
current_time - PluginTvChannel::archive_delay_sec ]
The 'playback_url_is_stream_url' specifies whether the playback URL is
stream URL for this channel.
5. Get_day_epg()
// List<PluginTvEpgProgram>
public function get_day_epg(
/* [in] String */ $channel_id,
/* [in] int */ $day_start_tm_sec,
/* [inout] Map: Key -> Value */ &$plugin_cookies);
Returns list of EPG program structures for the given channel and given
day.
The day is specified by the unixtime of it's beginning (0:00). I.e. the
$day_start_tm_sec is always divisible by 86400.
The output should be a (possibly empty) list of structures sorted by
time in ascending order:
class PluginTvEpgProgram
{
unixtime_t start_tm_sec;
unixtime_t end_tm_sec;
String name;
String description;
Boolean have_archive; // Optional, default: false.
String icon_url; // Optional.
}
The 'start_tm_sec' and 'end_tm_sec' are the program start/end time in
unixtime format.
The 'end_tm_sec' is optional (the -1 value means unset).
The 'name' is required non-empty program name.
The 'description' is optional program description.
The 'have_archive' whether archive is available for program.
This flag is used together with pair of properties
'archive_past_sec' and 'archive_delay_sec' of PluginTvChannel: the
program is considered to have archive if it has 'have_archive' flag or
it's 'start_tm_sec' belongs to range
[ current_time - archive_past_sec, current_time - archive_delay_sec ]
NOTE: 'have_archive' property is available in firmware
150526_r10+.
The 'icon_url': URL of the small image to be painted in the EPG program
block. This icon replaces the standard 'R' sign of the archived
program, but can be used for non-archived programs too.
This property is used together with 'epg_icon_width',
'epg_icon_height', 'epg_icon_x_offset', 'epg_icon_y_offset' of
PluginTvChannel. The icon_url is ignored until epg_icon_width and
epg_icon_height are specified.
NOTE: 'icon_url' property is available in firmware 150527_r10+.
6. Change_tv_favorites()
// GuiAction
public function change_tv_favorites(
/* [in] String */ $op_type,
/* [in] String */ $channel_id,
/* [inout] Map: Key -> Value */ &$plugin_cookies);
Updates the list of favorite TV channels.
Is called from TV playback mode when user press B_GREEN, C_YELLOW,
D_BLUE remote buttons.
The return value is the optional GUI action to be executed immediately.
The following update operations supported:
- PLUGIN_FAVORITES_OP_ADD
- PLUGIN_FAVORITES_OP_REMOVE
- PLUGIN_FAVORITES_OP_MOVE_UP
- PLUGIN_FAVORITES_OP_MOVE_DOWN
The implementation of change_tv_favorites() should update it's own
persistent copy of favorites. There list of favorites inside Dune GUI
will be updated automatically.
7. Get_tv_playback_url()
// String
public function get_tv_playback_url(
/* [in] String */ $channel_id,
/* [in] int */ $archive_tm_sec,
/* [in] String */ $protect_code,
/* [inout] Map: Key -> Value */ &$plugin_cookies);
Returns the playback URL for the given channel as string.
This operation is called for getting playback URL of:
- live playback if $archive_tm_sec <= 0;
- archive playback if $archive_tm_sec > 0.
See "Plugin TV archive playback" section for more details about TV
archive playback.
The nonempty protect_code can be specified for protected channels. See
"Protected TV channels" section for more details about protected TV
channels.
This operation is called each time the playback of particular channel
is started or resumed.
NOTE: some channels require to perform additional call to
Get_tv_stream_url() for getting the actual stream URL having playback
URL as the parameter. This use-case is indicated by
PluginTvChannel::playback_url_is_stream_url == false.
8. Get_tv_stream_url()
// String
public function get_tv_stream_url(
/* [in] String */ $playback_url,
/* [inout] Map: Key -> Value */ &$plugin_cookies);
Returns the TV stream url having the TV playback url as input.
Examples of possible TV stream urls:
- Multicast TS-over-UDP stream (raw-UDP or RTP-over-UDP):
- udp:/@ip-address:port
- Unicast TS-over-HTTP stream:
- http://ts://host[:port][/path]
The reason for separation of terms 'playback URL' and 'stream URL' is
the following. Sometimes plugin is unable to provide fixed URL for IPTV
stream playback and can only provide a way of receiving this URL by
means of remote call. And each call will return different result. To
implement such plugins one should do the followig:
- for each such channel the
PluginTvChannel::playback_url_is_stream_url should be set to false
- the Get_tv_playback_url() should return string which:
1. will be used for default playback engine initialization. So it
must have correct prefix (e.g. http://ts://);
2. will be passed to the Get_tv_stream_url() operation as
parameter.
- the Get_tv_stream_url() should be implemented to decode the
playback URL, perform the remote call, parse the results and return
the actual IPTV stream URL.
So lets call 'playback URL' such intermediate URL which is used for
playback engine pre-initiallization and for being passed to
Get_tv_stream_url() operation.
Lets call 'stream URL' the result of Get_tv_stream_url() operation
which is used for actual playback.
NOTE: if PluginTvChannel::playback_url_is_stream_url is set to TRUE
then playback URL is interpreted as stream URL and Get_tv_stream_url()
is never called.
9. Get_vod_info()
// PluginVodInfo
public function get_vod_info(
/* [in] String */ $media_url,
/* [inout] Map: Key -> Value */ &$plugin_cookies);
Returns data for launching plugin VOD playback using the given optional
$media_url as the hint about what series to start from.
This operation is typically called when user presses PLAY or ENTER
remote button on some plugin folder item having the 'plugin_vod_play'
action registered for the corresponding key event.
This operation launches the playback of the list of movie series.
Number of series >= 1.
The output data of get_vod_info:
class PluginVodInfo
{
String name;
String description;
String poster_url;
List<PluginVodSeriesInfo> series;
int initial_series_ndx;
int initial_position_ms;
int buffering_ms;
Boolean advert_mode;
GuiActionMap actions;
GuiTimerDef timer;
Boolean ip_address_required;
Boolean valid_time_required;
Boolean subtitles_osd_enabled;
}
class PluginVodSeriesInfo
{
String name;
String playback_url;
Boolean playback_url_is_stream_url;
}
The 'name', 'description', 'poster_url' and 'series[i]->name' are used
for OSD representation.
The 'series' specifies the list of series to play. They form a some
sort of playlist.
The 'initial_series_ndx' specifies the index of series to start
playback from.
The 'initial_position_ms' specifies the initial playback position in
milliseconds. If negative value specified then the default initial
position will be chosen (resume is possible).
The 'advert_mode': if TRUE, the VOD playback will be started with the
following limitations:
- some features disabled: seek, jump, change playback speed and
similar;
- very limited OSD is shown (e.g. the info block and status never
shown). However, some features are enabled: image setup, zoom,
audio/subtitles setup etc.
The 'ip_address_required' and 'valid_time_required' specify correct
behaviour in the case of unavailable IP address and/or valid time. See
the description of GET_TV_INFO operation output data for more details.
The 'buffering_ms' specify the prebuffering time in milliseconds. NOTE:
not implemented now.
The 'actions' allows to specify actions to be executed in the following
use-cases during VOD playback:
- particular key is pressed. Currently only color-keys are supported
(A_RED, B_GREEN, C_YELLOW and D_BLUE); The events of the following
kinds can be used: GUI_EVENT_KEY_A_RED, GUI_EVENT_KEY_B_GREEN,
GUI_EVENT_KEY_C_YELLOW, GUI_EVENT_KEY_D_BLUE.
- timer event occured. The event of kind GUI_EVENT_TIMER should be
used for the case.
- playback stopped, or playback of another media_url started, or
power off requested. The event of kind GUI_EVENT_PLAYBACK_STOP
should be used for the case. If action is specified for playback
stop, the actual playback stop/switch/shutdown will be delayed
until action execution is finished. However, the additional
STOP/POWER-OFF key press will cancel the action execution.
- playback
The 'timer' allows to specify timer event delay. The timer event will
be generated only once, but timer can be reset using ChangeBehaviour
GUI action.
The 'series->playback_url' specify the playback URL for specific
series.
The 'series->playback_url_is_stream_url':
- true => playback URL should be used as stream URL;
- false => Get_vod_stream_url() operation should be called to get
stream URL each time it is needed.
See the descripton of GET_TV_STREAM_URL and GET_VOD_STREAM_URL for more
details.
The 'subtitles_osd_enabled' enables/disables the subtitles OSD feature:
OSD control which shows the list of available subtitles and allows to
switch between them. Enabled by default.
NOTE: Available in firmware 140521_b9+.
NOTE: The subtitles OSD was not available for plugins in earlier
firmware versions.
10. Get_vod_stream_url()
// String
public function get_vod_stream_url(
/* [in] String */ $playback_url,
/* [inout] Map: Key -> Value */ &$plugin_cookies);
Returns the VOD stream url having the VOD playback url as input.
Examples of possible VOD stream urls:
- MP4 container over HTTP (the most recommended one):
- http://mp4://host[:port][/path]
- TS container over HTTP:
- http://ts://host[:port][/path]
- Other container over HTTP (support/performance is limited):
- http://host[:port][/path]
- MMS (support is limited)
- mms://host[/path]
This operation is called each time the playback should be
stared or resumed and the
PluginVodInfo::series[ndx]->playback_url_is_stream_url is false. The
PluginVodInfo::series[ndx]->playback_url is passed as a parameter.
See description of Get_tv_stream_url() operation for more details.
11. Handle_user_input()
// GuiAction
public function handle_user_input(
/* [in] Map: Key -> Value */ &$user_input,
/* [inout] Map: Key -> Value */ &$plugin_cookies);
This operation is called during execution of HANDLE_USER_INPUT GUI
action.
Handle_user_input() operation may return another GuiAction object which
will be executed immediately.
This operation allows to implement many complex use-cases. Here are
some of them:
- regular folders with elements of different types: the
HANDLE_USER_INPUT GUI action is mapped to some keys in definition
of such folders.
- setup screens with possibility to edit list of settings; the
HANDLE_USER_INPUT is specified as confirm/apply action to
text_fields/comboboxes or assigned to some "Apply" button.
- implementing 'Control dialogs': flexible dialogs with custom list
of controls. The behaviour of control dialogs is very close to the
behaviour of control folders.
GUI actions
GUI action concept is an important part of plugin PHP API. It is used by
plugins to specify the behaviour of Dune GUI in many use-cases.
In particular, GUI action is often assigned to the event of pressing remote
key by user. Also GUI action can be produced as a result of execution of
another GUI action. Also GUI action can be returned by every operation
instead of normal output in case of error.
Each GUI action implies some algorithm to be performed by Dune GUI.
The GUI action is received from plugin in form of GuiAction:
class GuiAction
{
String handler_string_id;
Any data;
Map<String, String> params;
}
The 'handler_string_id' specifies string identifier of the action type.
Each action type will be described below.
The 'data' specifies parameters of action. The 'data' is object of class,
specific for the action type. The data classes for all supported action
types will be described below.
The 'params' specify additional action parameters of String type. These
parameters are automatically filled with some kind of 'execution context'
in particular use-cases desribed below.
The GUI action is created to be executed by Dune GUI when some event occur.
Here is the details of action execution:
1. First the Dune GUI chooses the executor according to the current GUI state.
Now there are 3 types of executors:
- Main executor. It is used during browsing of the Dune menu (browsing
of the folder hierarchy), including the popup menus and dialogs. This
executor can handle all types of actions.
- Playback executor. This executor is used during plugin TV/VOD
playback. Currently it may perform only the following action types:
- PluginHandleUserInput
- PluginShowError
- ChangeBehaviour
- PluginInvalidateFolders
- PluginVodPlay (currently with some limitations: vod_info
parameter is mandatory).
- Light executor. It is used when handling the error-actions produced
by plugin operations during plugin TV/VOD playback. Currently this
executor may perform only PluginShowError action.
2. Executor analyzes type of the action. If type is not known for executor
then execution is finished with status 'Action not recognized'. The actual
not recognized action is also provided.
3. Executor performs actual execution of the given action. As a result of
this step the following data is produced:
- [int] execution status (Ok = 0, Error = -1, etc..)
- [GuiAction] post action. Optional.
If post action is not null then it should be executed immediately; so we
replace the old action with new one and go to the step (2).
Otherwise execution is finished with execution status returned from the
last executed action.
GUI event kinds
There is a number of GuiEventKind constants, allowing to assign GuiAction
to some GUI event. The most of them represent some remote buttons. Here is
the list:
- GUI_EVENT_KEY_ENTER
- GUI_EVENT_KEY_PLAY
- GUI_EVENT_KEY_A_RED
- GUI_EVENT_KEY_B_GREEN
- GUI_EVENT_KEY_C_YELLOW
- GUI_EVENT_KEY_D_BLUE
- GUI_EVENT_KEY_POPUP_MENU
- GUI_EVENT_KEY_INFO
- GUI_EVENT_TIMER - special event kind, representing a periodic
activity. This event is generated once after a time-out specified in
GuiTimerDef::delay_ms. Typically, new timer is specified by means of
ChangeBehaviour GUI action.
- GUI_EVENT_PLAYBACK_STOP - special event kind, representin playback
stop. This event is generated on playback stop or power-off or before
playback switch. In case some action is registered for event, the
player first suspends playback, executes the action, waits for
completion of the action chain, and then proceeds with actual stop,
power-off or switch.
(*) update in firmware 120902+
The following key events added available only in control dialogs:
- GUI_EVENT_KEY_LEFT
- GUI_EVENT_KEY_RIGHT
- GUI_EVENT_KEY_UP
- GUI_EVENT_KEY_DOWN
- GUI_EVENT_KEY_P_PLUS
- GUI_EVENT_KEY_P_MINUS
- GUI_EVENT_KEY_NEXT
- GUI_EVENT_KEY_PREV
- GUI_EVENT_KEY_0
- GUI_EVENT_KEY_1
- GUI_EVENT_KEY_2
- GUI_EVENT_KEY_3
- GUI_EVENT_KEY_4
- GUI_EVENT_KEY_5
- GUI_EVENT_KEY_6
- GUI_EVENT_KEY_7
- GUI_EVENT_KEY_8
- GUI_EVENT_KEY_9
(*) update in firmware 130315_b6+
The following special event kinds added for "Global plugin actions":
- GUI_EVENT_BOOT
- GUI_EVENT_INSTALL
- GUI_EVENT_UPDATE
- GUI_EVENT_UNINSTALL
(*) update in firmware 130819_b8+
All previously specified key events now can be used in plugin regular
folders. NOTE: GUI_EVENT_KEY_ENTER cannot be overridden for empty plugin
regular folders.
The following event kinds added to be used in control dialogs and plugin
regular folders:
- GUI_EVENT_KEY_SETUP
- GUI_EVENT_KEY_RETURN
- GUI_EVENT_KEY_SELECT
- GUI_EVENT_KEY_CLEAR
(*) update in firmware 130904_b8+
The following event kinds added to be used in control dialogs and plugin
regular folders:
- GUI_EVENT_KEY_PAUSE
(*) update in firmware 131029_b9+
All previously specified key events now can be used in plugin TV playback
and plugin VOD playback.
Also, the timer event can be in plugin TV playback (in the same way as in
plugin VOD playback).
The following event kinds added to be used in control dialogs, plugin
regular folders, plugin TV playback, plugin VOD playback (with some
restrictions described below):
- GUI_EVENT_KEY_FWD
- GUI_EVENT_KEY_REW
- GUI_EVENT_KEY_SLOW
- GUI_EVENT_KEY_STOP
- GUI_EVENT_KEY_TOP_MENU
- GUI_EVENT_KEY_POWER
- GUI_EVENT_KEY_EJECT
- GUI_EVENT_KEY_MODE
- GUI_EVENT_KEY_VENDOR
- GUI_EVENT_KEY_MUTE
- GUI_EVENT_KEY_V_PLUS
- GUI_EVENT_KEY_V_MINUS
- GUI_EVENT_KEY_SEARCH
- GUI_EVENT_KEY_ZOOM
- GUI_EVENT_KEY_SUBTITLE
- GUI_EVENT_KEY_REPEAT
- GUI_EVENT_KEY_AUDIO
- GUI_EVENT_KEY_REC
- GUI_EVENT_KEY_DUNE
- GUI_EVENT_KEY_URL
(*) update in firmware 150529+
- GUI_EVENT_PLAYBACK_SWITCHED - this event is generated after switching
playback to new media URL (including the very first one).
- GUI_EVENT_PLAYBACK_GOING_TO_SWITCH - this event is generated before
switching playback to new media URL playback. Unlike
GUI_EVENT_PLAYBACK_STOP, this event is not generated in case of
stop/power-off. Another difference from GUI_EVENT_PLAYBACK_STOP is that
player does not wait for completion of action, registered for
GUI_EVENT_PLAYBACK_GOING_TO_SWITCH event.
NOTE: the following events cannot be overridden in plugin regular folders:
- ZOOM, POWER, EJECT
NOTE about control dialogs: some RC buttons have special meaning when text
editor is active or combobox drop-down is shown and cannot be
overridden by control dialog 'actions' map.
List of GUI action types
The full list of GUI action types and their explicit properties is provided
below:
1. PluginOpenFolderAction
Data:
class PluginOpenFolderActionData
{
String caption; // optional; default = null (auto)
String media_url; // optional; default = null (auto)
}
Action:
browses into plugin folder. In more details:
- folder caption is added to path block;
- the Get_folder_view($media_url) plugin operation executed;
- the output data is used to show contents of folder.
Params:
'media_url':
- if not null it is used as identifier of folder to be opened;
otherwise media_url of the currently selected folder element
is used. If no element is selected => action is ignored.
'caption':
- is used as path element if not null; otherwise caption of
currently selected folder element is used.
Returns:
post action: never
status: ok/failed
2. PluginTvPlayAction
Data:
class PluginTvPlayActionData
{
String initial_group_id; // optional, default = null (auto)
String initial_channel_id; // optional, default = null (auto)
Boolean initial_is_favorite; // optional, default = false;
unixtime_t initial_archive_tm; // optional, default = -1 (unset)
}
Action:
launches TV playback. The selection and playback state is
initialized using the given parameters. In more details:
- media_url of currently selected folder element is taken; if
none is selected then $media_url is null;
- Get_tv_info($media_url) plugin operation is executed;
- if output is invalid => action is failed;
- TV playback state is initialized using received PluginTvInfo;
- if some of initial_XXX parameters are set => they override
the default selection and playback state.
Returns:
post action: never
status: ok/failed
3. PluginVodPlayAction
Data:
class PluginVodPlayActionData
{
PluginVodInfo vod_info; // optional, default = null.
}
Action:
launches VOD playback. If 'vod_info' is specified, it is used to
initialize VOD playback. Otherwise, the
get_vod_info($current_media_url) will be called and the result vod
info will be used. The $current_media_url is the media_url of
currently selected folder element; if none is selected then
$media_url is null.
Returns:
post action: never
status: ok/failed
4. PluginHandleUserInputAction
Data:
[none]
Action:
runs Handle_user_input(GuiAction::$params) plugin operation.
The output data from Handle_user_input() is returned as
post action.
Returns:
post action: the action returned from Handle_user_input()
operation
status: ok/failed
5. PluginShowErrorAction
Data:
class PluginShowErrorActionData
{
Boolean fatal;
String title;
List<String> msg_lines; [optional]
}
Action:
- shows error to the user. In playback state the single text line
is shown in the center of the screen; in Dune menu state the
dialog is shown with given title and message lines;
- if (fatal == true) => the exit from plugin by fatal error is
scheduled. In this case playback is stopped and Dune browser is
moved to the top menu;
- returns error status.
Returns:
post action: never
status: failed
6. ShowDialogAction
Data:
class ShowDialogActionData
{
String title;
List<GuiControlDef> defs;
GuiActionMap actions; // optional
GuiTimerDef timer; // optional
Boolean close_by_return; // optional, default = false
int preferred_width; // optional, default = 0 (auto)
int max_height; // optional, default = 0 (auto)
int min_item_title_width; // optional, default = 0 (auto)
int initial_sel_ndx; // optional, default = -1 (auto)
Map<String,String> params; // optional params
}
class GuiTimerDef
{
// Timer delay in milliseconds. Zero value is allowed here.
int delay_ms;
}
Action:
shows the specified control dialog and interacts with user until
dialog is closed.
The dialog shows the vertical list of controls, each control may
be preceeded with optional title text. So dialog may consist of
1 or 2 columns.
The special "vgap" control can be used to increase or decrease
vertical gaps between controls.
The vertical scrollbar appears when needed.
- actions: allows to specify actions to be executed when
particular key is pressed or timer event occured. The
GUI_EVENT_KEY_ENTER behaviour cannot be changed.
- timer: allows to specify the timer event. The timer event
will be generated only once, but the timer can be reset using
ChangeBehaviour GUI action.
- close_by_return: whether to close dialog by pressing RETURN.
- preferred_width: preferred dialog content width, including
titles. When set to 0 (default), the dialog preferred width
is automatically calculated using the preferred width of
listed controls.
- max_height: maximum dialog height.
- min_item_title_width: minimum width resered for control
titles.
NOTE: Available in firmware 121201+.
- initial_sel_ndx: index of focusable control to select first
(index in list of all focusable controls: comboboxes, buttons
and text fields).
- params: additional customization parameters in form of
key/value map. Supported keys:
- frame_style=default|glass (PHP constants available:
DIALOG_FRAME_STYLE_DEFAULT, DIALOG_FRAME_STYLE_GLASS).
NOTE: Available in firmware 130824_b8+.
- exit_seq=<string>
Sequence allowing to close dialog.
Syntax of 'exit_seq' string: comma-separated list of GUI
event kinds. Example:
"key_1,key2,key3,key9,key_c_yellow".
NOTE: Available in firmware 130904_b8+.
Returns:
post action: if dialog is closed by means of CloseDialogAndRun GUI
action => the CloseDialogAndRunActionData::post_action is
returned as post action
status: ok
7. CloseDialogAndRunAction
Data:
class CloseDialogAndRunActionData
{
GuiAction post_action; // optional, default = null (none)
}
Action:
Closes current control dialog and returns 'post_action' as a result
of caller SHOW_DIALOG GUI action.
This action is ignored when executed outside of control dialog.
Returns:
post action: none
status: ok
8. ResetControlsAction
Data:
class ResetControlsActionData
{
List<GuiControlDef> defs;
int initial_sel_ndx; // optional, default = -1 (do not change selection)
GuiAction post_action; // optional, default = null (none)
}
Action:
replaces state of current control dialog or control folder.
This action is ignored when executed outside of control dialog or
folder.
Returns:
post action: from action data
status: ok
9. ShowPopupMenuAction
Data:
class ShowPopupMenuActionData
{
List<GuiMenuItemDef> menu_items;
int selected_menu_item_index; // optional, default = 0
}
Action:
shows the specified popup menu and interacts with user until popup
menu is closed. If user chooses popup menu item then the
corresponding action is returned as post action.
Returns:
post action: the action assigned to menu item chosen by user
status: ok
10. StatusAction
Data:
class StatusActionData
{
int status;
}
Action:
just returns the given status.
Returns:
post action: none
status: ok
11. PluginUpdateFolderAction
Data:
class PluginUpdateFolderAction
{
PluginRegularFolderRange range;
Boolean need_refresh;
int sel_ndx; // optional, default = -1 (do not change current)
}
Action:
Partially replaces state of current plugin regular folder:
- if need_refresh is TRUE => cached folder state is cleared;
- the given range is applied/replaced;
- if sel_ndx >= 0 then focus is moved to element with given
index.
This action is ignored when executed outside of regular folder.
Returns:
post action: none
status: ok
12. PluginInvalidateFolders
Data:
class PluginInvalidateFoldersActionData
{
List<String> media_urls;
GuiAction post_action; // optional, default = null (none)
}
Action:
clears the cached data about plugin folders identified by given
media_urls forcing them to be fully reloaded.
This action is needed for the case when some actions inside child
folder changed state of parent folder. Using this action one is
able to force parent folder to reload it's state.
If mentioned media_url is not cached => it is ignored.
Returns:
post action: from action data
status: ok
13. PluginRunNativeCode GUI action.
Data:
[none]
Action:
loads native library 'native_code.so' from plugin installation
directory and tries to invoke some function from this library.
Returns:
post action: none
status: ok/failed
14. PluginClearArchiveCache GUI action.
Data:
class PluginClearArchiveCacheActionData
{
String archive_id; // optional, default = null (all)
GuiAction post_action; // optional, default = null (none)
}
Action:
deletes the cached data of the plugin archives from file system (if
exist). If 'archive_id' is set => only the specified archive is
cleared; otherwise all archives of the current plugin are cleared.
Returns:
post action: from action data
status: ok
15. DvdPlay
Data:
class DvdPlayActionData
{
String url;
}
Action:
launches DVD playback of the given url.
Returns:
post action: never
status: ok/failed
16. BlurayPlay
Data:
class BlurayPlayActionData
{
String url;
}
Action:
launches Blu-Ray playback of the given url. This action is
available in firmware supports blu-ray playback.
Returns:
post action: never
status: ok/failed
17. FilePlay
Data:
class FilePlayActionData
{
String url;
}
Action:
launches normal playback on the single file pointed by given URL.
URL should point to audio or video file or stream of supported
format.
Returns:
post action: never
status: ok/failed
18. PlaylistPlay
Data:
class PlaylistPlayActionData
{
String url;
int start_index;
}
Action:
launches normal file playback on the playlist built from the file
or folder pointed by the given URL. URL may point to:
- single local/network/http audio/video file or other supported
network resource;
- local/network/http playlist file (m3u, pls);
- local/network folder containing audio/video/playlist files.
The first played playlist item will be selected using the given
"start_index", if valid.
Returns:
post action: never
status: ok/failed
19. LaunchMediaUrl
Data:
class LaunchMediaUrlActionData
{
String url;
GuiAction post_action;
}
Action:
1. build playlist recursively using the given URL as root element
of hierarchy;
2. analyze the content of playlist and choose the actual executor;
3. run the chosen executor against the playlist.
The recursive algorithm does the following:
- enters recursively into local/network folders, local/network/http
playlists (m3u, pls);
- adds to the playlist audio/video/image files and streams,
DVD/Bluray files and folders, Flash-applications (swf://* and
local *.swf), WWW-urls (www://*, *.url, *.URL)
Possible playlist executors are:
- DVD player; it is chosen if playlist contains only one
element which is either DVD folder or DVD disk image file;
- Blu-ray player; it is chosen if playlist contains only one
element which is either Blu-ray folder or Blu-ray disk image file;
- Flash player; it is chosen if playlist contains only one
element: either *.swf file or swf://* url;
- Web browser; it is chosen if playlist contains only one
element: either *.url/*.URL file or www://* URL;
- Photo viewer: it is chosen if playlist contains only image
files of known types (jpg, png, bmp, gif);
- Plugin installer: it is chosen if playlist contains only one
element: plugin_installer://* URL.
- Plugin uninstaller: it is chosen if playlist contains only one
element: plugin_uninstaller://* URL.
- Plugin launcher: it is chosen if playlist contains only one
element: plugin_launcher://* URL.
- general file playback: otherwise.
Returns:
post action: from action data.
NOTE: post-playback action execution now is not fully
implemented; currently post action will be taken into account
only if actual playlist executor is one of the following:
- plugin installer;
- plugin uninstaller;
- plugin launcher;
- general file playback (some restrictions are possible).
In future, support for action post-execution will be added for
more playlist executors.
status: ok/failed
20. ShowMainScreen
Data:
class ShowMainScreenActionData
{
GuiAction post_action;
}
Action:
switches to the main screen.
This action is added to improve some auto_start use-cases.
NOTE: current implementation has limitations.
Returns:
post action: from action data
status: ok/failed
21. ShowBlackScreen
Data:
class ShowBlackScreenActionData
{
String bg_url;
GuiAction post_action;
}
Action:
Switches to the black screen with optional background picture.
If 'bg_url' if specified, it is used as background picture instead of
solid black background.
NOTE: 'bg_url' available in firmware 130914_b8+.
Returns:
post action: from action data
status: ok/failed
22. ChangeBehaviour
Data:
class ChangeBehaviourActionData
{
GuiActionMap actions; // Optional.
GuiTimerDef timer; // Optional.
GuiAction post_action; // Optional.
}
class GuiTimerDef
{
// Timer delay in milliseconds.
int delay_ms;
}
Action:
changes the behaviour in the current GUI container. Currently the
following GUI containers supported:
- regular folder;
- control dialog;
- VOD playback.
In future, other containers will be supported too (control/movie
folder, TV playback, general playback).
If 'actions' is set, it replaces the existing one.
If 'timer_ms' is set, the timer is restarted from the current time
moment.
Returns:
post action: from action data
status: ok/failed
23. OpenFolder
Data:
class OpenFolderActionData
{
String media_url; // optional; default = null (auto)
}
Action:
browses into general folder. If media_url is not specified, the
currently selected folder item will be opened in general way.
Params:
'media_url':
- if not null it is used as URL of folder to be opened.
The URL can point local folders using smb://, nfs://,
storage_name://, main_storage:// -- see
http://dune-hd.com/firmware/misc/media_url.txt for more
details.
Also there can be dune_http:// URl (see
http://dune-hd.com/firmware/misc/dune_folder_howto.txt for more
details).
Also there can be dune_setup://<setup_id> URLs. For example,
setup://applications, setup://video.
Returns:
post action: never
status: ok/failed
Note: Available in firmware 130315_b6+.
24. CloseAndRunAction
Data:
class CloseAndRunActionData
{
GuiAction post_action; // optional, default = null (none)
}
Action:
If control dialog is active, then it works in the same way as
CloseDialogAndRunAction.
Does nothing, if some other kind of dialog is opened.
If no dialogs is currently opened and some folder is active, then
it closes folder (goes to the upper folder) and returns
'post_action'.
Returns:
post action: from action data when folder is acti
status: ok
Note: Available in firmware 121114+.
Update in firmware 131029_b9+:
Now this action works as 'stop playback' when called from TV
playback / plugin VOD playback when no dialog is active.
24. PluginSystemAction
Data:
class PluginSystemActionData
{
String run_string;
GuiAction post_action; // optional, default = null (none)
}
Action:
Prepares a command for unix shell interpreter by prepending the
plugin installation path to the 'run_string'. Then command is
executed by running system(<command>). Command can be run in
background if 'run_string' ends with '&' character.
For example, if plugin installation directory contains the
bin/prepare.sh script, then it can be called by specifying it as
global action 'boot' in plugin manifest and setting the
'run_string' to
"bin/script.sh param1 param2" or
"bin/script.sh param1 param2 &".
Returns:
post action: from action data
status: ok
Note: Available in firmware 130315_b6+.
25. RunBuiltinAction
Data:
class RunBuiltinActionData
{
String builtin_action_id;
Map<String,String> params;
GuiAction post_action; // optional, default = null (none)
}
Action:
This action is introduced for internal purposes. It runs some
built-in functionality, identified by 'builtin_action_id' with
parameters 'params'. The list of available public "built-in
actions" depends on firmware and currently is empty.
Returns:
post action: from action data
status: ok
Note: Available in firmware 130315_b6+.
26. WaitForIpAddressAction
Data:
class WaitForIpAddressActionData
{
int timeout_sec;
GuiAction post_action; // optional, default = null (none)
}
Action:
If IP-address is not yet received by DHCP (in case of DHCP network
configuration), then standard "Wait For IP Address" dialog is
shown until IP address is received or 'timeout_sec' seconds
passed.
Returns:
post action: from action data
status: ok
Note: Available in firmware 130914_b8+.
27. WgetAction
Data:
class WgetActionData
{
String url;
String post_data;
String result_key_prefix;
GuiAction post_action; // optional, default = null (none)
}
Action:
Performs HTTP request to 'url' with 'post_data', passing result
status and data to the 'post_action'.
This action is strongly not recommended to be used from PHP
plugins; it was introduced for internal reasons.
PHP plugins should use native 'curl' methods for performing HTTP
requests.
Returns:
post action: from action data
status: ok
Note: Available in firmware 130924_b9+.
28. ChangeSettingsAction
Data:
class ChangeSettingsActionData
{
Map<String,String> settings;
Boolean reboot;
Boolean restart_gui;
GuiAction post_action; // optional, default = null (none)
}
Action:
Changes internal Dune settings.
The 'settings' specifies the setting_name -> setting_value
key/value pairs to be changed. The list of available setting names
and possible setting values is out of the current document's
scope. The current settings are always stored in
/config/settings.properties.
The 'reboot' specifies whether to reboot STB immediately.
The 'restart_gui' specifies whether to reboot STB immediately.
NOTE: currently the 'reboot' is the only reliable way to apply
setting from PHP plugin. This may change in future firmware
versions.
This action has no effect in plugin TV/VOD playback mode.
Returns:
post action: from action data
status: ok
Note: Available in firmware 140905_r10+.
29. PluginUpdateInfoBlockAction
Data:
class PluginUpdateInfoBlockActionData
{
String text_above;
String text_color; // optional, default is 15
Boolean text_halo; // optional, default is false
int text_y_offset; // optional, default is 0
GuiAction post_action; // optional, default = null (none)
}
Action:
Updates current state of the information block. The information is
shown sometimes in the lower part of screen, typically it is
toggled by pressing INFO button. The changes are only visible when
information block itself is visible.
The following properties specifies the multi-line text message
shown just above the upper bound of the information block. Once
specified using PluginUpdateInfoBlock action, this message will
always adjoin the information block until playback stops or
another PluginUpdateInfoBlock adjusts or hides message.
Action has no effect unless called in plugin TV or VOD playback
mode.
The 'text_above': multi-line message text. The text string is
split automatically to fit the information block width. Special LF
character ('\n') can be used to force line break. The empty or
missing value can be used to hide message.
The 'text_color': color index (integer 0..23, default=15)
The 'text_halo': whether to draw black shade ('halo') around text
to make it visible on the bright background.
The 'text_y_offset': signed integer, allows to adjust vertical
position of message.
Returns:
post action: from action data
status: ok
Note: Available in firmware 150526_r10+.
30. PluginUpdateEpgAction
Data:
class PluginUpdateEpgActionData
{
String channel_id;
Boolean clear;
int day_start_tm_sec;
PluginTvEpgProgramList programs;
GuiAction post_action; // optional, default = null (none)
}
Action:
Updates the EPG information cached in player memory.
There are 3 useful cases covered by this action:
1. Clear all cached EPG information: 'clear' is TRUE;
'channel_id', 'day_start_tm_sec', 'programs' not specified.
2. Clear cached EPG information for a particular channel and
(optionally) put a specified program list for a specified day
into cache instead: 'clear' is TRUE, 'channel_id',
'day_start_tm_sec', 'programs' are set correspondingly.
3. Just update EPG program list for the specified channel and
day: 'clear' is FALSE, 'channel_id', 'day_start_tm_sec',
'programs' are set correspondingly.
Action has no effect unless called in plugin TV playback mode.
The 'channel_id': identifier of channel to be cleared/updated. Can
be avoided allowing to clear EPG data for all channels.
The 'clear': whether to clear EPG data.
The 'day_start_tm_sec': day specification, the unix timestamp of
day's beginning. Used together with 'channel_id' and 'programs'.
Optional.
The 'programs': list of EPG program data to be cached and used in
GUI for given channel and day. Used together with 'channel_id' and
'day_start_tm_sec'. Optional.
Returns:
post action: from action data
status: ok
Note: Available in firmware 150528_r10+.
30. PluginUpdateOsdAction
Data:
class PluginUpdateOsdActionData
{
PluginOsdComponenetList components;
GuiAction post_action; // optional, default = null (none)
}
class PluginOsdComponent
{
int x;
int y;
String image_url;
int image_width; // optional, default is actual image size
int image_height; // optional, default is actual image size
String text;
PluginFontSize text_font_size; // optional, default = FONT_SIZE_NORMAL
String text_color; // optional, default = 15
Boolean text_halo; // optional, default = false
}
Action:
Updates the state related with the new feature: possibility to
paint the arbitrary number of custom images and text messages in
plugin TV/VOD playback mode. These images/messages are painted
under (before) the standard native OSD GUI components/controls:
playlist browser, information block, etc..
The PluginUpdateOsdAction acts by replacing old sequence of OSD
compenents with the new sequence. Once set by
PluginUpdateOsdAction action execution, these components remain
onscreen until removed/replaced by means of another
PluginUpdateOsdAction execution or when playback stops.
The PluginOsdComponent specifies either image or single-line text
message, depending on whether 'image_url' or 'text' is set.
The order of components specifies the actual order of their
painting.
Action has no effect unless called in plugin TV or VOD playback
mode.
The 'components': list of plugin OSD components. Empty list or
null value specifies empty list of components (nothing to paint).
PluginOsdComponent properties:
The 'x', 'y': top left corner of image or text.
The 'image_url', 'image_width', 'image_height': specify image to
be shown. The actual image dimension are used in case of zero
values of image_width/heigh, which is the default. The image
loading is performed asynchronously.
The 'text': single-line text message. It is not clipped except for
screen bounds.
The 'text_font_size': PLUGIN_FONT_NORMAL or PLUGIN_FONT_SMALL.
Optional, default is PLUGIN_FONT_NORMAL.
The 'text_color': color index (integer 0..23, default=15)
The 'text_halo': whether to draw black shade ('halo') around text
to make it visible on the bright background.
Returns:
post action: from action data
status: ok
Note: Available in firmware 150528_r10+.
GUI controls
GUI controls may appear in the following GUI control containers:
- plugin control folders;
- control dialogs.
The look and behaviuor of control folders and control dialogs is very
similar. GUI controls are positioned from top to the bottom, have 1 or
2 columns and each column is left-aligned. Each control may have optional
'title' text string. When title is specified, it is located in 1st column
and control itself is located in 2nd column. When title is not specified,
GUI control is located in 1st column and nothing is placed into 2nd column.
The width of GUI controls in 2nd column can be automatically arranged (if
GUI control does not specify width explicitly).
Control folder is opened by means of PLUGIN_OPEN_FOLDER GUI action. The
subsequent call to Get_folder_view() operation returns, among the other
data, the control folder specification:
class PluginControlsFolderView
{
Array<GuiControlDef> defs;
int initial_sel_ndx;
}
The plugin control folders can be closed in the same way as other Dune
folders: by means of RETURN, TOP_MENU.
Control dialog is opened by means of SHOW_DIALOG GUI action:
class ShowDialogActionData
{
String title;
List<GuiControlDef> defs;
Boolean close_by_return; // optional, default = false
int preferred_width; // optional, default = 0 (auto)
}
If 'close_by_return' is true => dialog can be closed by RETURN; otherwise
it cannot.
The only other way to close dialog is to provoke execution of
CLOSE_DIALOG_AND_RUN GUI action. Normally actions of this type are assigned
to at least one button in control dialog.
The core of control folder and dialog's specification is the list of GUI
control definitions of type:
class GuiControlDef
{
String name;
String title;
GuiControlKind kind;
Object specific_def;
Map<String,String> params;
}
The 'name' specify identifier of GUI control. It is used for passing the
current value of GUI control to the GUI actions invoked inside the
container.
The 'title' specify optional string title.
The 'kind' specify kind of GUI action:
enum GuiControlKind
{
GUI_CONTROL_LABEL,
GUI_CONTROL_COMBOBOX,
GUI_CONTROL_TEXT_FIELD,
GUI_CONTROL_BUTTON,
GUI_CONTROL_VGAP
}
The 'specific_def' contains GUI control parameters specific for the
particular GUI control kind.
The 'params' contains additional parameters in form of key/value string
map.
Label
Data:
class GuiLabelDef
{
String caption;
}
Supported GuiControlDef::params keys:
'smart', 'max_lines', 'lines_vgap', 'pars_vgap'.
NOTE: Available in firmware 130820_b8+.
Details:
GUI label is painted as fixed single-line text string. If string is too
long, it is truncated in center.
Parameters:
'caption' - the text string.
Additional parameters:
NOTE: Available in firmware 130820_b8+.
'max_lines' - if > 1 then label is auto-split into paragraphs by ASCII
character 0xA (LF) and auto-split into lines by spaces.
'lines_vgap' - vertical gap between lines, in pixels. Default is 0.
'pars_vgap' - vertical gap between paragraphs, in pixels. Default is
'lines_vgap'.
'smart' - if '1' => the smart mode is turned on. In smart mode label is
assumed to be a single line containing small icons and text strings.
The 'caption' is assumed to be specific XML; see below the example.
Smart label example:
<icon>gui_skin://special_icons/controls_button_green.aai</icon>
<text dy="7" size="small">Next</text>
<gap width="50"/>
<icon>gui_skin://special_icons/controls_button_yellow.aai</icon>
<text dy="7" size="small">Cancel</text>
<gap width="50"/>
<icon>gui_skin://special_icons/controls_button_blue.aai</icon>
<text dy="7" size="small">Keyboard</text>
Smart label syntax:
The <icon> takes url from element body, and 'width', 'height', 'dy'
from attributes.
The <text> takes text from element body, and 'color', 'size', 'dy' from
attributes. The 'color' shall be integer from '0' to '23', the 'size'
shall be one of the 'normal', 'small', 'tiny'.
The <gap> has only 'width' attribute.
Combobox
Data:
class GuiComboboxDef
{
String initial_value; // Optional, default = null (first)
List<Pair<String, String>> value_caption_pairs;
int width; // optional; default = -1 (auto)
GuiAction confirm_action; // optional; default = null (none)
GuiAction apply_action; // optional; default = null (none)
}
Details:
GUI combobox is painted as standard Dune combobox. It can reside in 3
states:
- unfocused: main component painted without focus;
- focused: main component painted with focus; ENTER key is
intercepted to swith to active state;
- active; main component painted with focus and the drop-down menu
component is painted; the arrow keys, ENTER and RETURN are
intercepted.
Parameters:
'value_caption_pairs' - the combobox model: the list of pairs
{choice_value, choice_caption}. The choice_caption is painted on screen and
the choice_value is used as choice identifier.
'initial_value' - the choice_value to be selected first.
'width' - the width of combobox; if not specified => the default width
is used; actually combobox width cannot be less than the default value.
'confirm_action' - if specified, it is executed when user press ENTER
in the drop-down menu. During confirm_action's execution the choice is
not applied and combobox remains in 'active' state. If execution status
is OK => choice is applied (combobox is switched into 'focused' state,
main component is updated); othewise the choice is not applied and
combobox remains in 'active' state.
'apply_action' - if specified, it is executed after changes are
applied. The action execution status is ignored.
Text field
Data:
class GuiTextFieldDef
{
String initial_value; // Optional, default = null (first)
Boolean numeric; // Optional, default = false
Boolean password; // Optional, default = false
Boolean has_osk; // Optional, default = false
Boolean always_active; // Optional, default = false
int width; // optional; default = -1 (auto)
GuiAction confirm_action; // optional; default = null (none)
GuiAction apply_action; // optional; default = null (none)
}
Details:
GUI text field is painted as standard Dune text field. It can reside in
states:
- unfocused: text field painted without focus;
- focused: text field painted with focus; ENTER key is
intercepted to switch to the active state;
- active; text field painted with focus and some additional
graphics; the arrow keys, ENTER, RETURN and some other keys are
intercepted.
Parameters:
'initial_value' - the initial string.
'numeric' - if true => only number characters can be added;
'pasword' - if true => all characters are visualized as '*';
'has_osk' - if true => the on-screen keyboard is painted under the text
field; NOTE: currenly the OSK height is not taken into account when
components are layouted; so one should add VGapis to achieve nice
looking of container.
'always_active' - if true => the 'focused' state of text field is
avoided, i.e. text field is automatically switched to 'active' state
when it gains focus.
'width' - the width of text field; if not specified => some predefined
width is used.
'confirm_action' - if specified, it is executed when user press ENTER
in the active state of control. During confirm_action's execution the
changes in text string are not applied and text field remains in
'active' state. If execution status is OK => changes are applied and
text field is switched to 'focused' state; othewise the changes are
reverted and text field remains in 'active' state.
'apply_action' - if specified, it is executed after changes are
applied. The action execution status is ignored.
Button
Data:
class GuiButtonDef
{
String caption;
int width; // optional; default = -1 (auto)
GuiAction push_action; // optional; default = null (none)
}
Map<String,String> params;
Supported GuiControlDef::params keys:
'button_caption_centered'
Details:
GUI button is painted as standard Dune button. It can reside in
states:
- unfocused: button painted without focus;
- focused: button painted with focus; ENTER key is
intercepted to execute the push_action;
Parameters:
'capiton' - the text over the button;
'width' - the width of button; if not specified => the default width
is used;
'push_action' - if specified, it is executed when user press ENTER on
focused button.
Additional parameters:
'button_caption_centered' - boolean specifies whether button caption
should be centered instead of being left-aligned.
VGap
Data:
class GuiVGapDef
{
int vgap;
}
Details:
This pseudo-control is used to change the default distances between GUI
controls. It is not painted at all.
Parameters:
'vgap' - the integer value to be added to the default distance between
neighbour controls. If positive => distance increased, if negative =>
distance reduced.
Gui action execution in GUI control containers
Every action executed from GUI control takes additional parameters in the
'params' key-value maps
The value of 'selected_control_id' is set to GuiControlDef::name of the currently
selected control. This control is always the action producer.
For each GUI control of type (combobox | text_field) the value of
'GuiControlDef::name' is set to the current state-value of this control.
The state-value of text field is the current state of edited text; the
state-value of comobox is the currently selected choice_value.
Actually, the only GUI action which is used in GUI control containers is
HANDLE_USER_INPUT. When plugin creates HANDLE_USER_INPUT action to be
assigned to some GUI control, it should preliminary add some additional
marks to 'params' map in order to be able to further recognize the context
of action invocation from the implementation of Handle_user_input()
operation. So, the implementation of Handle_user_input() can distinguish
the different GUI control containers and have all information about the
current state of all GUI controls in the current container.
Preinstalled plugin resources
- Each plugin's installation may contain some resources (images). These
images may be accessed using special url syntax:
plugin_file://path/to/resource
or
plugin_file://%plugin_name%/path/to/resource
The 1st syntax accesses the resources of the 'current' plugin
(context-dependent).
The 2nd syntax allows to use preinstalled resources of plugin with
specified name.
Plugin archives
- Currently there is a way of caching the images used for representation of
plugin menu folders in the system storage or flash memory storage
(if supported). The PluginFolderView and PluginTvInfo may have the
'archive' field of type PluginArchiveDef:
{
string $id;
map(string,string) $urls_with_keys;
string $all_tgz_url; // optional
long long total_size;
# etc..
}
So if one does NOT use plugin archive for folder, it leaves the
PluginFolderView::archive as null, and writes the http://xxx/yyy.png
image url to the corresponding ViewItemParams::icon_path. In this case,
image will be http-downloaded many times.
To use plugin archive, one should specify as PluginFolderView::archive:
array(
'id' => 'myarchive',
'urls_with_keys' =>
array(
'xxx_key.png' => 'http://xxx/yyy.png',
# etc
),
'all_tgz_url' => 'http://xxx/all.tgz', // optional
'total_size' => '1234567',
)
and use special syntax for ViewItemParams::icon_path:
plugin_archive://myarchive/xxx_key.png
The execution of the PLUGIN_OPEN_FOLDER/PLUGIN_TV_PLAY operation first
checks whether archive is specified and launches the 'Update Archive'
dialog if needed. The Update Archive dialog checks whether archive is
changed. Then it checks whether suitable storage exists and has enough
free space. Then it and performes synchronization of the remote archive
state with local cache (the extra files are deleted, missing files are
downloaded). The keys are used as file names in the local cache. The
'total_size' value is trusted to be the cumulated size of all files in
archive.
The files can be downloaded by 2 different methods:
- first, if number of images to download is more than some limit (now
50) => then gzipped tarball is downloaded from 'all_tgz_url' URL,
unpacked and used as new local cache. The tarball's content should be
consistent with keys of the 'urls_with_keys' map: it should contain
the same set of files.
- Otherwise (if < 50 files have to be downloaded or 'all_tgz_url' is
unset) => the needed files are downloaded from their remote locations
specified in 'urls_with_keys'.
The handling of the icon URLs of type 'plugin_archive://<archive>/<key>'
work correctly even when Dune GUI was unable to keep local copy of
archive. In this case plugin_archive:// URLs work as http:// URLs.
Asynchronous image loading
The asynchronous image loading is used in regular folders with
FolderViewParams::async_icon_loading == true.
If async_icon_loading == false then GUI is blocked until all visible icons
are loaded.
If async_icon_loading == true then icon files are downloaded in separate
thread. During the download process the
PluginRegularFolderView::not_loaded_view_item_params is used for
representing the element and therefore another image may be used instead.
NOTE: some image resources are never loaded asynchronously:
1. standard Dune skin resources, e.g. urls gui_skin://xxx
2. preinstalled plugin resources, e.g. urls plugin_file://xxx
3. resources from the already cached plugin archive, e.g.
urls plugin_archive://<archive_name>/path
Plugin TV archive playback
Each plugin TV channel may have support for archive playback.
To enable archive playback:
- PluginTvChannel::have_archive should be set to true;
- Get_tv_playback_url() + Get_tv_stream_url() should accept real
unixtime values of 'archive_tm_sec' parameter and return the correct
archive stream URL;
- archive_past_days and archive_delay_sec of PluginTvChannel should be
set appropriately. The default is 14 days and 31 minutes
correspondingly.
Protected TV channels
Currently the only way to enable the protect code checking for some
channels one should do the following:
- set PluginTvChannel::is_protected to true;
- set PluginTvChannel::playback_url_is_stream_url to false if not done
yet;
- encode given protect_code into the result playback_url in the
implementation of Get_tv_playback_url();
- ensure that Get_tv_stream_url() returns string 'protected' each time the
protect code is incorrect and the actual stream url otherwise.
Auto-resume
The auto-resume feature is enabled by setting
<auto_resume>
<enable>yes</enable>
...
</auto_resume>
in the plugin manifest.
The auto-resume procedure is triggered when STB is turned on or resumed
from standby mode. This procedure tries to restore the last state of Dune
GUI before STB was turned off or sent to standby. Currently only the
following GUI states can be auto-resumed:
- Live TV playback of the particular channel;
- Archive TV playback of the particular channel and timestamp.
- VOD playback of the particular movie.
NOTE: the position of Dune GUI in folder hierarchy is not remembered now
and therefore cannot be restored.
It is possible to add the standard IP address and valid time requirements
for the auto-resume:
<auto_resume>
...
<ip_address_required>yes</ip_address_required>
<valid_time_required>yes</valid_time_required>
</auto_resume>
Also there is a way to specify custom GUI action to be executed instead of
the default auto-resume procedure. Example:
<auto_resume>
<enable>yes</enable>
<action>
<type>plugin_handle_user_input</type>
</action>
</auto_resume>
The all values of the resume_state.properties will be passed to the
auto-resume actions as parameters.
Including executable Linux programs into plugin
If plugin archive contains 'bin' directory (at the same level as the plugin
manifest), all files and subdirectories in the 'bin' directory will be made
executable during installation. In other words, if the plugin needs
executable files, they should be put under the 'bin' directory.
Note, that ZIP-archives don't support UNIX file attributes, thus, even if
an archive has been created from the executable files, those files will not
have executable attribute after extracting from the archive.
Files in 'www/cgi-bin' directory are processed the same way.
Executables for SMP87xx ARM platforms should be put into the following
directories, files in these directories are processed the same way:
.platform.87xx/bin/
.platform.87xx/www/cgi-bin/
Interface language translations
Each plugin may provide additional local translation tables located in
$install_dir_path/translations directory and having names
dune_language_<lang>.txt. These files will be loaded to the global STB
translation table on STB start or when interface language is changed by
user.
The local plugin translation files have the same format as global Dune
translation files. They define additional keys to be added to the global
table. The local translation keys are added to the plugin's own namescope
and cannot conflict with the global keys. Only the owner plugin can access
translation keys provided by itself.
The translation keys can be used in so-called public strings. Such strings
can be:
1. returned from DunePlugin interface calls;
2. declared in dune_plugin.xml.
Public strings are easily recognized: they are intended to be painted on
screen in some use-cases. For example, the plugin caption, entry point
caption, and all other "captions" are the public strings.
Each public string may be:
1. Just fixed string (not translated)
"Movie"
2. Simple reference:
"%tr%movie_caption"
For example, if current interface language is "english" and plugin has
the following record in it's translations/dune_language_english.txt:
movie_caption = Movie
and another on in translations/dune_language_french.txt:
movie_caption = Film
then this string will be dereferenced to
"Movie" or "Film" depending on current interface language setting.
3. Extended public string syntax:
extended_public_string ::= "%ext%" string_with_refs
string_with_refs ::= string {ref string}
ref ::= "<key_local>" key_name {param} "</key_local>"
param ::= "<" param_name ">" string_with_refs "</" param_name ">";
key_name ::= string
param_name ::= string
Examples:
1) Using of positional parameters:
String:
"%ext%<key_local>movie_folder_contains__1<p>20</p></key_local>"
Translation record:
movie_folder_contains__1 = Folder contains %s movies.
Result string:
"Folder contains 20 movies."
2) Using of named parameters:
String:
"%ext%<key_local>cur_time3<h>21</h><m>38</m><s>00</s></key_local>"
Translation record:
cur_time3 = Current time is %{h}:%{m}:%{s}.
Result string:
"Current time is 21:38:00."
HTTP server extension
The local STB HTTP server is configured to provide access to files in the
following directories in plugin file structure:
$install_dir_path/www/* - normal access;
$install_dir_path/www/cgi-bin/* - access with CGI execution enabled.
The following HTTP urls are mapped to these directories:
http://<STB-address>/plugins/<plugin_name>/*
http://<STB-address>/cgi-bin/plugins/<plugin_name>/*
The following language constructions are provided for convenience in PHP
code:
DuneSystem::$properties['plugin_www_url'] =
http://127.0.0.1/plugins/<plugin_name>/
DuneSystem::$properties['plugin_cgi_url'] =
http://127.0.0.1/cgi-bin/plugins/<plugin_name>/
Auto-start specification in plugin manifest
The auto start specification in the plugin manifest dune_plugin.xml allows
to enable automatic startup of the plugin when the plugin is declared as
"main" plugin (there may be at most one plugin declared as "main" plugin).
For more information about "main plugin", see the description of
"/firmware/config/main_plugin_name.txt" here:
http://files.dune-hd.com/sdk/doc/html/dune_custom_firmware.html
The auto_start section in plugin manifest affects the following use-cases:
- STB power-on;
- resume from the stand-by mode.
For "main" plugin the <auto_start> section in dune_plugin.xml is taken into
account; the <auto_start> section of other plugins is just ignored. The
example of the auto_start section:
<dune_plugin>
...
<auto_start>
<entry_point_media_url>main_tv</entry_point_media_url>
<action>
<type>plugin_open_folder</type>
</action>
</auto_start>
...
</dune_plugin>
NOTE: the 'plugin_open_folder' is just an example. Typically, the
auto_start action should be the same as 'key_enter' action in the
corresponding entry point.
This specification will cause STB to enter the "main_tv" plugin folder on
each startup (of course, if the described plugin is "main" plugin).
Details:
- entry_point_media_url (optional, default = unset)
the media_url of the plugin entry point. On STB startup the folder
containing the specified entry point will be entered and the entry
point itself will be focused. If not set, the default folder will
be opened on startup.
- action (optional, default = unset)
the action to be executed on startup (just after entry point is
selected, if specified).
- ip_address_required = yes|no (optional, default = no)
- valid_time_required = yes|no (optional, default = no)
if yes, the standard dialog will appear waiting for IP address or
valid time.
- run_action_before_auto_resume = yes|no (optional, default = no)
By default, the auto-start action will not be executed when STB
tries to auto-resume playback. Setting the
'run_action_before_auto_resume' to 'yes' will force STB to execute
auto-start action even in the auto-resume use-case. See the details
about the auto-resume feature in the corresponding section
('Auto-resume').
- skip_initial_dialogs = yes|no (optional, default = no)
if yes, the action will be executed before the initial STB setup
wizard; otherwise action will be executed after setup wizard. This
only affects the use-case of first STB power-on after
the Reset Settings procedure.
- force_on_start = none|main_screen|black_screen
- force_on_finish = none|main_screen|black_screen
allows to specify the background for auto_start action execution.
Configuring plugin auto-start via menu
The user can manually configure the STB to automatically launch a certain
plugin on STB boot.
To do it:
- First, add the plugin into the favorites menu (choose the plugin,
press "POP UP MENU" RC button, choose "Add to favorites").
- Then, go into the favorites menu and enable autostart for the plugin
(choose the plugin, press "POP UP MENU" RC button, choose "Enable
autostart").
Image file formats (for icons etc)
- JPEG
- PNG with alphachannel
- BMP with alphachannel
- AAI with alphachannel
- This is Dune HD proprietary format.
- See:
- http://dune-hd.com/firmware/misc/
- http://dune-hd.com/firmware/misc/AAImageGen-README.txt
Ways to reference image files from plugins
- Image file from web server:
- Icon path/URL: http://host[:port][path]
- Image file from web server, preloaded/cached via plugin archive:
- Icon path/URL: plugin_archive://archive-name/path
- Image file built-in into plugin (part of plugin):
- Icon path/URL: plugin_file://path-to-file
- Example: plugin_file://plugin_icon.png
- Image file built-in into firmware (part of standard GUI skin):
- Icon path/URL: gui_skin://path-to-file
- Example: gui_skin://large_icons/tv.aai
- More information about GUI skins:
- http://dune-hd.com/support/skins
Features added in firmware version 120531_2200_beta
Starting with the firmware version 120531_2200_beta, the following Dune PHP
Plugins API extensions and improvements were added:
- New GUI actions:
- file_play
- dvd_play
- bluray_play
- playlist_play
- launch_media_url
- change_behavior
- show_black_screen
- show_main_screen
- New GUI events:
- timer
- playback_stop
- New properties in existing data structures:
- GuiAction::params
- PluginInvalidateFoldersActionData::details
- PluginInvalidateFoldersActionData::rate_details
- PluginMovieFolderView::left_button_caption
- PluginMovieFolderView::left_button_action
- PluginMovieFolderView::params
- PluginRegularFolderView::timer
- PluginTvInfo::epg_mode
- PluginVodInfo::initial_position_ms
- PluginVodInfo::advert_mode
- PluginVodInfo::actions
- PluginVodInfo::timer
- ShowDialogActionData::actions
- ShowDialogActionData::timer
- ShowDialogActionData::max_height
- ShowDialogActionData::initial_sel_ndx
- ViewItemParams::item_caption_color
- ViewItemParams::item_sandwich_icon_scale_factor
- ViewParams::paint_details_box_background
- ViewParams::help_line_text_color
- ViewParams::item_detailed_info_title_color
- ViewParams::item_detailed_info_text_color
- New data structures and their properties:
- BlurayPlayActionData::url
- ChangeBehaviourActionData::actions
- ChangeBehaviourActionData::timer
- ChangeBehaviourActionData::post_action
- DvdPlayActionData::url
- FilePlayActionData::url
- GuiTimerDef::delay_ms
- LaunchMediaUrlActionData::url
- LaunchMediaUrlActionData::post_action
- PlaylistPlayActionData::url
- PlaylistPlayActionData::start_index
- PluginFolderViewParams::paint_path_box
- PluginFolderViewParams::paint_content_box_background
- PluginFolderViewParams::background_url
- PluginVodPlayActionData::vod_info
- ShowBlackScreenActionData::post_action
- ShowMainScreenActionData::post_action
- New features related to plugin file structure:
- {plugin_install_dir}/bin/
- The player automatically sets executable permissions on all
files in this directory during plugin installation.
- {plugin_install_dir}/www/{path}
- The player automatically makes these files accessible via
HTTP (locally inside the player, and from the local network):
- http://localhost-or-dune-ip-address/plugins/{plugin_name}/{path}
- {plugin_install_dir}/www/cgi-bin/{path}
- The player automatically makes these CGI applications
accessible via HTTP (locally inside the player, and from the
local network):
- http://localhost-or-dune-ip-address/cgi-bin/plugins/{plugin_name}/{path}
- Other new features:
- Ability to package FlashLite application into plugin and launch
it when the user enters plugin entry point, or when PHP plugin
code decides to call it. Supported via the new "launch_media_url"
action.
- Ability to package HTML page/application into plugin and launch
it in web browser when the user enters plugin entry point, or
when PHP plugin decides to call it. Supported via the new
"launch_media_url" action.
- If the plugin is pure FlashLite or HTML application and does not
need to execute any PHP code, "plain" plugin type can be
specified in plugin manifest instead of "php"; in this case,
there is no need to include PHP program into the plugin and
specify "program" parameter in plugin manifest.
Implementing advanced playback control in PHP plugins
The following features of PHP API (introduced in firmware version
120531_2200_beta) can be used to implement advanced playback control use
cases in PHP plugins.
PluginVodInfo::timer
PluginVodInfo::initial_position_ms
PluginVodInfo::advert_mode
GUI_EVENT_TIMER
GUI_EVENT_PLAYBACK_STOP
Examples:
1) Playback AD video before and after main video.
First perform PluginVodPlay action with media_url pointing to AD
pre-roll video, PluginVodInfo::advert_mode == TRUE, and
GUI_EVENT_PLAYBACK_STOP event registered in PluginVodInfo::actions.
When GUI_EVENT_PLAYBACK_STOP event occurs, another PluginVodPlay action
should be performed: media_url pointing to main video,
PluginVodInfo::advert_mode == FALSE, and GUI_EVENT_PLAYBACK_STOP event
registered in PluginVodInfo::actions.
When GUI_EVENT_PLAYBACK_STOP event occurs, another PluginVodPlay action
should be performed: media_url pointing to AD post-roll video,
PluginVodInfo::advert_mode == TRUE.
The following plugin demonstrates this approach:
dune_plugin_demo2_with_ad.zip
2) Playback AD video in the middle of main video.
There is no direct support for this, but the following approach can be
potentially used (not really tested, but should work if there are no
bugs).
Start main video playback with PluginVodInfo::timer specified with
appropriate timer delay (one second or a few seconds), and
GUI_EVENT_TIMER registered in PluginVodInfo::actions.
When GUI_EVENT_TIMER event occurs, the plugin code should check the
current playback position, and, if needed (it is time to show ad),
request playback of AD media url: perform PluginVodPlay action with
PluginVodInfo::advert_mode == TRUE and GUI_EVENT_PLAYBACK_STOP event
registered in PluginVodInfo::actions.
When GUI_EVENT_PLAYBACK_STOP event occurs, another PluginVodPlay action
should be performed: media_url pointing to main video,
PluginVodInfo::advert_mode == FALSE, and
PluginVodInfo::initial_position_ms pointing to the position where the
main video was interrupted by the ad.
Checking the current playback position can be performed in the following
way:
Read "playback_position" field in the file
"/tmp/run/ext_command.state".
NOTE: this is not part of official PHP API, but can be used as a
temporary solution.
3) Rememebering and resuming VOD playback position.
Approach A:
~~~~~~~~~~~
Specify "auto_resume" feature in plugin manifest.
If "action" is not specified, PHP engine will automatically resume VOD
playback.
If "action" is specified (required if PHP plugin needs to do some
checking/processing before resuming VOD playback), see Approach B.
Approach B:
~~~~~~~~~~~
Specify "auto_resume" feature in plugin manifest, and specify
PluginHandleUserInputAction "action".
Instead of standard auto resume processing, the specified action will be
executed.
Then, in PHP code, read the information required for auto-resume from
the following file:
/config/resume_state.properties
NOTE: this is not part of official PHP API, but can be used as a
temporary solution.
Sample content of this file:
mode = PLUGIN_VOD_PLAYBACK
plugin_name = some_plugin
plugin_entry_media_url = vod_category_list
plugin_media_url = {"screen_id":"vod_scene_info","scene_id":"193115"}
plugin_vod_id = 193115
plugin_vod_series_ndx = 0
plugin_vod_position_seconds = 37
plugin_tv_group = 1
plugin_tv_channel = 5
plugin_tv_is_favorite = 0
plugin_tv_archive_tm = 1343834591
Then, perform VOD playback with PluginVodInfo::initial_position_ms
specified.
Approach C:
~~~~~~~~~~~
The same as Approach B, but w/o using "auto_resume" feature in plugin
manifest. The file "/config/resume_state.properties" is created by the
system even if "auto_resume" feature is not used, and this file can be
read and handled by PHP plugin code.
Approach D:
~~~~~~~~~~~
Start main video playback with PluginVodInfo::timer specified with
appropriate timer delay (one second or a few seconds), and
GUI_EVENT_TIMER registered in PluginVodInfo::actions, and
GUI_EVENT_PLAYBACK_STOP registered in PluginVodInfo::actions.
When GUI_EVENT_TIMER event occurs, the plugin code should check the
current playback position and remember it.
(See above for the info how to do it.)
When GUI_EVENT_PLAYBACK_STOP event occurs, the plugin code should
persistently remember the latest playback position remembered when
handling GUI_EVENT_TIMER events.
Then, use the persistently remembered position when starting playback
next time, by specifying PluginVodInfo::initial_position_ms.
Plugin online update mechanism
Dune STB firmware includes support for online update of plugins. Each
plugin may specify that it should be updated from from the given HTTP URL.
When the user launches any entry point of the plugin, the system checks for
available updates using this URL. If an update is available, it is
automatically proposed for installation to the user. After the update is
installed, the originally requested plugin entry point is launched.
To enable online update for a plugin, the plugin manifest file
("dune_plugin.xml") should include the following XML specification inside
the root ("dune_plugin") XML-element:
<version_index>5</version_index>
<version>130528_1700</version>
<check_update>
<schema>2</schema>
<url>http://some-server/some-path/update_info.xml</url>
<timeout>0</timeout>
<required>no</required>
<auto>no</auto>
</check_update>
Here, the semantics of XML-elements is the following:
version_index
The numeric version index, which should increase each time a new
plugin version is published on the server. Is not shown in the UI.
version
The version caption, which is shown in the UI when the system
proposes/performs update to this version.
check_update / schema
Update schema version. The version 1 is legacy and must not be used.
The version 2 must be used.
url
The HTTP URL pointing to "update_info" XML document.
timeout
The timeout (in seconds). It specifies minimum timeout between
attempts to check available updates performed. If the value is 0, the
system checks for available updates everytime when the user launches
any entry point of the plugin.
required
The flag indicating if the update is required or not. Possible values
are "yes" and "no".
auto
The flag indicating whether background autocheck for updates is
enabled for plugin. It is disabled by default.
NOTE: 'auto' feature is available in firmwares 150430_r10+.
The "update_info" XML document has the following structure:
<dune_plugin_update_info>
<schema>2</schema>
<name>plugin_name</name>
<plugin_version_descriptor>
<version_index>5</version_index>
<version>130528_1700</version>
<beta>no</beta>
<critical>no</critical>
<url>http://some-server/some-path/5.tgz</url>
<md5>a209a234fc9c518d3a165750a1f0dde4</md5>
<size>2244608</size>
<caption>plugin_caption</caption>
</plugin_version_descriptor>
</dune_plugin_update_info>
Here, the semantics of XML-elements is the following:
schema
The value must be 2.
name
Plugin name.
caption
Plugin caption.
plugin_version_descriptor / version_index
Plugin version index corresponding to the plugin available on the
server. Must be the same as the plugin version index specified in the
plugin archive available on the server.
plugin_version_descriptor / version
Plugin version caption corresponding to the plugin available on the
server. Must be the same as the plugin version caption specified in
the plugin archive available on the server.
plugin_version_descriptor / beta
The flag indicating if this plugin update is beta or non-beta
(stable). Possible values: "yes" (beta), "no" (non-beta). Reserved
for future use, currently the value is ignored; it is recommended to
use "no" value.
plugin_version_descriptor / critical
The flag indicating if this plugin update is critical. Possible
values: "yes" (critical), "no" (non-critical). The value "yes" can be
used for plugins which specify "check_update / timeout" = 0 and
"required" = "yes" in their manifest file; in this case, the system
does not allow to launch the old version of the plugin if plugin
update is available on the server and this plugin update is critical.
plugin_version_descriptor / url
HTTP URL pointing to the plugin archive in the .tar.gz format. The
content of the .tar.gz archive must be exactly the same as the
content of the regular plugin installed archive (dune_plugin*.zip
file).
plugin_version_descriptor / md5
MD5 checksum of the .tar.gz file specified in
"plugin_version_descriptor / url" element.
plugin_version_descriptor / size
Specifies the storage space (in bytes) occupied by the plugin after
it is installed into the flash memory of the STB. Can be computed
using the following algorithm: "du -sk /path/to/folder" * 1024.
plugin_version_descriptor / caption
Plugin caption. This caption will be used in the UI dialogs shown
during plugin update. If plugin caption does not change between
plugin versions, it should be the same as plugin caption specified in
the plugin manifest file.
NOTE: The "update-info" XML document may contain multiple
"plugin_version_descriptor" elements. Only the one with the biggest value
of version_index is actually used; the rest are ignored.
Signed plugins
Plugins preinstalled in the standard retail Dune firmware or available in the
standard retail Dune firmware via Dune Store are specially signed by Dune HD.
Signed plugins include the following additional files:
dune_plugin.sign
This file contains the plugin signature.
dune_plugin_signer_id.txt
This file contains "signer ID" -- an identifier of the key used for
plugin signing. Allowed values are:
- The string "com.dune-hd" -- reserved for the use by Dune HD only.
- Customer ID of the custom firmware build.
(*) Available in firmware 150326_r10+.
When a plugin is signed, the system verifies the signature of the plugin
and refuses to use it if the signature does not match the plugin or if the
specified signer ID is not allowed.
Custom firmware versions (e.g. used by operators) may be configured to
allow only signed plugins (provided/approved by Dune HD and/or the
customer) and disallow unsigned plugins (provided by 3-parties and not
approved by the customer).
Using custom signing keys
NOTE: This functionality is available in firmware 150326_r10+.
To sign plugins using a custom signing key, perform the following steps:
1. Generate a pair of private and public DSA keys for plugin signing and
vertification.
Perform the following commands on a Linux PC:
openssl dsaparam -out dsaparam.pem 2048
openssl gendsa dsaparam.pem -out plugin_private_key.pem
openssl dsa -in plugin_private_key.pem -pubout -out plugin_public_key.pem
2. Sign plugins using private plugin key.
Download "plugin_sign" utility, using one of the following options:
http://files.dune-hd.com/sdk/misc/plugin_sign.x86
A precompiled executable for Linux PC (x86), dynamically
linked. Requires libcrypto 0.9.8 to be installed in the system.
http://files.dune-hd.com/sdk/misc/plugin_sign_static.x86
A precompiled executable for Linux PC (x86), statically linked.
Use the utility in the following way (on a Linux PC):
/path/to/plugin_sign.x86 /path/to/plugin/dir {signer_id} plugin_private_key.pem
Here, {signer_id} should be the customer ID of the custom firmware.
The utility will generate "dune_plugin.sign" and
"dune_plugin_signer_id.txt" files in the plugin directory.
3. Include the public plugin key into the custom firmware.
Put the file "pluging_public_key.pem" into the following location:
/firmware/config/plugin_key.pem
Plugins signed by the corresponding private key and using the value of
"signer ID" equal to the value of "customer ID" of the custom firmware
will be allowed by this custom firmware.
Global plugin actions
NOTE: Available in firmware 130315_b6+.
The mechanism of "global plugin actions" allows a plugin to force the STB to
perform certain actions (e.g. launch a shell script shipped within a
plugin) on certain system events (e.g. on STB boot or plugin
install/uninstall).
This mechanism is available in firmware versions 130515_2104_b6+.
Supported system events:
boot
Is launched on cold STB boot immediately after the STB engine
initializes plugins. Is launched in all cases, even if custom
stb_home application is started instead of the native Dune GUI. At
this moment, /tmp/sysinfo.txt is not available yet and other parts of
the STB engine may not be initialized yet. Can modify visibility of
plugin entry points. Cannot launch dialogs, playback and other
GUI-related actions.
boot_end
Is launched on cold STB boot at the very end of the STB boot process.
Is launched in all cases, even if custom stb_home application is
started instead of the native Dune GUI. At this moment, it is
guaranteed that /tmp/sysinfo.txt file is already available. Cannot
launch dialogs, playback and other GUI-related actions.
NOTE: Available in firmware 130917_b9+.
gui_start
Is launched during startup of the native Dune GUI -- on STB boot or
when the STB exists software standby mode. Is not launched if custom
stb-home application is started instead of native Dune GUI. Is
launched after the initial setup wizard of the native Dune GUI.
NOTE: Available in the firmware 130914_b8+.
install:
Is launched immediately after plugin has been installed.
update:
Is launched immediately after plugin has been updated.
uninstall:
Is launched before plugin is deleted.
To perform an action on a system event, the plugin should declare
corresponding global action in the plugin manifest file. The action can be
any standard plugin GUI action, or "plugin_system" action which allows to
launch an executable file shipped within the plugin. For "boot" system
event, only "plugin_system" action is supported.
Example of defining global actions in the plugin manifest file:
<dune_plugin>
...
<global_actions>
<boot>
<type>plugin_system</type>
<data>
<run_string>bin/smbserver_ctl.sh start &</run_string>
</data>
</boot>
<install>
<type>plugin_system</type>
<data>
<run_string>bin/smbserver_ctl.sh start &</run_string>
</data>
</install>
<update>
<type>plugin_system</type>
<data>
<run_string>bin/smbserver_ctl.sh start &</run_string>
</data>
</update>
<uninstall>
<type>plugin_system</type>
<data>
<run_string>bin/smbserver_ctl.sh stop &</run_string>
</data>
</uninstall>
</global_actions>
...
</dune_plugin>
Regular folder GUI customization
Here are some specific notes about ViewParams and ViewItemParams used for
regular folder GUI customizataion.
Additional information can be found here:
http://dune-hd.com/support/misc/dune_folder_howto.txt
The ViewParams are assigned with some regular folder and specify different
aspects of folder content visualisation.
The ViewItemParams are assigned with each folder element and (together with
folder's ViewParams) affect it's visualication inside parent folder.
Normally regular folder screen is divided into 3 areas:
- "path block" in the top (optional)
- "content block" in the bottom-left
- "details block" in the bottom-right
The rectangular content block of regular folder is divided into small 'item'
rectangles of equal dimentions, using number of rows/columns as parameter.
Each non-empty item rect normally contains and icon and a caption text.
The details block normally contains additional information about currently
selected content item: some icon in the top and a structured text below.
List of ViewParams properties
- num_cols (positive integer, mandatory)
- num_rows (positive integer, mandatory)
Content area grid parameters.
- animation_enabled (boolean, default=yes)
Whether to enable cursor animation.
- scroll_animation_enabled (boolean, default=yes)
Whether to enable content scrolling animation. Currently has effect
only on horizontal orientation.
NOTE: Available in firmware 131203_b9+.
- orientation (vertical|horizontal, default=vertical)
NOTE: Available in firmware 131203_b9+
- cycle_mode_enabled (boolean, default=no)
When enabled, selection rectangle is always in center while folder
elements are scrolled left/right. Has effect only on horizontal
orientation with single row and odd number of columns >= 5.
NOTE: Available in firmware 131203_b9+
- cycle_mode_gap (yes|no|auto, default=no)
Specifies whether to paint additional horizontal gap between last and
first folder elements. "Auto" means to paint gap when number of
element greater then number of columns. Has effect only when
cycle_mode is effectively enabled.
NOTE: Available in firmware 131203_b9+
- cycle_mode_gap_width (integer, default=auto=half item width)
Specifies horizontal gap width. Has effect only when
cycle_mode is effectively enabled.
NOTE: Available in firmware 131203_b9+
- cycle_mode_gap_icon_path (image URL string, default=unset)
Specifies icon to be painted in the middle of horizontal gap. Has
effect only when cycle_mode is effectively enabled.
NOTE: Available in firmware 131203_b9+
- background_path (image URL string, default=unset)
- background_x (non-negative integer, default=0)
- background_y (non-negative integer, default=0)
- background_width (positive integer, default=real image width)
- background_height (positive integer, default=real image height)
- optimize_full_screen_background (boolean, default=false)
- background_order (before_all|before_icons|after_all,
default=before_icons)
If background_path is set, then specifies custom background which is
painted after the default full-screen background. The background
properties have effect only when backgroun_path is set. The
'optimize_full_screen_background' allows to avoid paining of the
skin's background; in this case background_order should be before_all
and the effective custom background rectangle should cover all
screen. The 'backgroun_order' allows to specify backround painting
order:
- before_all: before all other graphics;
- before_icons: after glasses, but before icons/captions/focuses.
- after_all: after all other graphics.
- scroll_path (image URL string, default=unset)
- scroll_x (non-negative integer, default=auto)
- scroll_y (non-negative integer, default=auto)
- scroll_height (positive integer, default=auto)
Allows to override default skin scrollbar graphics.
- mark_path (image URL string, default=unset)
- mark_dx (integer, default=0)
- mark_dy (integer, default=0)
- mark_scale_factor (double, default=1.0)
Allows to override default skin folder element mark icon. The mark_dx
and mark_dy: if mark_path is set => offset from the top-left corner
of icon; otherwise => offset from the default position near the
right-top corner of icon.
- paint_path_box (boolean, default=true)
- paint_path_box_background (boolean, default=true)
NOTE: Available in firmware 130818+
- paint_widget (boolean, default=true)
NOTE: Available in firmware 130818+
- paint_widget_background (boolean, default=true)
NOTE: Available in firmware 130818+
- paint_content_box_background (boolean, default=true)
- paint_scrollbar (boolean, default=true)
- paint_icon_selection_box (boolean, default=true)
- paint_help_line (boolean, default=true)
- paint_details (boolean, default=true)
- paint_details_box_background (boolean, default=true)
Allows to hide some graphics.
- help_line_text_color (integer color index, currently from 0 to 23;
default is 23)
Color of text in help line.
- icon_selection_box_dx (integer, default=auto)
- icon_selection_box_dy (integer, default=auto)
- icon_selection_box_width (positive integer, default=auto)
- icon_selection_box_height (positive integer, default=auto)
Allows to adjust the icon_selection_box size and position. By default
the selection is painted over content item rectangle.
- paint_icon_badge_box (boolean, default=false)
Enables badge mode. In badge mode the "badge" cut-image from skin is
painted under icon and icons are automatically downscaled and
centered into the badge box.
- hidden_badge_box (boolean, default=false)
When true, the badge is not painted but the additional graphics (marks
and stars) are painted in the badge-mode locations.
NOTE: Available in firmware 120819+.
- icon_badge_box_dx (integer, default=auto)
- icon_badge_box_dy (integer, default=auto)
- icon_badge_box_width (positive integer, default=auto)
- icon_badge_box_height (positive integer, default=auto)
- icon_badge_box_sel_dx (integer, default=auto)
- icon_badge_box_sel_dy (integer, default=auto)
- icon_badge_box_sel_width (positive integer, default=auto)
- icon_badge_box_sel_height (positive integer, default=auto)
Allow to adjust the badge rectangle location, separately in selected
and unselected state.
- content_box_x (non-negative integer, default=auto)
- content_box_y (non-negative integer, default=auto)
- content_box_width (positive integer, default=auto)
- content_box_height (positive integer, default=auto)
Allow to specify the content block rectangle.
- content_box_padding_left (non-negative integer, default=20)
- content_box_padding_top (non-negative integer, default=20)
- content_box_padding_right (non-negative integer, default=20)
- content_box_padding_bottom (non-negative integer, default=20)
Allow to specify the content block padding.
- extra_content_objects (string, default=null)
Allows to paint some fixed graphics in the content block. Currently
only text labels in normal font are supported. Example string:
label{x=50}{y=600}{text=Text:}{color=7}label{x=70}{y=659}{text=Some text.}{color=15}
The x,y are specified relatively to the content block rectangle.
Extra content objects normally should not cross the content block
bounds.
NOTE: Available in firmware 121201+.
- paint_item_info_in_details (boolean, default=true)
Whether to paint text in details block. If false => only icon is
painted in details block.
- item_detailed_info_rel_y (non-negative integer, default=auto)
Specifies the Y-position of details text relative to the top of the
details block, if specified.
If not specified, then icon scale_factor is calculated w/o
height-limitations and the text is placed just below the icon.
If specified, then text is painted at the specified Y-coordinate, and
the icon's scale_factor/position are calculated respectively.
- zoom_detailed_icon (boolean, default=false)
- detailed_icon_scale_factor (double, default=auto)
If 'zoom_detailed_icon' is true => the detailed icon is scaled to fit
into details block by width (even upscaled if needed).
Otherwise, if 'detailed_icon_scale_factor' is specified => the
detailed icon is scaled using this factor. Otherwise, the detailed
icon scale-factor is calculated automatically to fit into details
block width and into 'item_detailed_info_rel_y', if specified.
- detailed_icon_valign (top|center|bottom, default=top)
Vertical alignment of the detailed icon in case
'item_detailed_info_rel_y' is specified and is greater than actual
detailed icon height.
PHP constants available: VALIGN_TOP, VALIGN_CENTER, VALIGN_BOTTOM.
NOTE: Available in firmware 120606+.
- item_detailed_info_font_size (normal|small, default=normal)
PHP constants available: FONT_SIZE_NORMAL, FONT_SIZE_SMALL
- item_detailed_info_title_color (integer color index 0..23, default=8)
- item_detailed_info_text_color (integer color index 0..23, default=7)
The text color index for detailed info 'title' and 'text'. See
description of ViewItemParams::item_detailed_info for more details.
- item_detailed_info_auto_line_break (boolean, default=false)
Whether to automatically break detailed info text into lines, when
line does not fit into width. Also see the
ViewItemParams::item_detailed_info for more details.
NOTE: Available in firmware 120605+.
- paint_sandwich (boolean, default=false)
Whether to paint all item using "sandwich". Sandwich consists of 4
components:
Base (icon or cut-image)
Mask (icon or cut-image, only alpha channel is used)
Cover (icon or cut-image)
Icon (icon)
Sandwich is painted using following sequence:
- first, Base is painted as background into buffer.
- next, Icon is painted into buffer; typically centered if
smaller or downscaled if bigger.
- next, alpha from Mask is merged with alpha from buffer.
- finally, cover is painted into buffer.
- sandwich_base (string, image URL or cut_icon URL string,
default=unset)
- sandwich_mask (string, image URL or cut_icon URL string,
default=unset)
- sandwich_cover (string, image URL or cut_icon URL string,
default=unset)
Sandwich Base, Mask and Cover components, as images or cut-icons.
The following URLs can be used, taken from skin:
sandwich_base=gui_skin://special_icons/sandwich_base.aai
sandwich_mask=cut_icon://{name=sandwich_mask}
sandwich_cover=cut_icon://{name=sandwich_cover}
- sandwich_width (non-negative integer, default=0 meaning "auto")
- sandwich_height (non-negative integer, default=0 meaning "auto")
- sandwich_sel_width (non-negative integer, default=0 meaning "auto")
- sandwich_sel_height (non-negative integer, default=0 meaning "auto")
Sandwich dimensions in selected and non-selected state.
- sandwich_icon_keep_aspect_ratio (boolean, default=true)
Whether to keep icon aspect ratio when scaling.
- sandwich_icon_upscale_enabled (boolean, default=false)
Whether to upscale icon to fit sandwich bounds. NOTE: the downscale
is always performed when needed.
- sandwich_icon_scale_factor (positive double in range (0..1], default=1)
Specifies how to scale icon relative to the sandwich bounds. Can be
overridden by ViewItemParams::item_sandwich_icon_scale_factor.
List of ViewItemParams properties
- item_paint_icon (boolean, default=true)
Whether to paint current item's icon in content block.
- item_paint_caption (boolean, default=true)
Whether to paint item caption text in content block.
- item_paint_unselected_caption (boolean, default=true)
Whether to paint captions for currently non-selected items.
NOTE: Available in firmware 130818+.
- item_caption_font_size (normal|small, default=normal)
Item caption font size.
PHP constants available: FONT_SIZE_NORMAL, FONT_SIZE_SMALL.
- item_paint_caption_within_icon (boolean, default=false)
If true, the caption is painted inside icon. This option typically is
used together with item_paint_caption=0.
- item_caption_within_icon_color (string representing color, the
following values allowed: white, black, 0, 1, 2, ... 23;
default=white)
Specifies color of caption text within icon.
- item_padding_top (non-negative integer, default=0)
- item_padding_bottom (non-negative integer, default=0)
Specifies vertical padding of icon+caption area inside the item
block. Normally caption is painted in the bottom and icon is
Y-aligned in the rest of vertical space above caption.
- icon_path (image URL string, mandatory)
- icon_sel_path (image URL string, by default equals to icon_path)
Icon URL in selected and non-selected state.
- icon_width (non-negative integer, default=0 meaning auto)
- icon_height (non-negative integer, default=0 meaning auto)
- icon_sel_width (non-negative integer, default=0 meaning auto)
- icon_sel_height (non-negative integer, default=0 meaning auto)
Icon dimensions in selected and non-selected state. If not specified,
the real icon image dimensions will be used.
- icon_keep_aspect_ratio (boolean, default=yes)
Whether to keep icon aspect ratio when scaling to the predefined
dimensions (see ViewItemParams::icon_width and
ViewItemParams::icon_height).
- icon_scale_factor (positive double, default=1.0)
- icon_sel_scale_factor (positive double, default=auto)
Icon scale factor in selected and non-selected state.
- icon_margin_top (integer, default=0)
- icon_margin_bottom (integer, default=0)
- icon_margin_left (integer, default=0)
- icon_margin_right (integer, default=0)
- icon_sel_margin_top (integer, default=0)
- icon_sel_margin_bottom (integer, default=0)
- icon_sel_margin_left (integer, default=0)
- icon_sel_margin_right (integer, default=0)
Icon margins in selected and non-selected state.
- item_layout (left|center, default=center)
The default layout is "center", meaning that icon and caption are
horizontally centered, icon is painted above caption. When "left" is
chosen, the icon and caption are vertically centered, icon is aligned
to the left of rectangle and caption text is painted starting from
the left bound of text area block. The text area block is
right-aligned but normally it occupies all item rectangle width. So,
to avoid painting text over icon, it is needed to change
ViewItemParams::item_caption_dx or ViewItemParams::item_caption_width
respectively. PHP constants available: HALIGN_CENTER, HALIGN_LEFT.
- icon_valign (top|center|bottom, default=top)
The method of vertical alignment of icon (between the upper bound of
item rectangle from top and the caption from bottom). It is used
only when ViewItemParams::item_layout = HALIGN_CENTER. PHP constants
available: VALIGN_TOP, VALIGN_CENTER, VALIGN_BOTTOM.
- icon_dx (integer, default=0)
- icon_dy (integer, default=0)
- icon_sel_dx (integer, default=0)
- icon_sel_dy (integer, default=0)
The additional icon horizontal/vertical offset in selected and
non-selected state.
- icon_fit_scale_factor (double in range (0..1], default=0.9)
Used only when ViewParams::paint_icon_badge_box = true.
In badge mode icon is downscaled and centered into badge box, using
this scale factor as parameter.
NOTE: Available in firmware 120605+.
- item_caption_wrap_enabled (boolean, default=false)
Allows to show the long captions in 2 rows. If 2 rows are not
enough then caption is painted in 1 row with scrolling.
The overall content block layout must ensure that 2-row caption
does not cross the content block bounds.
- item_caption_width (non-negative integer, default=0 meaning auto)
Allows to change the default width of caption text block. By default
the text block occupies all item rectangle width.
- item_caption_dx (integer, default=0)
Moves the left bound of caption text block, the right bound remains
unchanged.
- item_caption_dy (integer, default=0)
- item_caption_sel_dy (integer, default=0)
Additionally changes the vertical position of caption in selected and
non-selected states separately.
- item_caption_color (integer color index 0..23, default=auto)
Caption text color. By default 15 is used (white).
- item_detailed_info (string, default=unset)
Structured text to be painted in the details block when current item
is selected (focused). It may contain several paragraphs, each
paragraph may have separated single-line title and a multiline text.
The paragraphs are separated by '||'; the title and text lines are
separated by '|'. The auto line breaking can also be used instead of
'|' to separate text lines (see
ViewParams::item_detailed_info_auto_line_break). Example of
item_detailed_info:
Title 1|line 1.1|line 1.2|line 1.3||Title 2|line2.1|line2.2
- item_detailed_icon_path (image URL string, default=icon_path)
Allows to specify icon to be painted in details block; by default the
same icon is used for content block and for details block.
- item_badge_icon_path (image URL string, default=unset)
Specifies icon to be pained instead of the default skin badge cut
image. Affects only badge mode
(ViewParams::paint_icon_badge_box=true).
This property is ignored in GUI skins having enable_badge_icons=no
unless ViewItemParams::item_override_default_badge is set to true.
NOTE: Available in firmware 120830+.
- item_override_default_badge (boolean, default=false)
When true, the ViewItemParams::item_badge_icon_path overrides the
default GUI skin badge even for skins with enable_badge_icons=no.
NOTE: Available in firmware 131005+.
- item_sandwich_icon_scale_factor (double in range (0..1], default=auto)
Specifies how to scale icon relative to the sandwich bounds. If not
set, the ViewParams::sandwich_icon_scale_factor used instead.
Other functionality
The GComponents framework (gcomp*) is currently unfinished and is currently
reserved for internal use only.
Porting plugins to SMP87xx platforms
Please see the following sections:
- "Differences between SMP86xx and SMP87xx platforms"
- "Including platform-specific files for SMP87xx platforms"
Also please see the following:
- http://files.dune-hd.com/sdk/doc/html/smp875x.html
- http://files.dune-hd.com/sdk/doc/html/dune_devel_info.html#toolchain_for_smp87xx_arm_platforms
Differences between SMP86xx and SMP87xx platforms
All the features PHP plugins framework and the plugins mechanism in general
(manifest files, www/ and www/cgi-bin folders, etc) are fully supported on
SMP87xx platforms the same way as on SMP86xx platforms.
The main differences between SMP86xx and SMP87xx platforms which affect
plugins are the following:
- SMP87xx platforms do not support outdated FlashLite technology.
- SMP87xx plarforms do support HTML applications and Dune STB JS API,
but a slightly different version of the web browser engine is used
(QtWebkit based), and there may be slight differences in the behavior
and supported features of the web browser engine and in the behavior
and supported features of Dune STB JS API implementation. So it is
recommended to carefully test if HTML application works correctly on
SMP87xx platform, and some adaptation/porting may be required.
- The playback engine on SMP87xx platform is based on the playback
engine of SMP86xx platforms and supports the same streaming protocols
and media formats and features (and even more, e.g. DASH streaming
protocol and H.265 video codec), but some incompatibilities and slight
differences potentially may take place. So it is recommended to
carefully test if the media content is played OK on SMP87xx platform,
and some adaptation/porting may be required.
- If the plugin includes native binary code (such as binary executables
or libraries, Linux kernel drivers, or other platform-specific files),
the plugin should carry two versions of such platform-specific files
-- one version for SMP86xx platform, another version for SMP87xx
platform; for more details, see "Including platform-specific files for
SMP87xx platforms" section.
- SMP87xx platforms support background playback feature -- by pressing
TOP MENU RC button, the user can return to the main menu, keeping
video or audio playback in background (to return to the playback, TOP
MENU RC button can be pressed again, or "Now playing" POP UP MENU item
can be used). When navigating the main menu, the user can navigate
through the screens of the same plugin which controls the current
playback session; to ensure that this works correctly, the plugin
should take this use case into account.
Including platform-specific files for SMP87xx platforms
If the plugin includes files specific to SMP86xx platforms which can not be
used on SMP87xx platforms (such as executable binary files for MIPS CPU),
the following approach should be used to add support for SMP87xx platform.
At the top level of the plugin, folder ".platform.87xx" should be created,
and for each platform-specific file, the version of the file for SMP87xx
platform should be put under this folder.
For example:
bin/some_exe -- SMP86xx (MIPS) version of "some_exe"
www/cgi-bin/cgi_exe -- SMP86xx (MIPS) version of "cgi_exe"
.platform.87xx/bin/some_exe -- SMP87xx (ARM) version of "some_exe"
.platform.87xx/www/cgi-bin/cgi_exe -- SMP87xx (ARM) version of "cgi_exe"
When such a plugin is installed on SMP86xx platform, the content of
".platform.87xx" folder is automatically deleted from the plugin
installation directory.
When such a plugin is installed on SMP87xx platform, the content of
".platform.87xx" folder is automatically moved to the top level of the
plugin installation directory.
Toolchain to build native binaries for SMP87xx platforms can be found here:
- http://files.dune-hd.com/sdk/doc/html/dune_devel_info.html#toolchain_for_smp87xx_arm_platforms
Porting plugins to Android platforms
Please see the following sections:
- "Differences between Sigma and Android platforms"
- "Including platform-specific files for Android platforms"
Also please see the following:
- http://files.dune-hd.com/sdk/doc/html/dune_devel_info.html#toolchain_for_android_platforms
- http://files.dune-hd.com/sdk/doc/html/dune_devel_info.html#launching_executables_from_user_storages_on_android_platforms
- http://files.dune-hd.com/sdk/doc/html/dune_devel_info.html#important_notes_about_latest_atv_and_android_11_aosp_platforms
Differences between Sigma and Android platforms
All the features PHP plugins framework and the plugins mechanism in general
(manifest files, www/ and www/cgi-bin folders, etc) are fully supported on
Android platforms the same way as on Sigma (SMP87xx) platforms.
The main differences between Sigma and Android platforms which affect
plugins are the following:
- Android platforms do not support outdated FlashLite technology.
- Android plarforms do support HTML applications and Dune STB JS API,
but a slightly different version of the web browser engine is used,
and there may be slight differences in the behavior and supported
features of the web browser engine and in the behavior and supported
features of Dune STB JS API implementation. So it is recommended to
carefully test if HTML application works correctly on Android
platform, and some adaptation/porting may be required.
- The playback engine on Android platform is similar to the playback
engine of Sigma platforms and in general supports the same streaming
protocols and media formats and features (and even more, e.g. 4Kp60
video, Widevine DRM, etc), but the core part of the playback engine is
different and some incompatibilities and slight differences
potentially may take place. So it is recommended to carefully test if
the media content is played OK on Android platform, and some
adaptation/porting may be required.
- If the plugin includes native binary code (such as binary executables
or libraries, or other platform-specific files), the plugin should
carry several versions of such platform-specific files -- one or two
version for Sigma SMP86xx/SMP87xx platforms, and another version for
Android platform; for more details, see "Including platform-specific
files for Android platforms" section.
- On Android platforms, user storages are mounted with "noexec" flag,
which may complicate the use of "dune_plugins" folder mechanism. See
the following for more information and possible workaround:
- http://files.dune-hd.com/sdk/doc/html/dune_devel_info.html#launching_executables_from_user_storages_on_android_platforms
Including platform-specific files for Android platforms
If the plugin includes files specific to Sigma platforms which can not be
used on Android platforms (such as executable binary files), the following
approach should be used to add support for Android platform.
At the top level of the plugin, folder ".platform.android" should be
created, and for each platform-specific file, the version of the file for
Android platform should be put under this folder.
For example:
bin/some_exe -- SMP86xx (MIPS) version of "some_exe"
www/cgi-bin/cgi_exe -- SMP86xx (MIPS) version of "cgi_exe"
.platform.87xx/bin/some_exe -- SMP87xx (ARM) version of "some_exe"
.platform.87xx/www/cgi-bin/cgi_exe -- SMP87xx (ARM) version of "cgi_exe"
.platform.android/bin/some_exe -- Android version of "some_exe"
.platform.android/www/cgi-bin/cgi_exe -- Android version of "cgi_exe"
When such a plugin is installed on Android platform, the content of
".platform.android" folder is automatically deleted from the plugin
installation directory.
When such a plugin is installed on Android platform, the content of
".platform.87xx" folder is automatically moved to the top level of the
plugin installation directory.
Toolchain to build native binaries for Android platforms can be found here:
- http://files.dune-hd.com/sdk/doc/html/dune_devel_info.html#toolchain_for_android_platforms
Debugging plugins
Here are some hints which can be helpful to debug plugins during
development.
During plugin development/debugging, it is recommended to create
convenience scripts for typical repetitive actions which can include some
of the below commands (or similar commands).
See the logs of the plugin:
On Sigma platforms (in telnet session):
tail -F /tmp/run/<plugin_name>.log
On Android platforms (in telnet or ADB session):
busybox tail -F /tmp/run/<plugin_name>.log
On Android platforms (on remote PC via ADB):
adb shell busybox tail -F /tmp/run/<plugin_name>.log
Copy plugin files from PC into STB flash memory via ADB on Android platforms:
# local folder <plugin_name> should contain files to deploy to the STB
adb shell rm -rf /flashdata/plugins/<plugin_name>
adb push <plugin_name> /flashdata/plugins/
adb shell chmod -R +x /flashdata/plugins/<plugin_name>/bin
adb shell chmod -R +x /flashdata/plugins/<plugin_name>/www/cgi-bin
Restart shell process (to reload all plugins):
On Sigma platforms (in telnet session):
killall shell
On Android platforms (in telnet or ADB session):
killall com.dunehd.shell
On Android platforms (on remote PC via ADB):
adb shell killall com.dunehd.shell
Request shell process to reload plugins w/o restarting shell process:
Go to the top menu of the shell and press "ANGLE/ROTATE" button on the
old Dune HD RCU (or choose "Refresh" action in POP UP MENU), or navigate
to the top menu and send "ANGLE/ROTATE" IR code (00 BF 4D B2) via IP
Control:
curl 'http://dune-ip-address/cgi-bin/do?cmd=main_screen'
curl 'http://dune-ip-address/cgi-bin/do?cmd=ir_code&ir_code=B24DBF00'