mirror of
https://github.com/asciinema/asciinema.git
synced 2026-05-18 05:04:50 +02:00
feat(cli): add --audio-url, --description, --visibility flags for streaming
Add stream metadata options to the `stream` and `session` commands: - --audio-url: URL of a live audio stream for synchronized playback - --description: Markdown description of the streaming session - --visibility: Set stream visibility (public/unlisted/private) These flags expose existing server-side stream metadata fields through the CLI, enabling richer stream configuration without requiring the web interface.
This commit is contained in:
committed by
Marcin Kulik
parent
ac5274c35b
commit
da371e6ce6
15
src/api.rs
15
src/api.rs
@@ -24,6 +24,15 @@ pub struct StreamResponse {
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
/// Visibility level for streams and recordings
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum Visibility {
|
||||
Public,
|
||||
Unlisted,
|
||||
Private,
|
||||
}
|
||||
|
||||
#[derive(Default, Serialize)]
|
||||
pub struct StreamChangeset {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
@@ -38,6 +47,12 @@ pub struct StreamChangeset {
|
||||
pub shell: Option<Option<String>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub env: Option<Option<HashMap<String, String>>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub audio_url: Option<Option<String>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub description: Option<Option<String>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub visibility: Option<Visibility>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
|
||||
32
src/cli.rs
32
src/cli.rs
@@ -421,6 +421,26 @@ pub struct Stream {
|
||||
/// Specify a custom asciinema server URL for streaming to self-hosted servers. Use the base server URL (e.g., https://asciinema.example.com). Can also be set via the environment variable ASCIINEMA_SERVER_URL or the config file option server.url. If no server URL is configured via this option, environment variable, or config file, you will be prompted to choose one (defaulting to asciinema.org), which will be saved as a default.
|
||||
#[arg(long, value_name = "URL", help = "asciinema server URL", long_help)]
|
||||
pub server_url: Option<String>,
|
||||
|
||||
/// URL of a live audio stream (e.g., Icecast MP3/OGG) to synchronize with the terminal stream. When set, viewers can listen to audio commentary while watching the terminal. The audio URL is stored in the stream metadata and used by the player for synchronized playback. For example: --audio-url "https://icecast.example.com/live.mp3"
|
||||
#[arg(long, value_name = "URL", help = "Audio stream URL for synchronized playback", long_help)]
|
||||
pub audio_url: Option<String>,
|
||||
|
||||
/// Markdown description of the streaming session. This description is displayed on the stream page and can include formatting, links, and code blocks. Useful for providing context, instructions, or documentation for viewers.
|
||||
#[arg(long, help = "Description of the session (Markdown supported)", long_help)]
|
||||
pub description: Option<String>,
|
||||
|
||||
/// Set the visibility level for the stream. Public streams appear in listings and search results. Unlisted streams are accessible via direct URL but don't appear in listings. Private streams are only accessible to the owner.
|
||||
#[arg(long, value_enum, help = "Visibility level: public, unlisted, or private", long_help)]
|
||||
pub visibility: Option<StreamVisibility>,
|
||||
}
|
||||
|
||||
/// Visibility level for streams
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
|
||||
pub enum StreamVisibility {
|
||||
Public,
|
||||
Unlisted,
|
||||
Private,
|
||||
}
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
@@ -528,6 +548,18 @@ pub struct Session {
|
||||
#[arg(long, value_name = "URL", help = "asciinema server URL", long_help)]
|
||||
pub server_url: Option<String>,
|
||||
|
||||
/// URL of a live audio stream to synchronize with the terminal stream.
|
||||
#[arg(long, value_name = "URL", help = "Audio stream URL for synchronized playback")]
|
||||
pub audio_url: Option<String>,
|
||||
|
||||
/// Markdown description of the session.
|
||||
#[arg(long, help = "Description of the session (Markdown supported)")]
|
||||
pub description: Option<String>,
|
||||
|
||||
/// Visibility level for the stream.
|
||||
#[arg(long, value_enum, help = "Visibility level: public, unlisted, or private")]
|
||||
pub visibility: Option<StreamVisibility>,
|
||||
|
||||
#[arg(hide = true)]
|
||||
pub env: Vec<String>,
|
||||
}
|
||||
|
||||
@@ -14,9 +14,9 @@ use tracing::level_filters::LevelFilter;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
use url::Url;
|
||||
|
||||
use crate::api::{self, StreamChangeset, StreamResponse};
|
||||
use crate::api::{self, StreamChangeset, StreamResponse, Visibility};
|
||||
use crate::asciicast::{self, Version};
|
||||
use crate::cli::{self, Format, RelayTarget};
|
||||
use crate::cli::{self, Format, RelayTarget, StreamVisibility};
|
||||
use crate::config::{self, Config};
|
||||
use crate::encoder::{AsciicastV2Encoder, AsciicastV3Encoder, Encoder, RawEncoder, TextEncoder};
|
||||
use crate::file_writer::FileWriter;
|
||||
@@ -339,6 +339,13 @@ impl cli::Session {
|
||||
Some(Some(metadata.env.clone()))
|
||||
};
|
||||
|
||||
// Convert CLI visibility to API visibility
|
||||
let visibility = self.visibility.map(|v| match v {
|
||||
StreamVisibility::Public => Visibility::Public,
|
||||
StreamVisibility::Unlisted => Visibility::Unlisted,
|
||||
StreamVisibility::Private => Visibility::Private,
|
||||
});
|
||||
|
||||
let changeset = StreamChangeset {
|
||||
live: Some(true),
|
||||
title: metadata.title.clone().map(Some),
|
||||
@@ -346,6 +353,9 @@ impl cli::Session {
|
||||
term_version: Some(metadata.term.version.clone()),
|
||||
shell: Some(env::var("SHELL").ok()),
|
||||
env,
|
||||
audio_url: self.audio_url.clone().map(Some),
|
||||
description: self.description.clone().map(Some),
|
||||
visibility,
|
||||
};
|
||||
|
||||
if id.is_empty() {
|
||||
|
||||
@@ -58,6 +58,9 @@ fn main() -> ExitCode {
|
||||
return_: cmd.return_,
|
||||
log_file: cmd.log_file,
|
||||
server_url: None,
|
||||
audio_url: None,
|
||||
description: None,
|
||||
visibility: None,
|
||||
env: vec!["ASCIINEMA_REC=1".to_owned()],
|
||||
};
|
||||
|
||||
@@ -82,6 +85,9 @@ fn main() -> ExitCode {
|
||||
return_: cmd.return_,
|
||||
log_file: cmd.log_file,
|
||||
server_url: cmd.server_url,
|
||||
audio_url: cmd.audio_url,
|
||||
description: cmd.description,
|
||||
visibility: cmd.visibility,
|
||||
env: Vec::new(),
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user