Merge pull request from jb-alvarado/frontend

add Frontend, remove preview
This commit is contained in:
jb-alvarado 2022-07-25 17:30:53 +02:00 committed by GitHub
commit 651ed0edcc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 247 additions and 164 deletions

4
.gitignore vendored

@ -19,5 +19,7 @@
*.deb
*.rpm
/assets/*.db*
/dist/
/public/
tmp/
.vscode/

3
.gitmodules vendored Normal file

@ -0,0 +1,3 @@
[submodule "ffplayout-frontend"]
path = ffplayout-frontend
url = git@github.com:ffplayout/ffplayout-frontend.git

119
Cargo.lock generated

@ -19,6 +19,29 @@ dependencies = [
"tokio-util 0.7.3",
]
[[package]]
name = "actix-files"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d832782fac6ca7369a70c9ee9a20554623c5e51c76e190ad151780ebea1cf689"
dependencies = [
"actix-http",
"actix-service",
"actix-utils",
"actix-web",
"askama_escape",
"bitflags",
"bytes",
"derive_more",
"futures-core",
"http-range",
"log",
"mime",
"mime_guess",
"percent-encoding",
"pin-project-lite",
]
[[package]]
name = "actix-grants-proc-macro"
version = "2.0.1"
@ -296,6 +319,12 @@ dependencies = [
"password-hash",
]
[[package]]
name = "askama_escape"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341"
[[package]]
name = "async-attributes"
version = "1.1.2"
@ -386,7 +415,7 @@ dependencies = [
"async-global-executor",
"async-io",
"async-lock",
"crossbeam-utils 0.8.10",
"crossbeam-utils 0.8.11",
"futures-channel",
"futures-core",
"futures-io",
@ -558,9 +587,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "bytes"
version = "1.1.0"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
checksum = "f0b3de4a0c5e67e16066a0715723abd91edc2f9001d09c46e1dca929351e130e"
[[package]]
name = "bytestring"
@ -626,7 +655,7 @@ dependencies = [
[[package]]
name = "chrono"
version = "0.4.20-beta.1"
source = "git+https://github.com/chronotope/chrono.git#187819ff43e0e4da351b3ea4ac2d3076e06e8251"
source = "git+https://github.com/chronotope/chrono.git#acd4ecf09fd0e5e35e2b5d5e074f6e1cc77172fc"
dependencies = [
"num-integer",
"num-traits",
@ -636,9 +665,9 @@ dependencies = [
[[package]]
name = "clap"
version = "3.2.12"
version = "3.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab8b79fe3946ceb4a0b1c080b4018992b8d27e9ff363644c1c9b6387c854614d"
checksum = "54635806b078b7925d6e36810b1755f2a4b5b4d57560432c1ecf60bcbe10602b"
dependencies = [
"atty",
"bitflags",
@ -675,9 +704,9 @@ dependencies = [
[[package]]
name = "concurrent-queue"
version = "1.2.3"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83827793632c72fa4f73c2edb31e7a997527dd8ffe7077344621fc62c5478157"
checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3"
dependencies = [
"cache-padded",
]
@ -796,12 +825,12 @@ dependencies = [
[[package]]
name = "crossbeam-channel"
version = "0.5.5"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c02a4d71819009c192cf4872265391563fd6a84c81ff2c0f2a7026ca4c1d85c"
checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
dependencies = [
"cfg-if 1.0.0",
"crossbeam-utils 0.8.10",
"crossbeam-utils 0.8.11",
]
[[package]]
@ -843,12 +872,12 @@ dependencies = [
[[package]]
name = "crossbeam-queue"
version = "0.3.5"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f25d8400f4a7a5778f0e4e52384a48cbd9b5c495d110786187fc750075277a2"
checksum = "1cd42583b04998a5363558e5f9291ee5a5ff6b49944332103f251e7479a82aa7"
dependencies = [
"cfg-if 1.0.0",
"crossbeam-utils 0.8.10",
"crossbeam-utils 0.8.11",
]
[[package]]
@ -864,9 +893,9 @@ dependencies = [
[[package]]
name = "crossbeam-utils"
version = "0.8.10"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d82ee10ce34d7bc12c2122495e7593a9c41347ecdd64185af4ecf72cb1a7f83"
checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc"
dependencies = [
"cfg-if 1.0.0",
"once_cell",
@ -1000,19 +1029,19 @@ dependencies = [
[[package]]
name = "fastrand"
version = "1.7.0"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499"
dependencies = [
"instant",
]
[[package]]
name = "ffplayout"
version = "0.11.0"
version = "0.12.0"
dependencies = [
"clap",
"crossbeam-channel 0.5.5",
"crossbeam-channel 0.5.6",
"ffplayout-lib",
"futures",
"jsonrpc-http-server",
@ -1029,6 +1058,7 @@ dependencies = [
name = "ffplayout-api"
version = "0.5.0"
dependencies = [
"actix-files",
"actix-multipart",
"actix-web",
"actix-web-grants",
@ -1056,10 +1086,10 @@ dependencies = [
[[package]]
name = "ffplayout-lib"
version = "0.10.5"
version = "0.12.0"
dependencies = [
"chrono 0.4.20-beta.1",
"crossbeam-channel 0.5.5",
"crossbeam-channel 0.5.6",
"ffprobe",
"file-rotate",
"jsonrpc-http-server",
@ -1128,9 +1158,9 @@ dependencies = [
[[package]]
name = "flume"
version = "0.10.13"
version = "0.10.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ceeb589a3157cac0ab8cc585feb749bd2cea5cb55a6ee802ad72d9fd38303da"
checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577"
dependencies = [
"futures-core",
"futures-sink",
@ -1476,6 +1506,12 @@ dependencies = [
"pin-project-lite",
]
[[package]]
name = "http-range"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573"
[[package]]
name = "httparse"
version = "1.7.1"
@ -1725,9 +1761,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "lettre"
version = "0.10.0"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5677c78c7c7ede1dd68e8a7078012bc625449fb304e7b509b917eaaedfe6e849"
checksum = "2eabca5e0b4d0e98e7f2243fb5b7520b6af2b65d8f87bcc86f2c75185a6ff243"
dependencies = [
"base64",
"email-encoding",
@ -1845,6 +1881,16 @@ version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
[[package]]
name = "mime_guess"
version = "2.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef"
dependencies = [
"mime",
"unicase",
]
[[package]]
name = "minimal-lexical"
version = "0.2.1"
@ -2364,9 +2410,9 @@ dependencies = [
[[package]]
name = "redox_syscall"
version = "0.2.13"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42"
checksum = "534cfe58d6a18cc17120fbf4635d53d14691c1fe4d951064df9bd326178d7d5a"
dependencies = [
"bitflags",
]
@ -2548,18 +2594,18 @@ checksum = "a2333e6df6d6598f2b1974829f853c2b4c5f4a6e503c10af918081aa6f8564e1"
[[package]]
name = "serde"
version = "1.0.139"
version = "1.0.140"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0171ebb889e45aa68b44aee0859b3eede84c6f5f5c228e6f140c0b2a0a46cad6"
checksum = "fc855a42c7967b7c369eb5860f7164ef1f6f81c20c7cc1141f2a604e18723b03"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.139"
version = "1.0.140"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc1d3230c1de7932af58ad8ffbe1d784bd55efd5a9d84ac24f69c72d83543dfb"
checksum = "6f2122636b9fe3b81f1cb25099fcf2d3f542cdb1d45940d56c713158884a05da"
dependencies = [
"proc-macro2",
"quote",
@ -2664,9 +2710,12 @@ dependencies = [
[[package]]
name = "slab"
version = "0.4.6"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32"
checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
dependencies = [
"autocfg",
]
[[package]]
name = "smallvec"
@ -2733,7 +2782,7 @@ dependencies = [
"bytes",
"chrono 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
"crc",
"crossbeam-queue 0.3.5",
"crossbeam-queue 0.3.6",
"either",
"event-listener",
"flume",

@ -5,10 +5,9 @@
The ffplayout apps are mostly made to run on Linux as system services. But in general they should run on all platforms which are supported by Rust. At the moment the cross compiled version from *ffpapi* runs on Windows and Linux, and not on Mac. If it is needed there, it should be compile natively.
Check the [releases](https://github.com/ffplayout/ffplayout-engine/releases/latest) for pre compiled version.
Check the [releases](https://github.com/ffplayout/ffplayout/releases/latest) for pre compiled version.
**ffplayout-engine (ffplayout)**
-----
## **ffplayout-engine (ffplayout)**
[ffplayout](/ffplayout-engine/README.md) is 24/7 broadcasting solution. It can playout a folder with containing video clips, or play for every day a *JSON* playlist, while keeping the current playlist editable.
@ -39,7 +38,6 @@ Check the [releases](https://github.com/ffplayout/ffplayout-engine/releases/late
- **aevalsrc** (if video have no audio)
- **apad** (add silence if audio duration is to short)
- **tpad** (add black frames if video duration is to short)
- [separate preview stream](/docs/preview_stream.md)
- [output](/docs/output.md):
- **stream**
- **desktop**
@ -48,12 +46,13 @@ Check the [releases](https://github.com/ffplayout/ffplayout-engine/releases/late
- JSON RPC server, for getting infos about current playing and controlling
- [live ingest](/docs/live_ingest.md)
**ffplayout-api (ffpapi)**
-----
For preview stream, read: [/docs/preview_stream.md](/docs/preview_stream.md)
## **ffplayout-api (ffpapi)**
ffpapi is an [REST API](/ffplayout-api/README.md) for controlling the engine, manipulate playlists, add settings etc.
Requirements
-----
### Requirements
- RAM and CPU depends on video resolution, minimum 4 threads and 3GB RAM for 720p are recommend
- **ffmpeg** v4.2+ and **ffprobe** (**ffplay** if you want to play on desktop)
@ -61,8 +60,7 @@ Requirements
-----
JSON Playlist Example
-----
### JSON Playlist Example
```json
{
@ -95,15 +93,14 @@ JSON Playlist Example
}
```
**Warning**
-----
## **Warning**
(Endless) streaming over multiple days will only work when config have **day_start** value and the **length** value is **24 hours**. If you need only some hours for every day, use a *cron* job, or something similar.
-----
HLS output
-----
## HLS output
For outputting to HLS, output parameters should look like:
@ -124,8 +121,7 @@ out:
-----
JSON RPC
-----
## JSON RPC
The ffplayout engine can run a JSON RPC server. A request show look like:

@ -3,7 +3,7 @@ Description=Rest API for ffplayout
After=network.target remote-fs.target
[Service]
ExecStart=/usr/bin/ffpapi -l 127.0.0.1:8000
ExecStart=/usr/bin/ffpapi -l 0.0.0.0:8787
Restart=always
RestartSec=1
User=ffpu

@ -117,25 +117,7 @@ text:
out:
help_text: The final playout compression. Set the settings to your needs. 'mode'
has the options 'desktop', 'hls', 'null', 'stream'.
'preview' works only in streaming output and creates a separate preview stream.
mode: stream
preview: false
preview_param: >-
-s 512x288
-c:v libx264
-crf 24
-x264-params keyint=50:min-keyint=25:scenecut=-1
-maxrate 800k
-bufsize 1600k
-preset ultrafast
-tune zerolatency
-profile:v Main
-level 3.1
-c:a aac
-ar 44100
-b:a 128k
-flags +global_header
-f flv rtmp://preview.local/live/stream
output_param: >-
-c:v libx264
-crf 23

2
debian/postinst vendored

@ -16,6 +16,8 @@ if [ ! -d "/usr/share/ffplayout/db" ]; then
chown -R ${sysUser}. "/usr/share/ffplayout"
chown -R ${sysUser}. "/var/lib/ffplayout"
chown -R ${sysUser}. "/etc/ffplayout"
ln -s "/var/lib/ffplayout/tv-media" "/usr/share/ffplayout/public/"
fi
if [ ! -d "/var/log/ffplayout" ]; then

15
debian/postrm vendored Normal file

@ -0,0 +1,15 @@
#DEBHELPER#
sysUser="ffpu"
if [ -d "/usr/share/ffplayout" ]; then
yes | rm -rf "/usr/share/ffplayout" "/var/lib/ffplayout"
fi
if [ -d "/var/log/ffplayout" ]; then
yes | rm -rf "/var/log/ffplayout"
fi
if id $sysUser &>/dev/null; then
userdel -rf $sysUser
fi

@ -3,7 +3,7 @@
Run the API thru the systemd service, or like:
```BASH
ffpapi -l 127.0.0.1:8000
ffpapi -l 127.0.0.1:8787
```
For all endpoints an (Bearer) authentication is required.\
@ -14,7 +14,7 @@ For all endpoints an (Bearer) authentication is required.\
**Login**
```BASH
curl -X POST http://127.0.0.1:8000/auth/login/ -H "Content-Type: application/json" \
curl -X POST http://127.0.0.1:8787/auth/login/ -H "Content-Type: application/json" \
-d '{ "username": "<USER>", "password": "<PASS>" }'
```
**Response:**
@ -34,21 +34,21 @@ From here on all request **must** contain the authorization header:\
**Get current User**
```BASH
curl -X GET 'http://localhost:8000/api/user' -H 'Content-Type: application/json' \
curl -X GET 'http://127.0.0.1:8787/api/user' -H 'Content-Type: application/json' \
-H 'Authorization: Bearer <TOKEN>'
```
**Update current User**
```BASH
curl -X PUT http://localhost:8000/api/user/1 -H 'Content-Type: application/json' \
curl -X PUT http://127.0.0.1:8787/api/user/1 -H 'Content-Type: application/json' \
-d '{"mail": "<MAIL>", "password": "<PASS>"}' -H 'Authorization: <TOKEN>'
```
**Add User**
```BASH
curl -X POST 'http://localhost:8000/api/user/' -H 'Content-Type: application/json' \
curl -X POST 'http://127.0.0.1:8787/api/user/' -H 'Content-Type: application/json' \
-d '{"mail": "<MAIL>", "username": "<USER>", "password": "<PASS>", "role_id": 1, "channel_id": 1}' \
-H 'Authorization: Bearer <TOKEN>'
```
@ -58,7 +58,7 @@ curl -X POST 'http://localhost:8000/api/user/' -H 'Content-Type: application/jso
**Get Settings from Channel**
```BASH
curl -X GET http://127.0.0.1:8000/api/channel/1 -H "Authorization: Bearer <TOKEN>"
curl -X GET http://127.0.0.1:8787/api/channel/1 -H "Authorization: Bearer <TOKEN>"
```
**Response:**
@ -78,13 +78,13 @@ curl -X GET http://127.0.0.1:8000/api/channel/1 -H "Authorization: Bearer <TOKEN
**Get settings from all Channels**
```BASH
curl -X GET http://127.0.0.1:8000/api/channels -H "Authorization: Bearer <TOKEN>"
curl -X GET http://127.0.0.1:8787/api/channels -H "Authorization: Bearer <TOKEN>"
```
**Update Channel**
```BASH
curl -X PATCH http://127.0.0.1:8000/api/channel/1 -H "Content-Type: application/json" \
curl -X PATCH http://127.0.0.1:8787/api/channel/1 -H "Content-Type: application/json" \
-d '{ "id": 1, "name": "Channel 1", "preview_url": "http://localhost/live/stream.m3u8", \
"config_path": "/etc/ffplayout/ffplayout.yml", "extra_extensions": "jpg,jpeg,png", "timezone": "Europe/Berlin"}' \
-H "Authorization: Bearer <TOKEN>"
@ -93,7 +93,7 @@ curl -X PATCH http://127.0.0.1:8000/api/channel/1 -H "Content-Type: application/
**Create new Channel**
```BASH
curl -X POST http://127.0.0.1:8000/api/channel/ -H "Content-Type: application/json" \
curl -X POST http://127.0.0.1:8787/api/channel/ -H "Content-Type: application/json" \
-d '{ "name": "Channel 2", "preview_url": "http://localhost/live/channel2.m3u8", \
"config_path": "/etc/ffplayout/channel2.yml", "extra_extensions": "jpg,jpeg,png",
"timezone": "Europe/Berlin", "service": "ffplayout@channel2.service" }' \
@ -103,7 +103,7 @@ curl -X POST http://127.0.0.1:8000/api/channel/ -H "Content-Type: application/js
**Delete Channel**
```BASH
curl -X DELETE http://127.0.0.1:8000/api/channel/2 -H "Authorization: Bearer <TOKEN>"
curl -X DELETE http://127.0.0.1:8787/api/channel/2 -H "Authorization: Bearer <TOKEN>"
```
#### ffplayout Config
@ -111,7 +111,7 @@ curl -X DELETE http://127.0.0.1:8000/api/channel/2 -H "Authorization: Bearer <TO
**Get Config**
```BASH
curl -X GET http://localhost:8000/api/playout/config/1 -H 'Authorization: <TOKEN>'
curl -X GET http://127.0.0.1:8787/api/playout/config/1 -H 'Authorization: <TOKEN>'
```
Response is a JSON object from the ffplayout.yml
@ -119,7 +119,7 @@ Response is a JSON object from the ffplayout.yml
**Update Config**
```BASH
curl -X PUT http://localhost:8000/api/playout/config/1 -H "Content-Type: application/json" \
curl -X PUT http://127.0.0.1:8787/api/playout/config/1 -H "Content-Type: application/json" \
-d { <CONFIG DATA> } -H 'Authorization: <TOKEN>'
```
@ -130,14 +130,14 @@ Text presets are made for sending text messages to the ffplayout engine, to over
**Get all Presets**
```BASH
curl -X GET http://localhost:8000/api/presets/ -H 'Content-Type: application/json' \
curl -X GET http://127.0.0.1:8787/api/presets/ -H 'Content-Type: application/json' \
-H 'Authorization: <TOKEN>'
```
**Update Preset**
```BASH
curl -X PUT http://localhost:8000/api/presets/1 -H 'Content-Type: application/json' \
curl -X PUT http://127.0.0.1:8787/api/presets/1 -H 'Content-Type: application/json' \
-d '{ "name": "<PRESET NAME>", "text": "<TEXT>", "x": "<X>", "y": "<Y>", "fontsize": 24, \
"line_spacing": 4, "fontcolor": "#ffffff", "box": 1, "boxcolor": "#000000", "boxborderw": 4, "alpha": 1.0, "channel_id": 1 }' \
-H 'Authorization: <TOKEN>'
@ -146,7 +146,7 @@ curl -X PUT http://localhost:8000/api/presets/1 -H 'Content-Type: application/js
**Add new Preset**
```BASH
curl -X POST http://localhost:8000/api/presets/ -H 'Content-Type: application/json' \
curl -X POST http://127.0.0.1:8787/api/presets/ -H 'Content-Type: application/json' \
-d '{ "name": "<PRESET NAME>", "text": "TEXT>", "x": "<X>", "y": "<Y>", "fontsize": 24, \
"line_spacing": 4, "fontcolor": "#ffffff", "box": 1, "boxcolor": "#000000", "boxborderw": 4, "alpha": 1.0, "channel_id": 1 }' \
-H 'Authorization: <TOKEN>'
@ -155,7 +155,7 @@ curl -X POST http://localhost:8000/api/presets/ -H 'Content-Type: application/js
**Delete Preset**
```BASH
curl -X DELETE http://localhost:8000/api/presets/1 -H 'Content-Type: application/json' \
curl -X DELETE http://127.0.0.1:8787/api/presets/1 -H 'Content-Type: application/json' \
-H 'Authorization: <TOKEN>'
```
@ -170,7 +170,7 @@ here we communicate with the engine for:
**Send Text to ffplayout**
```BASH
curl -X POST http://localhost:8000/api/control/1/text/ \
curl -X POST http://127.0.0.1:8787/api/control/1/text/ \
-H 'Content-Type: application/json' -H 'Authorization: <TOKEN>' \
-d '{"text": "Hello from ffplayout", "x": "(w-text_w)/2", "y": "(h-text_h)/2", \
"fontsize": "24", "line_spacing": "4", "fontcolor": "#ffffff", "box": "1", \
@ -184,14 +184,14 @@ curl -X POST http://localhost:8000/api/control/1/text/ \
- reset
```BASH
curl -X POST http://localhost:8000/api/control/1/playout/next/ -H 'Content-Type: application/json'
curl -X POST http://127.0.0.1:8787/api/control/1/playout/next/ -H 'Content-Type: application/json'
-d '{ "command": "reset" }' -H 'Authorization: <TOKEN>'
```
**Get current Clip**
```BASH
curl -X GET http://localhost:8000/api/control/1/media/current
curl -X GET http://127.0.0.1:8787/api/control/1/media/current
-H 'Content-Type: application/json' -H 'Authorization: <TOKEN>'
```
@ -222,13 +222,13 @@ curl -X GET http://localhost:8000/api/control/1/media/current
**Get next Clip**
```BASH
curl -X GET http://localhost:8000/api/control/1/media/next/ -H 'Authorization: <TOKEN>'
curl -X GET http://127.0.0.1:8787/api/control/1/media/next/ -H 'Authorization: <TOKEN>'
```
**Get last Clip**
```BASH
curl -X GET http://localhost:8000/api/control/1/media/last/
curl -X GET http://127.0.0.1:8787/api/control/1/media/last/
-H 'Content-Type: application/json' -H 'Authorization: <TOKEN>'
```
@ -241,7 +241,7 @@ Control ffplayout process, like:
- status
```BASH
curl -X POST http://localhost:8000/api/control/1/process/
curl -X POST http://127.0.0.1:8787/api/control/1/process/
-H 'Content-Type: application/json' -H 'Authorization: <TOKEN>'
-d '{"command": "start"}'
```
@ -251,14 +251,14 @@ curl -X POST http://localhost:8000/api/control/1/process/
**Get playlist**
```BASH
curl -X GET http://localhost:8000/api/playlist/1?date=2022-06-20
curl -X GET http://127.0.0.1:8787/api/playlist/1?date=2022-06-20
-H 'Content-Type: application/json' -H 'Authorization: <TOKEN>'
```
**Save playlist**
```BASH
curl -X POST http://localhost:8000/api/playlist/1/
curl -X POST http://127.0.0.1:8787/api/playlist/1/
-H 'Content-Type: application/json' -H 'Authorization: <TOKEN>'
-- data "{<JSON playlist data>}"
```
@ -268,14 +268,14 @@ curl -X POST http://localhost:8000/api/playlist/1/
A new playlist will be generated and response.
```BASH
curl -X GET http://localhost:8000/api/playlist/1/generate/2022-06-20
curl -X GET http://127.0.0.1:8787/api/playlist/1/generate/2022-06-20
-H 'Content-Type: application/json' -H 'Authorization: <TOKEN>'
```
**Delete Playlist**
```BASH
curl -X DELETE http://localhost:8000/api/playlist/1/2022-06-20
curl -X DELETE http://127.0.0.1:8787/api/playlist/1/2022-06-20
-H 'Content-Type: application/json' -H 'Authorization: <TOKEN>'
```
@ -284,7 +284,7 @@ curl -X DELETE http://localhost:8000/api/playlist/1/2022-06-20
**Read Log Life**
```BASH
curl -X Get http://localhost:8000/api/log/1
curl -X Get http://127.0.0.1:8787/api/log/1
-H 'Content-Type: application/json' -H 'Authorization: <TOKEN>'
```
@ -293,34 +293,34 @@ curl -X Get http://localhost:8000/api/log/1
**Get File/Folder List**
```BASH
curl -X POST http://localhost:8000/api/file/1/browse/ -H 'Content-Type: application/json'
curl -X POST http://127.0.0.1:8787/api/file/1/browse/ -H 'Content-Type: application/json'
-d '{ "source": "/" }' -H 'Authorization: <TOKEN>'
```
**Create Folder**
```BASH
curl -X POST http://localhost:8000/api/file/1/create-folder/ -H 'Content-Type: application/json'
curl -X POST http://127.0.0.1:8787/api/file/1/create-folder/ -H 'Content-Type: application/json'
-d '{"source": "<FOLDER PATH>"}' -H 'Authorization: <TOKEN>'
```
**Rename File**
```BASH
curl -X POST http://localhost:8000/api/file/1/rename/ -H 'Content-Type: application/json'
curl -X POST http://127.0.0.1:8787/api/file/1/rename/ -H 'Content-Type: application/json'
-d '{"source": "<SOURCE>", "target": "<TARGET>"}' -H 'Authorization: <TOKEN>'
```
**Remove File/Folder**
```BASH
curl -X POST http://localhost:8000/api/file/1/remove/ -H 'Content-Type: application/json'
curl -X POST http://127.0.0.1:8787/api/file/1/remove/ -H 'Content-Type: application/json'
-d '{"source": "<SOURCE>"}' -H 'Authorization: <TOKEN>'
```
**Upload File**
```BASH
curl -X POST http://localhost:8000/api/file/1/upload/ -H 'Authorization: <TOKEN>'
curl -X POST http://127.0.0.1:8787/api/file/1/upload/ -H 'Authorization: <TOKEN>'
-F "file=@file.mp4"
```

@ -1,6 +1,26 @@
### Preview Stream
The ffplayout engine output provides a setting for previewing. In general you can use any technique to display your streaming preview, even SDL could be possible.
The ffplayout engine has no special preview config parameters, but you can add your settings to the **output_param**, like:
```YAML
-s 512x288
-c:v libx264
-crf 24
-x264-params keyint=50:min-keyint=25:scenecut=-1
-maxrate 800k
-bufsize 1600k
-preset ultrafast
-tune zerolatency
-profile:v Main
-level 3.1
-c:a aac
-ar 44100
-b:a 128k
-flags +global_header
-f flv rtmp://preview.local/live/stream
...
```
In this documentation we suspect, that you are using [ffplayout-frontend](https://github.com/ffplayout/ffplayout-frontend) and that you using [SRS](https://github.com/ossrs/srs) at least for the preview stream. In the past we used HLS for the preview, but now it is possible to also use [HTTP-FLV](https://github.com/ossrs/srs/wiki/v4_EN_DeliveryHttpStream) for less latency.
@ -8,7 +28,6 @@ To get this working we have to follow some steps. ffplayout engine needs a direc
```
...
127.0.0.1 preview.local
```

@ -9,6 +9,7 @@ edition = "2021"
[dependencies]
ffplayout-lib = { path = "../lib" }
actix-files = "0.6"
actix-multipart = "0.4"
actix-web = "4"
actix-web-grants = "3"

@ -18,9 +18,11 @@ ffpapi -u <USERNAME> -p <PASSWORD> -m <MAIL ADDRESS>
Then run the API thru the systemd service, or like:
```BASH
ffpapi -l 127.0.0.1:8080
ffpapi -l 127.0.0.1:8787
```
If you plan to run ffpapi with systemd set permission from **/usr/share/ffplayout** and content to user **www-data:www-data**.
**For possible endpoints read: [api endpoints](/docs/api.md)**
ffpapi can also serve the browser based frontend, just run in your browser `127.0.0.1:8787`.

@ -1,5 +1,6 @@
use std::{path::Path, process::exit};
use actix_files::Files;
use actix_web::{dev::ServiceRequest, middleware, web, App, Error, HttpMessage, HttpServer};
use actix_web_grants::permissions::AttachPermissions;
use actix_web_httpauth::extractors::bearer::BearerAuth;
@ -37,6 +38,18 @@ async fn validator(req: ServiceRequest, credentials: BearerAuth) -> Result<Servi
Ok(req)
}
fn public_path() -> &'static str {
if Path::new("/usr/share/ffplayout/public/").is_dir() {
return "/usr/share/ffplayout/public/"
}
if Path::new("./public/").is_dir() {
return "./public/"
}
"./ffplayout-frontend/dist"
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let args = Args::parse();
@ -107,6 +120,7 @@ async fn main() -> std::io::Result<()> {
.service(remove)
.service(save_file),
)
.service(Files::new("/", public_path()).index_file("index.html"))
})
.bind((addr, port))?
.run()

@ -8,7 +8,7 @@ pub struct Args {
#[clap(short, long, help = "ask for user credentials")]
pub ask: bool,
#[clap(short, long, help = "Listen on IP:PORT, like: 127.0.0.1:8080")]
#[clap(short, long, help = "Listen on IP:PORT, like: 127.0.0.1:8787")]
pub listen: Option<String>,
#[clap(short, long, help = "Initialize Database")]

@ -3,7 +3,7 @@
/// Run the API thru the systemd service, or like:
///
/// ```BASH
/// ffpapi -l 127.0.0.1:8000
/// ffpapi -l 127.0.0.1:8787
/// ```
///
/// For all endpoints an (Bearer) authentication is required.\
@ -70,7 +70,7 @@ pub struct FileObj {
/// **Login**
///
/// ```BASH
/// curl -X POST http://127.0.0.1:8000/auth/login/ -H "Content-Type: application/json" \
/// curl -X POST http://127.0.0.1:8787/auth/login/ -H "Content-Type: application/json" \
/// -d '{ "username": "<USER>", "password": "<PASS>" }'
/// ```
/// **Response:**
@ -141,7 +141,7 @@ pub async fn login(credentials: web::Json<User>) -> impl Responder {
/// **Get current User**
///
/// ```BASH
/// curl -X GET 'http://localhost:8000/api/user' -H 'Content-Type: application/json' \
/// curl -X GET 'http://127.0.0.1:8787/api/user' -H 'Content-Type: application/json' \
/// -H 'Authorization: Bearer <TOKEN>'
/// ```
#[get("/user")]
@ -159,7 +159,7 @@ async fn get_user(user: web::ReqData<LoginUser>) -> Result<impl Responder, Servi
/// **Update current User**
///
/// ```BASH
/// curl -X PUT http://localhost:8000/api/user/1 -H 'Content-Type: application/json' \
/// curl -X PUT http://127.0.0.1:8787/api/user/1 -H 'Content-Type: application/json' \
/// -d '{"mail": "<MAIL>", "password": "<PASS>"}' -H 'Authorization: <TOKEN>'
/// ```
#[put("/user/{id}")]
@ -202,7 +202,7 @@ async fn update_user(
/// **Add User**
///
/// ```BASH
/// curl -X POST 'http://localhost:8000/api/user/' -H 'Content-Type: application/json' \
/// curl -X POST 'http://127.0.0.1:8787/api/user/' -H 'Content-Type: application/json' \
/// -d '{"mail": "<MAIL>", "username": "<USER>", "password": "<PASS>", "role_id": 1, "channel_id": 1}' \
/// -H 'Authorization: Bearer <TOKEN>'
/// ```
@ -223,7 +223,7 @@ async fn add_user(data: web::Json<User>) -> Result<impl Responder, ServiceError>
/// **Get Settings from Channel**
///
/// ```BASH
/// curl -X GET http://127.0.0.1:8000/api/channel/1 -H "Authorization: Bearer <TOKEN>"
/// curl -X GET http://127.0.0.1:8787/api/channel/1 -H "Authorization: Bearer <TOKEN>"
/// ```
///
/// **Response:**
@ -252,7 +252,7 @@ async fn get_channel(id: web::Path<i64>) -> Result<impl Responder, ServiceError>
/// **Get settings from all Channels**
///
/// ```BASH
/// curl -X GET http://127.0.0.1:8000/api/channels -H "Authorization: Bearer <TOKEN>"
/// curl -X GET http://127.0.0.1:8787/api/channels -H "Authorization: Bearer <TOKEN>"
/// ```
#[get("/channels")]
#[has_any_role("Role::Admin", type = "Role")]
@ -267,7 +267,7 @@ async fn get_all_channels() -> Result<impl Responder, ServiceError> {
/// **Update Channel**
///
/// ```BASH
/// curl -X PATCH http://127.0.0.1:8000/api/channel/1 -H "Content-Type: application/json" \
/// curl -X PATCH http://127.0.0.1:8787/api/channel/1 -H "Content-Type: application/json" \
/// -d '{ "id": 1, "name": "Channel 1", "preview_url": "http://localhost/live/stream.m3u8", \
/// "config_path": "/etc/ffplayout/ffplayout.yml", "extra_extensions": "jpg,jpeg,png", "timezone": "Europe/Berlin"}' \
/// -H "Authorization: Bearer <TOKEN>"
@ -288,7 +288,7 @@ async fn patch_channel(
/// **Create new Channel**
///
/// ```BASH
/// curl -X POST http://127.0.0.1:8000/api/channel/ -H "Content-Type: application/json" \
/// curl -X POST http://127.0.0.1:8787/api/channel/ -H "Content-Type: application/json" \
/// -d '{ "name": "Channel 2", "preview_url": "http://localhost/live/channel2.m3u8", \
/// "config_path": "/etc/ffplayout/channel2.yml", "extra_extensions": "jpg,jpeg,png",
/// "timezone": "Europe/Berlin", "service": "ffplayout@channel2.service" }' \
@ -306,7 +306,7 @@ async fn add_channel(data: web::Json<Channel>) -> Result<impl Responder, Service
/// **Delete Channel**
///
/// ```BASH
/// curl -X DELETE http://127.0.0.1:8000/api/channel/2 -H "Authorization: Bearer <TOKEN>"
/// curl -X DELETE http://127.0.0.1:8787/api/channel/2 -H "Authorization: Bearer <TOKEN>"
/// ```
#[delete("/channel/{id}")]
#[has_any_role("Role::Admin", type = "Role")]
@ -323,7 +323,7 @@ async fn remove_channel(id: web::Path<i64>) -> Result<impl Responder, ServiceErr
/// **Get Config**
///
/// ```BASH
/// curl -X GET http://localhost:8000/api/playout/config/1 -H 'Authorization: <TOKEN>'
/// curl -X GET http://127.0.0.1:8787/api/playout/config/1 -H 'Authorization: <TOKEN>'
/// ```
///
/// Response is a JSON object from the ffplayout.yml
@ -345,7 +345,7 @@ async fn get_playout_config(
/// **Update Config**
///
/// ```BASH
/// curl -X PUT http://localhost:8000/api/playout/config/1 -H "Content-Type: application/json" \
/// curl -X PUT http://127.0.0.1:8787/api/playout/config/1 -H "Content-Type: application/json" \
/// -d { <CONFIG DATA> } -H 'Authorization: <TOKEN>'
/// ```
#[put("/playout/config/{id}")]
@ -378,7 +378,7 @@ async fn update_playout_config(
/// **Get all Presets**
///
/// ```BASH
/// curl -X GET http://localhost:8000/api/presets/ -H 'Content-Type: application/json' \
/// curl -X GET http://127.0.0.1:8787/api/presets/ -H 'Content-Type: application/json' \
/// -H 'Authorization: <TOKEN>'
/// ```
#[get("/presets/{id}")]
@ -394,7 +394,7 @@ async fn get_presets(id: web::Path<i64>) -> Result<impl Responder, ServiceError>
/// **Update Preset**
///
/// ```BASH
/// curl -X PUT http://localhost:8000/api/presets/1 -H 'Content-Type: application/json' \
/// curl -X PUT http://127.0.0.1:8787/api/presets/1 -H 'Content-Type: application/json' \
/// -d '{ "name": "<PRESET NAME>", "text": "<TEXT>", "x": "<X>", "y": "<Y>", "fontsize": 24, \
/// "line_spacing": 4, "fontcolor": "#ffffff", "box": 1, "boxcolor": "#000000", "boxborderw": 4, "alpha": 1.0, "channel_id": 1 }' \
/// -H 'Authorization: <TOKEN>'
@ -415,7 +415,7 @@ async fn update_preset(
/// **Add new Preset**
///
/// ```BASH
/// curl -X POST http://localhost:8000/api/presets/ -H 'Content-Type: application/json' \
/// curl -X POST http://127.0.0.1:8787/api/presets/ -H 'Content-Type: application/json' \
/// -d '{ "name": "<PRESET NAME>", "text": "TEXT>", "x": "<X>", "y": "<Y>", "fontsize": 24, \
/// "line_spacing": 4, "fontcolor": "#ffffff", "box": 1, "boxcolor": "#000000", "boxborderw": 4, "alpha": 1.0, "channel_id": 1 }' \
/// -H 'Authorization: <TOKEN>'
@ -433,7 +433,7 @@ async fn add_preset(data: web::Json<TextPreset>) -> Result<impl Responder, Servi
/// **Delete Preset**
///
/// ```BASH
/// curl -X DELETE http://localhost:8000/api/presets/1 -H 'Content-Type: application/json' \
/// curl -X DELETE http://127.0.0.1:8787/api/presets/1 -H 'Content-Type: application/json' \
/// -H 'Authorization: <TOKEN>'
/// ```
#[delete("/presets/{id}")]
@ -457,7 +457,7 @@ async fn delete_preset(id: web::Path<i64>) -> Result<impl Responder, ServiceErro
/// **Send Text to ffplayout**
///
/// ```BASH
/// curl -X POST http://localhost:8000/api/control/1/text/ \
/// curl -X POST http://127.0.0.1:8787/api/control/1/text/ \
/// -H 'Content-Type: application/json' -H 'Authorization: <TOKEN>' \
/// -d '{"text": "Hello from ffplayout", "x": "(w-text_w)/2", "y": "(h-text_h)/2", \
/// "fontsize": "24", "line_spacing": "4", "fontcolor": "#ffffff", "box": "1", \
@ -482,7 +482,7 @@ pub async fn send_text_message(
/// - reset
///
/// ```BASH
/// curl -X POST http://localhost:8000/api/control/1/playout/next/ -H 'Content-Type: application/json'
/// curl -X POST http://127.0.0.1:8787/api/control/1/playout/next/ -H 'Content-Type: application/json'
/// -d '{ "command": "reset" }' -H 'Authorization: <TOKEN>'
/// ```
#[post("/control/{id}/playout/")]
@ -500,7 +500,7 @@ pub async fn control_playout(
/// **Get current Clip**
///
/// ```BASH
/// curl -X GET http://localhost:8000/api/control/1/media/current
/// curl -X GET http://127.0.0.1:8787/api/control/1/media/current
/// -H 'Content-Type: application/json' -H 'Authorization: <TOKEN>'
/// ```
///
@ -539,7 +539,7 @@ pub async fn media_current(id: web::Path<i64>) -> Result<impl Responder, Service
/// **Get next Clip**
///
/// ```BASH
/// curl -X GET http://localhost:8000/api/control/1/media/next/ -H 'Authorization: <TOKEN>'
/// curl -X GET http://127.0.0.1:8787/api/control/1/media/next/ -H 'Authorization: <TOKEN>'
/// ```
#[get("/control/{id}/media/next")]
#[has_any_role("Role::Admin", "Role::User", type = "Role")]
@ -553,7 +553,7 @@ pub async fn media_next(id: web::Path<i64>) -> Result<impl Responder, ServiceErr
/// **Get last Clip**
///
/// ```BASH
/// curl -X GET http://localhost:8000/api/control/1/media/last/
/// curl -X GET http://127.0.0.1:8787/api/control/1/media/last/
/// -H 'Content-Type: application/json' -H 'Authorization: <TOKEN>'
/// ```
#[get("/control/{id}/media/last")]
@ -574,7 +574,7 @@ pub async fn media_last(id: web::Path<i64>) -> Result<impl Responder, ServiceErr
/// - status
///
/// ```BASH
/// curl -X POST http://localhost:8000/api/control/1/process/
/// curl -X POST http://127.0.0.1:8787/api/control/1/process/
/// -H 'Content-Type: application/json' -H 'Authorization: <TOKEN>'
/// -d '{"command": "start"}'
/// ```
@ -592,7 +592,7 @@ pub async fn process_control(
/// **Get playlist**
///
/// ```BASH
/// curl -X GET http://localhost:8000/api/playlist/1?date=2022-06-20
/// curl -X GET http://127.0.0.1:8787/api/playlist/1?date=2022-06-20
/// -H 'Content-Type: application/json' -H 'Authorization: <TOKEN>'
/// ```
#[get("/playlist/{id}")]
@ -610,7 +610,7 @@ pub async fn get_playlist(
/// **Save playlist**
///
/// ```BASH
/// curl -X POST http://localhost:8000/api/playlist/1/
/// curl -X POST http://127.0.0.1:8787/api/playlist/1/
/// -H 'Content-Type: application/json' -H 'Authorization: <TOKEN>'
/// -- data "{<JSON playlist data>}"
/// ```
@ -631,7 +631,7 @@ pub async fn save_playlist(
/// A new playlist will be generated and response.
///
/// ```BASH
/// curl -X GET http://localhost:8000/api/playlist/1/generate/2022-06-20
/// curl -X GET http://127.0.0.1:8787/api/playlist/1/generate/2022-06-20
/// -H 'Content-Type: application/json' -H 'Authorization: <TOKEN>'
/// ```
#[get("/playlist/{id}/generate/{date}")]
@ -648,7 +648,7 @@ pub async fn gen_playlist(
/// **Delete Playlist**
///
/// ```BASH
/// curl -X DELETE http://localhost:8000/api/playlist/1/2022-06-20
/// curl -X DELETE http://127.0.0.1:8787/api/playlist/1/2022-06-20
/// -H 'Content-Type: application/json' -H 'Authorization: <TOKEN>'
/// ```
#[delete("/playlist/{id}/{date}")]
@ -667,7 +667,7 @@ pub async fn del_playlist(
/// **Read Log Life**
///
/// ```BASH
/// curl -X Get http://localhost:8000/api/log/1
/// curl -X Get http://127.0.0.1:8787/api/log/1
/// -H 'Content-Type: application/json' -H 'Authorization: <TOKEN>'
/// ```
#[get("/log/{id}")]
@ -684,7 +684,7 @@ pub async fn get_log(
/// **Get File/Folder List**
///
/// ```BASH
/// curl -X POST http://localhost:8000/api/file/1/browse/ -H 'Content-Type: application/json'
/// curl -X POST http://127.0.0.1:8787/api/file/1/browse/ -H 'Content-Type: application/json'
/// -d '{ "source": "/" }' -H 'Authorization: <TOKEN>'
/// ```
#[post("/file/{id}/browse/")]
@ -702,7 +702,7 @@ pub async fn file_browser(
/// **Create Folder**
///
/// ```BASH
/// curl -X POST http://localhost:8000/api/file/1/create-folder/ -H 'Content-Type: application/json'
/// curl -X POST http://127.0.0.1:8787/api/file/1/create-folder/ -H 'Content-Type: application/json'
/// -d '{"source": "<FOLDER PATH>"}' -H 'Authorization: <TOKEN>'
/// ```
#[post("/file/{id}/create-folder/")]
@ -717,7 +717,7 @@ pub async fn add_dir(
/// **Rename File**
///
/// ```BASH
/// curl -X POST http://localhost:8000/api/file/1/rename/ -H 'Content-Type: application/json'
/// curl -X POST http://127.0.0.1:8787/api/file/1/rename/ -H 'Content-Type: application/json'
/// -d '{"source": "<SOURCE>", "target": "<TARGET>"}' -H 'Authorization: <TOKEN>'
/// ```
#[post("/file/{id}/rename/")]
@ -735,7 +735,7 @@ pub async fn move_rename(
/// **Remove File/Folder**
///
/// ```BASH
/// curl -X POST http://localhost:8000/api/file/1/remove/ -H 'Content-Type: application/json'
/// curl -X POST http://127.0.0.1:8787/api/file/1/remove/ -H 'Content-Type: application/json'
/// -d '{"source": "<SOURCE>"}' -H 'Authorization: <TOKEN>'
/// ```
#[post("/file/{id}/remove/")]
@ -753,7 +753,7 @@ pub async fn remove(
/// **Upload File**
///
/// ```BASH
/// curl -X POST http://localhost:8000/api/file/1/upload/ -H 'Authorization: <TOKEN>'
/// curl -X POST http://127.0.0.1:8787/api/file/1/upload/ -H 'Authorization: <TOKEN>'
/// -F "file=@file.mp4"
/// ```
#[put("/file/{id}/upload/")]

@ -4,7 +4,7 @@ description = "24/7 playout based on rust and ffmpeg"
license = "GPL-3.0"
authors = ["Jonathan Baecker jonbae77@gmail.com"]
readme = "README.md"
version = "0.11.0"
version = "0.12.0"
edition = "2021"
[dependencies]
@ -55,6 +55,7 @@ assets = [
["../assets/logo.png", "/usr/share/ffplayout/", "644"],
["../assets/ffplayout.yml", "/usr/share/ffplayout/ffplayout.yml.orig", "644"],
["../README.md", "/usr/share/doc/ffplayout/README", "644"],
["../public/**/*", "/usr/share/ffplayout/public/", "644"],
]
maintainer-scripts = "../debian/"
systemd-units = { enable = false, unit-scripts = "../assets" }
@ -75,6 +76,7 @@ assets = [
["../assets/logo.png", "/usr/share/ffplayout/", "644"],
["../assets/ffplayout.yml", "/usr/share/ffplayout/ffplayout.yml.orig", "644"],
["../README.md", "/usr/share/doc/ffplayout/README", "644"],
["../public/**/*", "/usr/share/ffplayout/public/", "644"],
]
# REHL RPM PACKAGE
@ -93,7 +95,10 @@ assets = [
{ source = "../LICENSE", dest = "/usr/share/doc/ffplayout/LICENSE", mode = "644" },
{ source = "../assets/logo.png", dest = "/usr/share/ffplayout/logo.png", mode = "644" },
{ source = "../assets/ffplayout.yml", dest = "/usr/share/ffplayout/ffplayout.yml.orig", mode = "644" },
{ source = "../public/**/*", dest = "/usr/share/ffplayout/public/", mode = "644" },
{ source = "../debian/postinst", dest = "/usr/share/ffplayout/postinst", mode = "755" },
{ source = "../debian/postrm", dest = "/usr/share/ffplayout/postrm", mode = "755" },
]
auto-req = "no"
post_install_script = "/usr/share/ffplayout/postinst"
post_uninstall_script = "/usr/share/ffplayout/postrm"

@ -149,10 +149,6 @@ pub fn write_hls(
proc_control.is_terminated.clone(),
);
if config.out.preview {
warn!("Preview in HLS mode is not supported!");
}
// spawn a thread for ffmpeg ingest server and create a channel for package sending
if config.ingest.enable {
thread::spawn(move || ingest_to_hls_server(config_clone, play_stat, proc_control_c));

@ -12,7 +12,6 @@ use ffplayout_lib::vec_strings;
pub fn output(config: &PlayoutConfig, log_format: &str) -> process::Child {
let mut enc_cmd = vec![];
let mut enc_filter = vec![];
let mut preview_cmd = config.out.preview_cmd.as_ref().unwrap().clone();
let mut output_cmd = config.out.output_cmd.as_ref().unwrap().clone();
let enc_prefix = vec_strings![
@ -42,10 +41,6 @@ pub fn output(config: &PlayoutConfig, log_format: &str) -> process::Child {
}
}
if config.out.preview {
enc_cmd.append(&mut preview_cmd);
}
enc_cmd.append(&mut output_cmd);
let enc_cmd = prepare_output_cmd(enc_prefix, enc_filter, enc_cmd, &config.out.mode);

1
ffplayout-frontend Submodule

@ -0,0 +1 @@
Subproject commit c02141af54762961cf559248a3c9d42e9d317e0b

@ -4,7 +4,7 @@ description = "Library for ffplayout"
license = "GPL-3.0"
authors = ["Jonathan Baecker jonbae77@gmail.com"]
readme = "README.md"
version = "0.10.5"
version = "0.12.0"
edition = "2021"
[dependencies]

@ -154,12 +154,6 @@ pub struct Text {
pub struct Out {
pub help_text: String,
pub mode: String,
pub preview: bool,
pub preview_param: String,
#[serde(skip_serializing, skip_deserializing)]
pub preview_cmd: Option<Vec<String>>,
pub output_param: String,
#[serde(skip_serializing, skip_deserializing)]
@ -245,7 +239,6 @@ impl PlayoutConfig {
config.processing.settings = Some(settings);
config.ingest.input_cmd = split(config.ingest.input_param.as_str());
config.out.preview_cmd = split(config.out.preview_param.as_str());
config.out.output_cmd = split(config.out.output_param.as_str());
// when text overlay without text_from_filename is on, turn also the RPC server on,

@ -26,7 +26,7 @@ for target in "${targets[@]}"; do
cp ./target/${target}/release/ffpapi.exe .
cp ./target/${target}/release/ffplayout.exe .
zip -r "ffplayout-v${version}_${target}.zip" assets docs LICENSE README.md ffplayout.exe ffpapi.exe -x *.db
zip -r "ffplayout-v${version}_${target}.zip" assets docs public LICENSE README.md ffplayout.exe ffpapi.exe -x *.db
rm -f ffplayout.exe ffpapi.exe
elif [[ $target == "x86_64-apple-darwin" ]] || [[ $target == "aarch64-apple-darwin" ]]; then
if [[ -f "ffplayout-v${version}_${target}.tar.gz" ]]; then
@ -36,7 +36,7 @@ for target in "${targets[@]}"; do
cargo build --release --target=$target --bin ffplayout
cp ./target/${target}/release/ffplayout .
tar -czvf "ffplayout-v${version}_${target}.tar.gz" --exclude='*.db' assets docs LICENSE README.md ffplayout
tar -czvf "ffplayout-v${version}_${target}.tar.gz" --exclude='*.db' assets docs public LICENSE README.md ffplayout
rm -f ffplayout
else
if [[ -f "ffplayout-v${version}_${target}.tar.gz" ]]; then
@ -47,18 +47,26 @@ for target in "${targets[@]}"; do
cp ./target/${target}/release/ffpapi .
cp ./target/${target}/release/ffplayout .
tar -czvf "ffplayout-v${version}_${target}.tar.gz" --exclude='*.db' assets docs LICENSE README.md ffplayout ffpapi
tar -czvf "ffplayout-v${version}_${target}.tar.gz" --exclude='*.db' assets docs public LICENSE README.md ffplayout ffpapi
rm -f ffplayout ffpapi
fi
echo ""
done
cargo deb --target=x86_64-unknown-linux-musl -p ffplayout --manifest-path=ffplayout-engine/Cargo.toml -o ffplayout_${version}_amd64.deb
cd ffplayout-frontend
npm install
npm run build
yes | rm -rf ../public
mv dist ../public
cd ..
cargo deb --target=x86_64-unknown-linux-musl -p ffplayout --manifest-path=ffplayout-engine/Cargo.toml -o ffplayout_${version}_amd64.deb
cargo deb --target=aarch64-unknown-linux-gnu --variant=arm64 -p ffplayout --manifest-path=ffplayout-engine/Cargo.toml -o ffplayout_${version}_arm64.deb
# cargo deb --target=armv7-unknown-linux-gnueabihf --variant=armhf -p ffplayout --manifest-path=ffplayout-engine/Cargo.toml -o ffplayout_${version}_armhf.deb
cargo generate-rpm --target=x86_64-unknown-linux-musl -p ffplayout-engine -o ffplayout-${version}-1.x86_64.rpm
cd ffplayout-engine
cargo generate-rpm --target=x86_64-unknown-linux-musl -o ../ffplayout-${version}-1.x86_64.rpm
cd ..