add sse playout status, reduce current media object

This commit is contained in:
jb-alvarado 2024-04-29 09:31:35 +02:00
parent 1d8307015f
commit c4ea14dc94
6 changed files with 23 additions and 130 deletions

View File

@ -176,19 +176,17 @@ Output from `{"media":"current"}` show:
```JSON ```JSON
{ {
"current_media": { "media": {
"category": "", "category": "",
"duration": 154.2, "duration": 154.2,
"out": 154.2, "out": 154.2,
"seek": 0.0, "in": 0.0,
"source": "/opt/tv-media/clip.mp4" "source": "/opt/tv-media/clip.mp4"
}, },
"index": 39, "index": 39,
"play_mode": "playlist", "mode": "playlist",
"played_sec": 67.80771999300123, "ingest": false,
"remaining_sec": 86.39228000699876, "played": 67.80771999300123,
"start_sec": 24713.631999999998,
"start_time": "06:51:53.631"
} }
``` ```

View File

@ -1,35 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Server-sent events</title>
<style>
p {
margin-top: 0.5em;
margin-bottom: 0.5em;
}
</style>
</head>
<body>
<div id="root"></div>
<div id="ping"></div>
<script>
let root = document.getElementById('root')
const ping = document.getElementById('ping')
let events = new EventSource('/events')
events.onmessage = (event) => {
let data = document.createElement('p')
let time = new Date().toLocaleTimeString()
data.innerText = time + ': ' + event.data
if (event.data.includes('ping')) {
ping.innerHTML = time + ': ' + event.data
} else {
root.appendChild(data)
}
}
</script>
</body>
</html>

View File

@ -1,59 +0,0 @@
/// https://github.com/actix/examples/tree/master/server-sent-events
///
use std::{io, sync::Arc};
use actix_web::{get, middleware::Logger, post, web, App, HttpResponse, HttpServer, Responder};
use actix_web_lab::{extract::Path, respond::Html};
use simplelog::*;
use ffplayout_api::sse::broadcast::Broadcaster;
use ffplayout_lib::utils::{init_logging, PlayoutConfig};
#[actix_web::main]
async fn main() -> io::Result<()> {
let mut config = PlayoutConfig::new(None, None);
config.mail.recipient = String::new();
config.logging.log_to_file = false;
config.logging.timestamp = false;
let logging = init_logging(&config, None, None);
CombinedLogger::init(logging).unwrap();
let data = Broadcaster::create();
HttpServer::new(move || {
App::new()
.app_data(web::Data::from(Arc::clone(&data)))
.service(index)
.service(event_stream)
.service(broadcast_msg)
.wrap(Logger::default())
})
.bind(("127.0.0.1", 8080))?
.workers(2)
.run()
.await
}
#[get("/")]
async fn index() -> impl Responder {
Html(include_str!("index.html").to_owned())
}
#[get("/events")]
async fn event_stream(broadcaster: web::Data<Broadcaster>) -> impl Responder {
broadcaster
.new_client(1, PlayoutConfig::default(), "ping".to_string())
.await
}
#[post("/broadcast/{msg}")]
async fn broadcast_msg(
broadcaster: web::Data<Broadcaster>,
Path((msg,)): Path<(String,)>,
) -> impl Responder {
broadcaster.broadcast(&msg).await;
HttpResponse::Ok().body("msg sent")
}

View File

@ -694,25 +694,19 @@ pub async fn control_playout(
/// **Response:** /// **Response:**
/// ///
/// ```JSON /// ```JSON
/// { /// {
/// "jsonrpc": "2.0", /// "media": {
/// "result": {
/// "current_media": {
/// "category": "", /// "category": "",
/// "duration": 154.2, /// "duration": 154.2,
/// "out": 154.2, /// "out": 154.2,
/// "seek": 0.0, /// "in": 0.0,
/// "source": "/opt/tv-media/clip.mp4" /// "source": "/opt/tv-media/clip.mp4"
/// }, /// },
/// "index": 39, /// "index": 39,
/// "play_mode": "playlist", /// "ingest": false,
/// "played_sec": 67.80771999300123, /// "mode": "playlist",
/// "remaining_sec": 86.39228000699876, /// "played": 67.808
/// "start_sec": 24713.631999999998, /// }
/// "start_time": "06:51:53.631"
/// },
/// "id": 1
/// }
/// ``` /// ```
#[get("/control/{id}/media/current")] #[get("/control/{id}/media/current")]
#[protect(any("Role::Admin", "Role::User"), ty = "Role")] #[protect(any("Role::Admin", "Role::User"), ty = "Role")]

View File

@ -72,10 +72,7 @@ impl Broadcaster {
this.remove_stale_clients().await; this.remove_stale_clients().await;
} }
if counter % 5 == 0 { this.broadcast_playout().await;
this.broadcast_playout().await;
}
this.broadcast_system().await; this.broadcast_system().await;
counter = (counter + 1) % 61; counter = (counter + 1) % 61;

View File

@ -15,8 +15,8 @@ pub use arg_parse::Args;
use ffplayout_lib::{ use ffplayout_lib::{
filter::Filters, filter::Filters,
utils::{ utils::{
config::Template, errors::ProcError, parse_log_level_filter, sec_to_time, time_in_seconds, config::Template, errors::ProcError, parse_log_level_filter, time_in_seconds, time_to_sec,
time_to_sec, Media, OutputMode::*, PlayoutConfig, PlayoutStatus, ProcessMode::*, Media, OutputMode::*, PlayoutConfig, PlayoutStatus, ProcessMode::*,
}, },
vec_strings, vec_strings,
}; };
@ -252,7 +252,7 @@ pub fn prepare_output_cmd(
/// map media struct to json object /// map media struct to json object
pub fn get_media_map(media: Media) -> Value { pub fn get_media_map(media: Media) -> Value {
json!({ json!({
"seek": media.seek, "in": media.seek,
"out": media.out, "out": media.out,
"duration": media.duration, "duration": media.duration,
"category": media.category, "category": media.category,
@ -272,21 +272,19 @@ pub fn get_data_map(
let shift = *playout_stat.time_shift.lock().unwrap(); let shift = *playout_stat.time_shift.lock().unwrap();
let begin = media.begin.unwrap_or(0.0) - shift; let begin = media.begin.unwrap_or(0.0) - shift;
data_map.insert("play_mode".to_string(), json!(config.processing.mode)); data_map.insert("mode".to_string(), json!(config.processing.mode));
data_map.insert("ingest_runs".to_string(), json!(server_is_running)); data_map.insert("ingest".to_string(), json!(server_is_running));
data_map.insert("index".to_string(), json!(media.index)); data_map.insert("index".to_string(), json!(media.index));
data_map.insert("start_sec".to_string(), json!(begin));
if begin > 0.0 { if begin > 0.0 {
let played_time = current_time - begin; let played_time = current_time - begin;
let remaining_time = media.out - played_time; data_map.insert(
"played".to_string(),
data_map.insert("start_time".to_string(), json!(sec_to_time(begin))); json!((played_time * 1000.0).round() / 1000.0),
data_map.insert("played_sec".to_string(), json!(played_time)); );
data_map.insert("remaining_sec".to_string(), json!(remaining_time));
} }
data_map.insert("current_media".to_string(), get_media_map(media)); data_map.insert("media".to_string(), get_media_map(media));
data_map data_map
} }