Flussonic Media Server documentation

Contents

Cluster Management via the SQL API

Flussonic Media Server allows you to manage streams (create, update, delete, and select) across an entire cluster of servers via a single entry point. In this article we will explain how to do it in detail.
You do not need to install MySQL server. Flussonic Media Server does not work with MySQL server but it behaves as if it itself was a MySQL server.

After you specify mysql 3306; in the configuration file, Flussonic Media Server binds to this port and works as a MySQL server (with only certain functionality). So do not install MySQL server!

Usually, a MySQL client tries to connect to MySQL server via a Unix domain socket. When you tell it to connect to localhost, it tries to open something like /tmp/mysql.sock or whatever else. Flussonic Media Server listens strictly on a TCP socket, so when you try to do it on localhost, you need to use 127.0.0.1. Usually it is an alias, but in case of MySQL client, there is a difference.

The cluster key

Servers in a cluster use cluster_key to authorize on each other. The cluster key is an arbitrary sequence of numbers and characters that you need to generate or make up. This key is saved in the server's global options.

To specify the cluster key on the current Flussonic Media Server, declare cluster_key by using either of the means:

  • In the configuration file, in the server's global options section.

    Example:

    cluster_key wjFxSiSG6EC6e2;
    
  • In the Flussonic's web interface in Cluster > Settings.

    Flussonic cluster

Servers in a cluster

First learn about the concept of servers in a cluster. Each Flussonic Media Server knows about itself, and to tell Flussonic about other servers in a cluster you must use the directive peer. Servers in a cluster use cluster_key to authorize on each other.

Adding cluster_key to the peer directive means telling Flussonic which cluster_key it must use to connect to another Flussonic server. By default, Flussonic Media Server uses its own cluster key to connect with peers.

Example

If you have two servers: srv01.cdn.local and srv02.cdn.local, you can configure them in the following way:

srv01.cdn.local:

http 80;
mysql 3306;
edit_auth admin secretpass;
cluster_key mcXpNJyZX3mSE3;
peer srv01.cdn.local;
peer srv02.cdn.local {
  cluster_key wjFxSiSG6EC6e2;
}

srv02.cdn.local:

http 80;
cluster_key wjFxSiSG6EC6e2;

When you configure the servers in such a way, srv01 will periodically ping srv02 and fetch the status of streams on it.

Now let's take a look at how you can set up the same confguration with the SQL API:

$ mysql -u admin -psecretpass -h srv01.cdn.local cluster
mysql> INSERT INTO peers (hostname,cluster_key) VALUES ('srv02.cdn.local','wjFxSiSG6EC6e2');
Query OK, 1 row affected (0.36 sec)

mysql> SELECT * FROM peers;
+----------------------+-----------+--------------------------------------+------+----------------+--------+------+
| hostname             | available | id                                   | port | cluster_key    | uptime | load |
+----------------------+-----------+--------------------------------------+------+----------------+--------+------+
| srv02.cdn.local      |         1 | bcac6edd-46a7-40cc-970a-5da3bec8d94b |   80 | wjFxSiSG6EC6e2 |  78715 | NULL |
| localhost            |         1 | cd30c5a4-3dda-4ac1-a2eb-a9b765918082 |   80 | mcXpNJyZX3mSE3 |   NULL |    0 |
+----------------------+-----------+--------------------------------------+------+----------------+--------+------+

Now you get the same configuration as described above. If you see a value in id, it means that the current Flussonic Media Server was able to connect to the remote Flussonic Media Server and establish peering. You will see the uptime and even load (output bandwidth utilization in percents).

You can delete this server from your configuration:

mysql> DELETE FROM peers WHERE hostname='srv02.cdn.local';
Query OK, 1 row affected (0.68 sec)

Now this server is deleted and you will not see streams from this server.

Stream management

You can get access to all streams on all your servers via a single place by using a regular SQL API.

Flussonic allows you to store some metadata directly in a stream confguration section in the file flussonic.conf, so perhaps you don't need to work with the streams table in your management system.

Stream is identified by the name column and have column server with the hostname of the server on which the stream is "located".

If you don't specify the server when creating a stream, it will be created on the server to which you are connected. If you specify the server, the stream will be created on the specified server.

You don't need to specify the server when you update, delete, or select a stream, because Flussonic Media Server will automatically find out on which server a stream is running.

The structure of the Peers table

The peers (servers in a cluster) table contains the following columns:

Field Type Description
hostname string
available bool
id string
port integer
https_port integer
rtmp_port integer
rtsp_port integer
cluster_key string
uptime integer
meta string
bandwidth_usage integer outbound traffic, % from total_bandwidth
cpu_usage integer CPU usage in %
memory_usage integer memory usage, % from RAM
total_clients integer
online_streams integer
total_streams integer
version string
build integer
is_remote bool
is_peer bool
is_source bool
error string
fetched_at integer
vsaas bool internal
vsaas_endpoint string internal
rproxy bool internal
rproxy_streampoint_key string internal
rproxy_endpoint_auth string internal
camera_alarm integer
camera_alarm_address string
camera_alarm_patterns string

The structure of the Streams table

The streams table is rather wide because each stream has a lot of information.

Field Type Description
name string stream name
title string mpegts title
provider string mpegts title
static bool static / ondemand
pulse_off bool exclude a stream from resource usage statistics
position integer position (for vod files)
disabled bool
retry_limit integer
source_timeout integer
password string
url publish bool
prefix string http://yourwebsite.com/…
max_bitrate integer
on_publish string
motion_detector_enabled bool
motion_detector_notify string
motion_detector_tags string
transcoder string
dvr_root string path to archive or reference to RAID storage
hls_off bool the protocol is turned off
hds_off bool the protocol is turned off
rtmp_off bool the protocol is turned off
rtsp_off bool the protocol is turned off
dash_off bool the protocol is turned off
mpegts_off bool the protocol is turned off
webrtc_off bool the protocol is turned off
m4s_off bool the protocol is turned off
m4f_off bool the protocol is turned off
mseld_off bool the protocol is turned off
url_prefix string
segment_count integer
segment_duration integer
prepush integer
backup string
add_audio_only bool
max_sessions integer
thumbnails_enabled bool
thumbnails_url string screenshots address (jpeg)
clients_timeout integer
push string
external_cache string internal
auth_url string
domains string
allowed_countries string
disallowed_countries string
glue_ts bool
vsaas bool internal
iptv bool internal
comment string
coordinates string internal
postal_address string internal
owner string internal
auth_token string internal
mobile_token string internal
access string internal
onvif_url string internal
onvif_profile string internal
can_ptz bool internal
dvr_protected bool internal
agent_id string internal
agent_pin string internal
agent_key string internal
agent_model string internal
agent_serial string internal
registered_at integer internal
program_id integer internal
stream_id integer internal
extra string internal
dvr string
dvr_no_index bool not create idx index
urls string
cluster_ingest bool
alive bool
remote bool
source_hostname string
lifetime integer internal
start_running_at integer
ts_delay integer internal
retry_count integer
client_count integer
last_dts integer internal
last_dts_at integer internal
last_access_at integer
input_error_rate integer internal
bytes_in integer
bytes_out integer
out_bandwidth integer
bufferings integer internal
bitrate integer
source_error string source error
url string
current_agent_id string internal
agent_status string internal
server string
published_from string publication source IP address
published_via string publication format
dvr_only bool internal
running_transcoder bool
dvr_replication integer
dvr_replication_running bool

You can see that not all configuration options are here yet, we are working on it.

Creating streams

When you first launch a new cluster, you have no streams:

mysql> select * from streams;
Empty set (0.00 sec)

Here and later we assume that you have configured the path to VOD on all servers:

file vod {
  path priv;
}

and the file bunny.mp4 is located in this priv path.

Let's create a stream:

mysql> insert into streams (name,urls,dvr) values  ('bunny1','file://vod/bunny.mp4','movies 2d 20G');
Query OK, 1 row affected (0.02 sec)
mysql> select name,static,urls,lifetime,server from streams;
+--------+--------+----------------------+----------+-----------+
| name   | static | urls                 | lifetime | server    |
+--------+--------+----------------------+----------+-----------+
| bunny1 |      1 | file://vod/bunny.mp4 |    27029 | localhost |
+--------+--------+----------------------+----------+-----------+
1 row in set (0.01 sec)

Now let's make our cluster work:

mysql> insert into streams (name,urls,dvr,server) values  ('bunny2','file://vod/bunny.mp4','movies 2d 20G','srv02.cdn.local');
Query OK, 1 row affected (0.03 sec)

mysql> select name,static,urls,lifetime,server from streams;
+--------+--------+----------------------+----------+-----------------+
| name   | static | urls                 | lifetime | server          |
+--------+--------+----------------------+----------+-----------------+
| bunny1 |      1 | file://vod/bunny.mp4 |   108025 | localhost       |
| bunny2 |      1 | file://vod/bunny.mp4 |     3989 | srv02.cdn.local |
+--------+--------+----------------------+----------+-----------------+
2 rows in set (0.00 sec)

This demonstrates that you can create streams on all your servers via a single entry point. You need only to specify the server where you want to create a stream.

Updating streams

When updating stream information, you don't need to specify the server explicitly. It is very convenient because you don't need to remember where your stream is.

mysql> update streams set url_prefix='http://srv02.cdn.local' where name='bunny2';
Query OK, 1 row affected (0.02 sec)

mysql> select name,static,urls,lifetime,server,url_prefix from streams;
+--------+--------+----------------------+----------+-----------------+------------------------+
| name   | static | urls                 | lifetime | server          | url_prefix             |
+--------+--------+----------------------+----------+-----------------+------------------------+
| bunny1 |      1 | file://vod/bunny.mp4 |   429009 | localhost       | NULL                   |
| bunny2 |      1 | file://vod/bunny.mp4 |   319980 | srv02.cdn.local | http://srv02.cdn.local |
+--------+--------+----------------------+----------+-----------------+------------------------+
2 rows in set (0.01 sec)

Flussonic Media Server "knows" on what server a stream runs, so it will not require specifying it from you.

However, within a cluster, the name is not a unique field. If you duplicated stream names on several servers, you must specify the server on which you want to update a stream.

Deleting streams

Let's get rid of one of these streams:

mysql> delete from streams where name='bunny1';
Query OK, 1 row affected (0.02 sec)

mysql> select name,static,urls,lifetime,server,url_prefix from streams;
+--------+--------+----------------------+----------+-----------------+------------------------+
| name   | static | urls                 | lifetime | server          | url_prefix             |
+--------+--------+----------------------+----------+-----------------+------------------------+
| bunny2 |      1 | file://vod/bunny.mp4 |   593231 | srv02.cdn.local | http://srv02.cdn.local |
+--------+--------+----------------------+----------+-----------------+------------------------+
1 row in set (0.01 sec)

and then delete all other streams:

mysql> delete from streams where name='bunny2';
Query OK, 1 row affected (0.02 sec)

mysql> select name,static,urls,lifetime,server,url_prefix from streams;
Empty set (0.00 sec)

Flussonic Media Server follows the same rule for deletion as for updating or selecting. If you have a single stream in a cluster, Flussonic will find it and modify the configuration file of that remote server.

Migration of streams between servers

This is where magic begins. If you configured a stream on one server, all you need to do is to specify another server for it, and the migration will be performed automatically:

mysql> insert into streams (name,urls,dvr,server) values  ('bunny2','file://vod/bunny.mp4','movies 2d 20G','srv02.cdn.local');
Query OK, 1 row affected (0.03 sec)

mysql> select name,static,urls,lifetime,server from streams;
+--------+--------+----------------------+----------+-----------------+
| name   | static | urls                 | lifetime | server          |
+--------+--------+----------------------+----------+-----------------+
| bunny2 |      1 | file://vod/bunny.mp4 |     3889 | srv02.cdn.local |
+--------+--------+----------------------+----------+-----------------+
1 rows in set (0.00 sec)

mysql> update streams set server='srv03.cdn.local' where name='bunny2';
Query OK, 1 row affected (0.02 sec)

mysql> select name,static,urls,lifetime,server from streams;
+--------+--------+----------------------+----------+-----------------+
| name   | static | urls                 | lifetime | server          |
+--------+--------+----------------------+----------+-----------------+
| bunny2 |      1 | file://vod/bunny.mp4 |     3989 | srv03.cdn.local |
+--------+--------+----------------------+----------+-----------------+
1 rows in set (0.00 sec)

You can move streams from any server to any other one. Flussonic Media Server will create them on the new server and delete on the old.

GPU table

The gpu table contains information about the current GPU usage.

Query examples:

  • SELECT * FROM gpu
MySQL [cluster]> select * from gpu;
+---------+------+-------+-------------+--------+---------+---------+------+
| server  | hwid | power | temperature | memory | encoder | decoder | sm   |
+---------+------+-------+-------------+--------+---------+---------+------+
| encoder | nv1  |     8 |          37 |      0 |       0 |       0 |    0 |
| encoder | nv0  |    20 |          41 |      0 |       0 |       0 |    0 |
+---------+------+-------+-------------+--------+---------+---------+------+
2 rows in set (0.00 sec)
  • SELECT * FROM gpu ORDER BY sm DESC - sort data by CUDA usage
mysql> select * from gpu order by sm desc;
+--------+------+-------+-------------+--------+---------+---------+------+
| server | hwid | power | temperature | memory | encoder | decoder | sm   |
+--------+------+-------+-------------+--------+---------+---------+------+
| 4gpu   | nv2  |    46 |          36 |      2 |      11 |       7 |    7 |
| 4gpu   | nv3  |    45 |          32 |      2 |      10 |       7 |    6 |
| 4gpu   | nv0  |    43 |          38 |      2 |       7 |       3 |    4 |
| 4gpu   | nv1  |    44 |          34 |      1 |       2 |       3 |    3 |
+--------+------+-------+-------------+--------+---------+---------+------+

Description of colums:

  • server - hostname of the server
  • hwid - gpu ID, the same ID is used in transcoder settings (deviceid=1)
  • power - current power usage in watts
  • temperature - temperature in °C
  • memory - memory usage in %
  • encoder - encoder usage in %
  • decoder - decoder usage in %
  • sm - CUDA usage in %.