News

17 May 2017

[Blog] Connecting to our API with PHP

Hello there! Carina here.

I reckon that those of you who are using MistServer have, perhaps without realising it, frequently interacted with its API: the MistServer Management Interface (or MI for short) is a javascript based webpage that uses the API to communicate with Mist. Through the API, it requests information from MistServer and saves any configuration edits.

For most users, the MI is all they'll need to configure MistServer to suit their needs. However, for some, it's not suitable. For example: suppose you'd want a group of users to be able to configure only a stream that belongs to them. MistServer can facilitate multiple users, but it doesn't support a permission system of the sort directly. Instead, PHP could be used to translate user inputs to API calls.

In this blog post, I'll explain what such a PHP implementation might look like. All the PHP code used for this example will be provided. I won't get too technical in the blog post itself, because I reckon that those who want all the details can read the PHP code, and those who can't, needn't be bothered with the exact reasons for everything. Additional information about how to use MistServer's API can be found in the documentation.

Resources

Communicating with MistServer

The first step is to set up a way to send HTTP POST requests to MistServer, with a JSON payload. I'll call this mistserver.php. I've used CURL to handle the HTTP request. MistServer will respond with a JSON encoded reply, which is translated to an associative array.

If MistServer is hosted on the same machine that will be running the php, authorization isn't required (new in 2.11). Otherwise, MistServer will reply telling us to authenticate using a special string. If this is the case, the password will be encrypted together with the authentication string, and sent back to MistServer along with the username. Once MistServer reports that the status is OK, the authentication part is stripped from MistServer's reply, and returned.

By default, we'll be using minimal mode, which means we'll be using less bandwidth, but mostly that MistServer's response will be less bulky and thus more readable.

Actually requesting things!

I've purposely left out showing any errors in mistserver.php, so that you guys can just copy the file and use it in your projects. We should probably still tell users when something happens, though! I've made a few examples of usage here, that does actually output something readable in a separate file, index.php.

MistServer never replies with an error key directly in its main object, so I've used that to report CURL or API errors.

I've created a new function, getData(), that adds error printing around the main communication function. It returns false if there was an error and the data array if there wasn't.

Reading

We're all set! Let's actually start requesting some information. How about we check which protocols are enabled?

getCurrentProtocols() calls getData() and asks MistServer to respond with the config object. We check if the communication was successful, and if the config key exists. Then, we loop over the configured protocols and print the connector name. That's it!

Sent: Received:
Array(
  "config" => true
)
Array(
  "config" => Array(
    "protocols" => Array(
      0 => Array(
        "connector" => "HTTP",
        "online" => 1
      ),
      [..]
    ),
    [..]
  )
)

Another example. Let's read the logs, and if there are any errors in it, print the most recent one. Note that MistServer only provides the last 100 log entries through the API, so there might not be any.

getLastErrorLog() also calls getData(), but this time requests the log array. If we get it back, we reverse the array to get the newest entries first, and then start looping over them, until we find an error. If we do, we print it.

Sent: Received:
Array(
  "log" => true
)
Array(
  "log" => Array(
    0 => 1494493673,
    1 => "CONF",
    2 => "Controller started"
  ),
  [..]
)

As you can see, using MistServer's API is actually quite straightforward. It's time we up the bar (slightly, don't worry) and try changing some of MistServer's configuration.

Writing

How about adding a stream? For this we'll use the addstream command. This command is available in the Open Source version from 2.11; it was already available in Pro versions.

Two parameters need to be included: the stream name and source. There can be more options, depending on what kind of source it is. Note that if addstream is used, and a stream with that name already exists, it will be overwritten.

The addStream($name,$options) function calls getData() with these values, checks if the stream exists in the reply, and returns it.

Sent: Received:
Array(
  "addstream" => Array(
    "example" => Array(
      "source" => "/path/to/file.flv"
    )
  )
)
Array(
  "streams" => Array(
    "example" => Array(
      "name" => "example",
      "source" => "/path/to/file.flv"
    ),
    "incomplete list" => 1
  )
)

Alright, great. Now, let's remove the stream again with the deletestream command. This command is available in the Open Source version from 2.11 as well.

The deleteStream($name) function calls getData(), and checks if the stream has indeed been removed.

Sent: Received:
Array(
  "deletestream" => Array(
    0 => "example"
  )
)
Array(
  "streams" => Array(
    "incomplete list" => 1
  )
)

And there you have it. The API truly isn't that complicated. So get on with it and integrate MistServer into your project!

Next time, you can look forward to Balder, who will be talking about the different streaming protocols.