commit
4111a6f20a
4
.gitignore
vendored
4
.gitignore
vendored
@ -19,5 +19,7 @@
|
||||
*.deb
|
||||
*.rpm
|
||||
/assets/*.db*
|
||||
|
||||
/dist/
|
||||
/public/
|
||||
tmp/
|
||||
.vscode/
|
||||
|
3
.gitmodules
vendored
Normal file
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
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",
|
||||
|
32
README.md
32
README.md
@ -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,21 +46,25 @@ 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)
|
||||
- if you want to overlay text, ffmpeg needs to have **libzmq**
|
||||
|
||||
### Install
|
||||
|
||||
Check [install](docs/install.md) for details about how to install ffplayout.
|
||||
|
||||
-----
|
||||
|
||||
JSON Playlist Example
|
||||
-----
|
||||
### JSON Playlist Example
|
||||
|
||||
```json
|
||||
{
|
||||
@ -95,15 +97,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 +125,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
|
||||
|
75
assets/ffplayout.conf
Normal file
75
assets/ffplayout.conf
Normal file
@ -0,0 +1,75 @@
|
||||
server {
|
||||
listen 80;
|
||||
|
||||
server_name ffplayout.local;
|
||||
|
||||
gzip on;
|
||||
gzip_types text/plain application/xml text/css application/javascript;
|
||||
gzip_min_length 1000;
|
||||
|
||||
charset utf-8;
|
||||
|
||||
client_max_body_size 7000M; # should be desirable value
|
||||
|
||||
add_header X-Frame-Options SAMEORIGIN;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
|
||||
|
||||
location / {
|
||||
if ($http_origin ~ '^https?://(localhost|ffplayout\.local)') {
|
||||
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
|
||||
add_header 'Access-Control-Allow-Credentials' 'true' always;
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
|
||||
add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With' always;
|
||||
}
|
||||
|
||||
if ($request_method = OPTIONS ) {
|
||||
add_header 'Access-Control-Max-Age' 1728000;
|
||||
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
||||
add_header 'Content-Length' 0;
|
||||
return 204;
|
||||
}
|
||||
|
||||
root /var/www/ffplayout-frontend/;
|
||||
}
|
||||
|
||||
location ~ ^/(api|auth) {
|
||||
if ($http_origin ~ '^https?://(localhost|ffplayout\.local)') {
|
||||
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
|
||||
add_header 'Access-Control-Allow-Credentials' 'true' always;
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
|
||||
add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With' always;
|
||||
}
|
||||
|
||||
add_header Last-Modified $date_gmt;
|
||||
add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
|
||||
if_modified_since off;
|
||||
expires off;
|
||||
etag off;
|
||||
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_read_timeout 36000s;
|
||||
proxy_connect_timeout 36000s;
|
||||
proxy_send_timeout 36000s;
|
||||
proxy_buffer_size 128k;
|
||||
proxy_buffers 4 256k;
|
||||
proxy_busy_buffers_size 256k;
|
||||
send_timeout 36000s;
|
||||
proxy_no_cache 1;
|
||||
proxy_pass http://127.0.0.1:8000;
|
||||
|
||||
}
|
||||
|
||||
location /live/ {
|
||||
alias /var/www/srs/live/;
|
||||
}
|
||||
|
||||
location /preview/stream.flv {
|
||||
# HTTP-FLV preview
|
||||
proxy_pass http://preview.local:8080/live/stream.flv;
|
||||
}
|
||||
}
|
@ -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
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
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
|
64
docs/api.md
64
docs/api.md
@ -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"
|
||||
```
|
||||
|
24
docs/install.md
Normal file
24
docs/install.md
Normal file
@ -0,0 +1,24 @@
|
||||
### Install ffplayout
|
||||
|
||||
ffplayout provides ***.deb** amd ***.rpm** packages, which makes it more easy to install and use, but there is still some steps to do.
|
||||
|
||||
1. download the latest ffplayout from [release](https://github.com/ffplayout/ffplayout/releases/latest) page.
|
||||
2. install it with `apt install /tmp/ffplayout_<VERSION>_amd64.deb`
|
||||
3. install ffmpeg/ffprobe, or compile and copy it to **/usr/local/bin/**
|
||||
4. activate systemd services:
|
||||
- `systemctl enable ffplayout`
|
||||
- `systemctl enable --now ffpapi`
|
||||
5. initialize sqlite database for ffpapi:
|
||||
- `ffpapi -i`
|
||||
6. add admin user to ffpapi:
|
||||
- `ffpapi -a`
|
||||
7. use a revers proxy for SSL, Port is **8787**.
|
||||
8. login with your browser, address without proxy would be: **http://[IP ADDRESS]:8787**
|
||||
|
||||
Default location for playlists and media files are: **/var/lib/ffplayout/**. If you need to change them, the media storage folder needs a symlink to **/usr/share/ffplayout/public/**.
|
||||
|
||||
When you don't need the frontend and API, skip enable the systemd service **ffpapi**.
|
||||
|
||||
When playlists are created and the ffplayout output is configured, you can start the process: `systemctl start ffplayout`, or click start in frontend.
|
||||
|
||||
If you want to configure ffplayout over terminal, you can edit **/etc/ffplayout/ffplayout.yml**.
|
@ -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]
|
||||
@ -54,7 +54,9 @@ assets = [
|
||||
["../assets/ffplayout.yml", "/etc/ffplayout/", "644"],
|
||||
["../assets/logo.png", "/usr/share/ffplayout/", "644"],
|
||||
["../assets/ffplayout.yml", "/usr/share/ffplayout/ffplayout.yml.orig", "644"],
|
||||
["../assets/ffplayout.conf", "/usr/share/ffplayout/ffplayout.conf.example", "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" }
|
||||
@ -74,7 +76,9 @@ assets = [
|
||||
["../assets/ffplayout.yml", "/etc/ffplayout/", "644"],
|
||||
["../assets/logo.png", "/usr/share/ffplayout/", "644"],
|
||||
["../assets/ffplayout.yml", "/usr/share/ffplayout/ffplayout.yml.orig", "644"],
|
||||
["../assets/ffplayout.conf", "/usr/share/ffplayout/ffplayout.conf.example", "644"],
|
||||
["../README.md", "/usr/share/doc/ffplayout/README", "644"],
|
||||
["../public/**/*", "/usr/share/ffplayout/public/", "644"],
|
||||
]
|
||||
|
||||
# REHL RPM PACKAGE
|
||||
@ -93,7 +97,11 @@ 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 = "../assets/ffplayout.conf", dest = "/usr/share/ffplayout/ffplayout.conf.example", 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"
|
||||
|
@ -109,8 +109,6 @@ fn ingest_to_hls_server(
|
||||
log_line(line, &level);
|
||||
}
|
||||
|
||||
info!("Switch from live ingest to {}", config.processing.mode);
|
||||
|
||||
proc_control
|
||||
.server_is_running
|
||||
.store(false, Ordering::SeqCst);
|
||||
@ -122,6 +120,8 @@ fn ingest_to_hls_server(
|
||||
if proc_control.is_terminated.load(Ordering::SeqCst) {
|
||||
break;
|
||||
}
|
||||
|
||||
info!("Switch from live ingest to {}", config.processing.mode);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -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
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]
|
||||
|
@ -275,18 +275,18 @@ fn realtime_filter(
|
||||
config: &PlayoutConfig,
|
||||
codec_type: &str,
|
||||
) {
|
||||
let mut t = "";
|
||||
|
||||
if codec_type == "audio" {
|
||||
t = "a"
|
||||
}
|
||||
|
||||
if config.general.generate.is_none() && &config.out.mode.to_lowercase() == "hls" {
|
||||
let mut t = "";
|
||||
|
||||
if codec_type == "audio" {
|
||||
t = "a"
|
||||
}
|
||||
|
||||
let mut speed_filter = format!("{t}realtime=speed=1");
|
||||
let (delta, _) = get_delta(config, &node.begin.unwrap());
|
||||
let duration = node.out - node.seek;
|
||||
|
||||
if delta < 0.0 {
|
||||
if delta < 0.0 && node.seek == 0.0 {
|
||||
let duration = node.out - node.seek;
|
||||
let speed = duration / (duration + delta);
|
||||
|
||||
if speed > 0.0 && speed < 1.1 && delta < config.general.stop_threshold {
|
||||
|
@ -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 ..
|
||||
|
Loading…
x
Reference in New Issue
Block a user