Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions lang/template.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@
"(chosen files are used instead of the folder)": "",
"(deleted rule)": "",
"(not connected)": "",
"0: recordings are never deleted": "",
"1 hour": "",
"12+ characters": "",
"12-band": "",
"16 bands at most": "",
"A DovaFM Digital Entertainment Group brand. Free and open source under the MIT licence.": "",
"A copy of this event to change": "",
"A copy of this template to change": "",
"A different pattern for part of the day. The first one that covers the time is used; outside them the pattern above is.": "",
"A folder on this computer, a network folder (\\\\server\\share) or a cloud folder that syncs (OneDrive, Dropbox, Google Drive). Each day gets its own folder. If the folder can't be written, that hour goes into the data folder's recordings folder instead.": "",
"A newer RadioMaster is on GitHub — click to see what's new and install it": "",
"A plugin controls RadioMaster by printing lines such as RM: VOLUME 60 or RM: PLAYLIST Evening.": "",
"A stopped server is off air until someone starts it again on that computer.": "",
Expand All @@ -22,6 +25,7 @@
"API key": "",
"API password": "",
"AUX Playlist": "",
"About": "",
"About RadioMaster": "",
"About this song": "",
"Account is active": "",
Expand Down Expand Up @@ -114,6 +118,7 @@
"Bell": "",
"Bell lifts or cuts around a frequency; shelves move everything above or below it; cuts remove it.": "",
"Between lines": "",
"Bitrate": "",
"Bitrate (kbps)": "",
"Blue": "",
"Broadcast / encoders": "",
Expand Down Expand Up @@ -217,6 +222,7 @@
"Duplicate": "",
"Duration": "",
"ELAPSED": "",
"Each file": "",
"Each keeps its own licence (MIT, Apache-2.0, MPL-2.0 or LGPL for LAME).": "",
"Each runs a playlist command, e.g. PLAYLIST Evening, VOLUME 60, GENERATE Drive time, RULE Top of hour jingle or STOP.": "",
"Each track is analysed: silence is skipped, cold endings get almost no overlap, and songs that fade out let the next one start as the outro dies away. Cues you set in the track editor always win.": "",
Expand Down Expand Up @@ -244,11 +250,13 @@
"Every play (CSV / Excel)…": "",
"Every track overlaps the next by this much. Tracks with cues set in the track editor still use their own.": "",
"Everything": "",
"Everything that goes on air is saved, one file per hour (or the length chosen below), as proof of broadcast. It records in the background while RadioMaster runs.": "",
"Exit": "",
"Export as CSV…": "",
"Export now-playing metadata": "",
"Export translation template": "",
"Extra": "",
"FLAC (lossless, about half the size of WAV; needs ffmpeg)": "",
"FLAC in Ogg, lossless (ffmpeg)": "",
"Fade": "",
"Fade on cold endings": "",
Expand All @@ -269,6 +277,7 @@
"Fixed crossfade": "",
"Fixed keys": "",
"Flat": "",
"Folder": "",
"Folder in the profile": "",
"Folder on the server": "",
"Folder…": "",
Expand Down Expand Up @@ -395,6 +404,7 @@
"MIDI isn't available:": "",
"MIDI only": "",
"MP3 (built in)": "",
"MP3 (compressed, 64–320 kbps)": "",
"Make a jingle rule in the Advertisement scheduler first, or add a Jingles category": "",
"Make a tunnel in the Cloudflare dashboard (Zero Trust → Networks → Tunnels) for your own domain, and point it at http://localhost and the portal port. Without a token you get a random trycloudflare.com address.": "",
"Make everything larger or smaller if the text is hard to read.": "",
Expand Down Expand Up @@ -455,6 +465,7 @@
"Not encrypted (http). Turn on HTTPS in Server settings for a server on the internet.": "",
"Not found anywhere": "",
"Not playing": "",
"Not recording": "",
"Notch": "",
"Notepad": "",
"Nothing here.": "",
Expand Down Expand Up @@ -567,6 +578,7 @@
"Read the play history again": "",
"Recent": "",
"Reconnecting…": "",
"Record the station's output": "",
"Recordings": "",
"Recordings are saved as WAV in the voicetracks folder of your RadioMaster data folder.": "",
"Recordings folder": "",
Expand Down Expand Up @@ -671,6 +683,9 @@
"Show every file in the folder, not only audio": "",
"Show every file, not only audio": "",
"Show every track in the library or playlist next to the editor": "",
"Show recorder": "",
"Show recording": "",
"Show recording: click to see it": "",
"Shown on the pad": "",
"Shuffle upcoming": "",
"Sign in": "",
Expand Down Expand Up @@ -705,6 +720,8 @@
"Start encoder #": "",
"Start playing when the server starts": "",
"Start time": "",
"Starting: waiting for sound from the mixer": "",
"Starting…": "",
"Starts in": "",
"Station": "",
"Station audio": "",
Expand Down Expand Up @@ -820,6 +837,8 @@
"Voice": "",
"Vol ": "",
"Volume": "",
"WAV (uncompressed, about 600 MB an hour)": "",
"Waiting: outside the days and hours set": "",
"Want to be listed? Contribute code, a translation or testing — see CONTRIBUTORS.md on GitHub.": "",
"Warn the presenter": "",
"Web": "",
Expand Down Expand Up @@ -857,6 +876,7 @@
"Yes": "",
"You can't disable your own account": "",
"You can't take away your own administrator access": "",
"You're connected to a RadioMaster Server: the server records, into a folder on the server.": "",
"Your account can't change playlists": "",
"Your account isn't allowed to do this": "",
"Your account isn't allowed to edit playlists": "",
Expand All @@ -866,6 +886,7 @@
"Your adverts, each with the dates and days it may run. Rules can play from this list.": "",
"Zoom": "",
"Zoom on the hand-over to the next track": "",
"a day": "",
"a folder or chosen files": "",
"administrator": "",
"advert": "",
Expand All @@ -878,6 +899,7 @@
"all day": "",
"all files in order": "",
"all of them": "",
"an hour": "",
"analysing next track…": "",
"analysing…": "",
"any": "",
Expand All @@ -888,6 +910,7 @@
"can't analyse the next track": "",
"command, e.g. PLAYLIST Evening": "",
"cut tail after": "",
"days": "",
"delete for good": "",
"e.g. station id, news": "",
"egui · rodio · symphonia · LAME": "",
Expand All @@ -898,13 +921,15 @@
"files": "",
"files checked": "",
"files deleted": "",
"files finished since it started": "",
"files for good? Playlist rows that use them will play the kept copy.": "",
"files moved to the Removed tracks folder": "",
"files retagged": "",
"files to the Removed tracks folder? Playlist rows that use them will play the kept copy.": "",
"filter": "",
"folder": "",
"folder or .m3u": "",
"for all the days kept": "",
"from": "",
"genre": "",
"get ffmpeg": "",
Expand Down Expand Up @@ -950,6 +975,7 @@
"now (the track on air moves on)": "",
"of each track (0 = off)": "",
"off": "",
"older recordings are deleted (only RadioMaster's own files)": "",
"on air": "",
"on the clock": "",
"on the server": "",
Expand All @@ -968,6 +994,7 @@
"port": "",
"preset name": "",
"random": "",
"recorded": "",
"rows": "",
"saved (type to replace)": "",
"search requestable songs": "",
Expand Down Expand Up @@ -1023,6 +1050,10 @@
"⏭ Skip song": "",
"⏹ Disconnect": "",
"⏹ Stop (F12)": "",
"⏺ REC": "",
"⏺ REC: problem": "",
"⏺ REC: starting": "",
"⏺ REC: waiting": "",
"■ Stop": "",
"■ Stop all jingles": "",
"■ Stop jingles": "",
Expand All @@ -1045,6 +1076,7 @@
"● Offline": "",
"● On air": "",
"● Record": "",
"● Recording": "",
"● in force now": "",
"● offline": "",
"● online": "",
Expand Down Expand Up @@ -1112,6 +1144,7 @@
"👯 Duplicates": "",
"💾 Save as M3U…": "",
"📁 Create folder": "",
"📁 Open the recordings folder": "",
"📂 Also look in…": "",
"📂 Load M3U into this tab…": "",
"📂 Open plugins folder": "",
Expand Down
39 changes: 37 additions & 2 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,21 @@ enum SettingsPage {
Playback,
Devices,
Streaming,
Recording,
Audio,
Automation,
Remote,
Appearance,
Accounts,
}
impl SettingsPage {
const ALL: [SettingsPage; 10] = [
const ALL: [SettingsPage; 11] = [
Self::General,
Self::Library,
Self::Playback,
Self::Devices,
Self::Streaming,
Self::Recording,
Self::Audio,
Self::Automation,
Self::Remote,
Expand All @@ -60,6 +62,7 @@ impl SettingsPage {
Self::Playback => "Playback",
Self::Devices => "Audio devices",
Self::Streaming => "Broadcast / encoders",
Self::Recording => "Show recording",
Self::Audio => "Audio processing",
Self::Automation => "Automation / metadata",
Self::Remote => "Remote API",
Expand All @@ -86,6 +89,8 @@ enum Dlg {
CatFolder(usize, PathBuf),
SaveReport(PathBuf),
AnnounceFolder(PathBuf),
/// folder for show recordings
RecFolder(PathBuf),
ContainerFiles(Vec<PathBuf>),
FfmpegPath(PathBuf),
/// (outro?, file) for a speech row
Expand Down Expand Up @@ -203,6 +208,8 @@ mod panes;
mod pltools;
#[path = "plview.rs"]
mod plview;
#[path = "recui.rs"]
mod recui;
#[path = "reportui.rs"]
mod reportui;
#[path = "serveradmin.rs"]
Expand Down Expand Up @@ -897,6 +904,7 @@ impl App {
self.ins_from_pl = Some((p, rows, vec![true; n]));
}
Dlg::AnnounceFolder(p) => core.cfg.announce.folder = p.to_string_lossy().to_string(),
Dlg::RecFolder(p) => core.cfg.recording.folder = p.to_string_lossy().to_string(),
Dlg::ContainerFiles(v) => {
if let Some(d) = self.item_dlg.as_mut() {
d.items.extend(v);
Expand Down Expand Up @@ -1196,6 +1204,7 @@ impl App {
ToolWin::Scheduler,
ToolWin::AudioFx,
ToolWin::Streams,
ToolWin::Recorder,
ToolWin::AzuraCast,
ToolWin::Reports,
ToolWin::History,
Expand Down Expand Up @@ -1483,7 +1492,10 @@ impl App {
}

// ----------------------------------------------------------- status bar
fn status_bar(&self, ctx: &egui::Context, core: &Playout) {
/// The message line, clock, streams and recorder at the bottom. Needs `&mut self` because
/// clicking ⏺ REC opens the Show recorder window (its only caller is `update`).
fn status_bar(&mut self, ctx: &egui::Context, core: &Playout) {
Comment thread
epell-development marked this conversation as resolved.
Resolved
let mut open_recorder = false;
egui::TopBottomPanel::bottom("status").show(ctx, |ui| {
ui.horizontal(|ui| {
ui.label(core.notify.lock().clone());
Expand All @@ -1492,13 +1504,34 @@ impl App {
ui.separator();
let live = core.handles.iter().flatten().filter(|h| h.status.lock().state == EncState::Live).count();
ui.label(RichText::new(format!("● {live} stream(s) live")).color(if live > 0 { GREEN } else { GRAY }));
if let Some(rec) = core.recording() {
ui.separator();
let (text, color) = match rec.state.as_str() {
"recording" => (tr("⏺ REC"), RED),
"error" => (tr("⏺ REC: problem"), AMBER),
"starting" => (tr("⏺ REC: starting"), GRAY),
_ => (tr("⏺ REC: waiting"), GRAY),
};
let hover =
if rec.error.is_empty() { tr("Show recording: click to see it").to_string() } else { rec.error.clone() };
if ui
.add(egui::Label::new(RichText::new(text).color(color)).sense(egui::Sense::click()))
.on_hover_text(hover)
.clicked()
{
open_recorder = true;
}
}
if let Some(np) = &core.azura.lock().np {
ui.separator();
ui.label(format!("👥 {} listeners ({} unique)", np.listeners.current, np.listeners.unique));
}
});
});
});
if open_recorder {
self.open_tool(ToolWin::Recorder);
}
}

// --------------------------------------------------------------- player
Expand Down Expand Up @@ -2115,6 +2148,7 @@ impl App {
self.smart_fade_settings(ui, core);
},
SettingsPage::Streaming=>self.tab_streaming(ui,core),
SettingsPage::Recording=>self.tab_recording(ui,core),
SettingsPage::Audio=>self.tab_dsp(ui,core),
SettingsPage::Devices=>self.tab_devices(ui,core),
SettingsPage::Automation=>self.tab_settings(ui,core),
Expand Down Expand Up @@ -4062,6 +4096,7 @@ impl eframe::App for App {
for i in 0..c.cfg.encoders.len() {
c.stop_encoder(i);
}
c.finish_recording();
c.save_all();
c.plugins.stop_services();
drop(c);
Expand Down
Loading
Loading