Skip to content

Commit

Permalink
mvp - done
Browse files Browse the repository at this point in the history
  • Loading branch information
alexmorbo committed Feb 8, 2023
1 parent 859ace5 commit 80a452b
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 37 deletions.
91 changes: 91 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,93 @@
# ReactPHP Trassir API Client

![GitHub last commit](https://img.shields.io/github/last-commit/alexmorbo/react-trassir)
![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/alexmorbo/react-trassir/docker-publish.yml)

This application allows you to control Trassir Server via API

[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/alexmorbo)

## Installation

Docker
```bash
docker run -d --name trassir-api-client -p 8080:8080 \
-v /path/to/data.db:/app/data/data.db \
ghcr.io/alexmorbo/react-trassir:master
```

## Usage

Application exposes api, default on port 8080

Endpoints:
- POST /instances - add trassir instance
POST JSON:
```json
{
"ip": "11.11.11.11",
"http_port": 8080,
"rtsp_port": 555,
"login": "username",
"password": "password"
}
```

- GET /instances - get all instances

Example:
```json
[
{
"id": 1,
"ip": "11.11.11.11",
"name": "some_server_name",
"http_port": 8080,
"rtsp_port": 555,
"login": "username",
"password": "password",
"created_at": "2023-02-07 21:10:22",
"state": 1,
"channels": [
{
"guid": "some_guid",
"name": "some_name",
"rights": "1",
"codec": "H.264",
"have_mainstream": "1",
"have_substream": "1",
"have_hardware_archive": "0",
"have_ptz": "1",
"fish_eye": 0,
"have_voice_comm": "0",
"aspect_ratio": "auto",
"flip": "",
"rotate": ""
},
...
],
"remote_channels": [
...
],
"zombies": [
...
],
"templates": [
...
]
},
...
]
```

- GET /instances/{id} - get instance by id
Response like GET /instances, but with single instance

- DELETE /instances/{id} - delete instance by id

- GET /instances/{id}/channel/{channelGuid}/screenshot - get screenshot from channel
channelGuid - guid of channel from GET /instances/{id}

- GET /instances/{id}/channel/{channelGuid}/video/{container} - get stream from channel
channelGuid - guid of channel from GET /instances/{id}
container - container of stream, can be: hls, rtsp
8 changes: 4 additions & 4 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

67 changes: 51 additions & 16 deletions src/Controller/InstanceController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
use AlexMorbo\React\Trassir\Dto\Instance;
use AlexMorbo\React\Trassir\Traits\DBTrait;
use AlexMorbo\React\Trassir\TrassirHelper;
use AlexMorbo\Trassir\TrassirException;
use Clue\React\SQLite\DatabaseInterface;
use Fig\Http\Message\StatusCodeInterface;
use HttpSoft\Response\JsonResponse;
use React\EventLoop\Loop;
use React\Http\Message\Response;
use React\Http\Message\ServerRequest;
use React\Promise\PromiseInterface;
Expand Down Expand Up @@ -46,10 +46,13 @@ function ($result) {
$promises = [];
foreach ($result as $instanceData) {
$promises[] = $this->trassirHelper->getInstance($instanceData['id'])
->then(fn(Instance $instance) => $instance->getTrassir()->getChannels())
->then(
function ($channels) use ($instanceData) {
return array_merge($instanceData, $channels);
function (Instance $instance) use ($instanceData) {
return array_merge(
$instanceData,
['state' => $instance->getTrassir()->getState()],
$instance->getTrassir()->getChannels()
);
}
);
}
Expand All @@ -71,10 +74,13 @@ function ($result) use ($instanceId) {
}

return $this->trassirHelper->getInstance($instanceId)
->then(fn(Instance $instance) => $instance->getTrassir()->getChannels())
->then(
function ($channels) use ($result) {
return array_merge($result[0], $channels);
function (Instance $instance) use ($result) {
return array_merge(
$result[0],
['state' => $instance->getTrassir()->getState()],
$instance->getTrassir()->getChannels()
);
}
)
->then(fn($instanceData) => new JsonResponse($instanceData));
Expand Down Expand Up @@ -115,11 +121,32 @@ public function addInstance(ServerRequest $request, Response $response): Promise

return $instanceId
->then(
function ($id) {
Loop::get()->addTimer(0, function () use ($id) {
$this->trassirHelper->connectByInstanceId($id);
});
return new JsonResponse(['id' => $id]);
function ($instanceId) {
return $this->trassirHelper
->connectByInstanceId($instanceId)
->then(
function (Instance $instance) use ($instanceId) {
return $instance->getTrassir()->getConnection()
->then(
function() use ($instance, $instanceId) {
$settings = $instance->getTrassir()->getSettings();
$this->dbUpdate(
'instances',
['name' => $settings['name']],
['id' => $instanceId]
);

return new JsonResponse(['status' => 'success', 'id' => $instanceId]);
}
)
->otherwise(
fn(TrassirException $e) => new JsonResponse([
'status' => 'error',
'error' => $e->getMessage()
], StatusCodeInterface::STATUS_INTERNAL_SERVER_ERROR)
);
}
);
},
function ($error) {
return new JsonResponse(['error' => $error]);
Expand Down Expand Up @@ -158,7 +185,7 @@ public function getChannelScreenshot(
$instanceId = (int)$instanceId;
return $this->trassirHelper->getInstance($instanceId)
->then(
function(Instance $instance) use ($channelId) {
function (Instance $instance) use ($channelId) {
foreach ($instance->getTrassir()->getChannels() as $type => $channels) {
foreach ($channels as $channel) {
if ($channel['guid'] === $channelId) {
Expand Down Expand Up @@ -195,14 +222,22 @@ public function getChannelVideo(

return $this->trassirHelper->getInstance($instanceId)
->then(
function(Instance $instance) use ($channelId, $streamType) {
function (Instance $instance) use ($channelId, $streamType) {
foreach ($instance->getTrassir()->getChannels() as $type => $channels) {
foreach ($channels as $channel) {
if ($channel['guid'] === $channelId) {
if ($type === 'channels') {
return $instance->getTrassir()->getVideo($instance->getName(), $channelId, $streamType);
return $instance->getTrassir()->getVideo(
$instance->getName(),
$channelId,
$streamType
);
} else {
return $instance->getTrassir()->getVideo($channel['server_guid'], $channelId, $streamType);
return $instance->getTrassir()->getVideo(
$channel['server_guid'],
$channelId,
$streamType
);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Dto/Instance.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Instance
private string $login;
private string $password;

public function __construct(array $instanceData, private Trassir $trassir)
public function __construct(array $instanceData, private readonly Trassir $trassir)
{
$this->id = $instanceData['id'];
$this->name = $instanceData['name'];
Expand Down
2 changes: 1 addition & 1 deletion src/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ private function initServer(string $ip, int $port): int

$router
->getHttpServer()
->on('error', fn() => dd(func_get_args()));
->on('error', fn() => var_dump(func_get_args()));

$router->listen();

Expand Down
16 changes: 1 addition & 15 deletions src/TrassirHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public function getTrassirInstance(array $instanceData): Trassir
{
$options = ConnectionOptions::fromServer(
Server::fromArray([
'id' => $instanceData['id'],
'host' => $instanceData['ip'],
'httpPort' => $instanceData['http_port'],
'rtspPort' => $instanceData['rtsp_port'],
Expand Down Expand Up @@ -85,21 +86,6 @@ function ($result) {

return all($promises);
}
)
->then(
function (array $instances) {
/**
* Update instance id in database
*/
foreach ($instances as $instanceId) {
$settings = $this->instances[$instanceId]->getTrassir()->getSettings();
$this->dbUpdate(
'instances',
['name' => $settings['name']],
['id' => $instanceId]
);
}
}
);
}
}

0 comments on commit 80a452b

Please sign in to comment.