page.rs

crates/veilvoice-video/src/page.rs

veilvoice-video · 1610 lines · read the source here · or on GitHub

The picture: one still for a preview, and one page that plays.

Why a page rather than a video file

It needs nothing installed, it contacts nothing, and it opens on every browser and every phone. A video file needs an encoder this project does not ship, as crate::ffmpeg explains, so the page is the thing that always exists and the file is the extra.

It is also the honest artefact for this particular job. What is being drawn is a waveform, some circles and a title: flat colour, hard edges and text. That is what vector graphics are for, and it stays sharp at any size on any screen rather than being resampled from a fixed grid of pixels.

The layout, and why the padding is a setting

A title across the top, a row of circles under it, one per speaker, in their colour and with their name beneath, and the waveform along the bottom with a line that moves through it. Look::padding is a setting because the same picture is wanted at very different sizes: a thumbnail wants little and a full-screen render wants a lot, and a fixed margin looks wrong at one end or the other.

Everything user-supplied is escaped

Names and titles are typed by a person and end up inside markup. They are escaped on the way in, every time, through one function. A name containing </text> would otherwise end the element it is in and the rest of the file would be whatever that person wrote, which is a nuisance in a local file and a real problem in one that gets sent to somebody.

The script, and what happens without it

Lighting the circle of whoever is speaking means knowing where the audio has got to, and only the audio element knows that. There is a small inline script, with no file, no library and no network, and a <noscript> saying what it does. Without it the audio plays, the subtitles appear, the waveform is drawn and the circles simply stay dim.

In plain words

Draws the picture: a waveform, a circle for each person that lights up when it is their turn, and the names.

It produces two things. A still, so you can see what you will get before anything is rendered, and a self-contained web page that plays the veiled audio with the picture moving along beside it.

A page rather than a video file, because a page needs nothing installed to watch and can be opened by anybody. If you want an actual video file, the command to make one is printed for you.

WHAT THIS FILE CONTAINS

1610 lines defining 19 functions (9 public), 4 types and 0 constants. Everything below is read out of the source, so it cannot disagree with the code.

The types it owns.

  • struct Look line 62 · What the picture looks like.
  • enum Background line 94 · What sits behind the picture.
  • struct Layout line 175 · Where each part of the picture goes.
  • struct Drawn line 749 · What a render produced, and anything the user should know about it.

What happens when it runs. These are the ways in: public, and nothing else in this file calls them, so they are what an outside caller reaches first.

  • Look::black line 103 · Black, for somebody who wants the plainest possible picture.
  • Look::themed line 116 · The same look in another palette.
  • Look::checked line 137 · Whether these numbers describe a picture that can be drawn.
  • inline_vtt line 326 · A WebVTT track as a data: URI, so a page opened from disk still has it.
    reaches base64
  • player line 878 · The self-contained page that plays.
    reaches escape, player_body, player_head, player_script, still, layout, names_array, background_markup, speaker_markup, js_string, data_uri, base64

WHAT CALLS WHAT

Look::default line 81 Look::black line 103 Look::themed line 116 Look::checked line 137 layout line 193 escape line 229 base64 line 249 media_type line 276 data_uri line 297 inline_vtt line 326 background_markup line 331 player_head line 384 player_body line 436 player_script line 506 names_array line 607 js_string line 617 speaker_markup line 641 still line 763 player line 878 entry: a way in: public, and nothing in this file calls it api: public, and also used inside this file helper: private to this file dashed: a call that goes back up, or across a wrapped rank The functions this file defines, and the calls between them. An edge means the callee's name appears, called, inside the caller's body. This is a syntactic reading, not a type-resolved one.

The functions this file defines, and the calls between them. An edge means the callee's name appears, called, inside the caller's body. This is a syntactic reading, not a type-resolved one.

The same graph as Mermaid source
%%{init: {"theme":"base","themeVariables":{"background":"#1a1b26","primaryColor":"#1f2335","primaryTextColor":"#c0caf5","primaryBorderColor":"#7aa2f7","secondaryColor":"#16161e","tertiaryColor":"#16161e","lineColor":"#737aa2","textColor":"#c0caf5","mainBkg":"#1f2335","nodeBorder":"#7aa2f7","clusterBkg":"#16161e","clusterBorder":"#2f3549","fontFamily":"ui-monospace, SFMono-Regular, Consolas, monospace","fontSize":"14px"}}}%%
flowchart TD
    n_default["Look::default<br/>line 81"]
    n_black(["Look::black<br/>line 103"])
    n_themed(["Look::themed<br/>line 116"])
    n_checked(["Look::checked<br/>line 137"])
    n_layout["layout<br/>line 193"]
    n_escape["escape<br/>line 229"]
    n_base64["base64<br/>line 249"]
    n_media_type["media_type<br/>line 276"]
    n_data_uri["data_uri<br/>line 297"]
    n_inline_vtt(["inline_vtt<br/>line 326"])
    n_background_markup["background_markup<br/>line 331"]
    n_player_head["player_head<br/>line 384"]
    n_player_body["player_body<br/>line 436"]
    n_player_script["player_script<br/>line 506"]
    n_names_array["names_array<br/>line 607"]
    n_js_string["js_string<br/>line 617"]
    n_speaker_markup["speaker_markup<br/>line 641"]
    n_still["still<br/>line 763"]
    n_player(["player<br/>line 878"])
    n_background_markup --> n_data_uri
    n_background_markup --> n_escape
    n_data_uri --> n_base64
    n_data_uri --> n_media_type
    n_inline_vtt --> n_base64
    n_names_array --> n_js_string
    n_player --> n_escape
    n_player --> n_player_body
    n_player --> n_player_head
    n_player --> n_player_script
    n_player --> n_still
    n_player_body --> n_escape
    n_player_script --> n_layout
    n_player_script --> n_names_array
    n_speaker_markup --> n_data_uri
    n_speaker_markup --> n_escape
    n_still --> n_background_markup
    n_still --> n_escape
    n_still --> n_layout
    n_still --> n_speaker_markup
    click n_default href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/page.rs#L81" "open the source"
    click n_black href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/page.rs#L103" "open the source"
    click n_themed href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/page.rs#L116" "open the source"
    click n_checked href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/page.rs#L137" "open the source"
    click n_layout href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/page.rs#L193" "open the source"
    click n_escape href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/page.rs#L229" "open the source"
    click n_base64 href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/page.rs#L249" "open the source"
    click n_media_type href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/page.rs#L276" "open the source"
    click n_data_uri href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/page.rs#L297" "open the source"
    click n_inline_vtt href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/page.rs#L326" "open the source"
    click n_background_markup href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/page.rs#L331" "open the source"
    click n_player_head href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/page.rs#L384" "open the source"
    click n_player_body href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/page.rs#L436" "open the source"
    click n_player_script href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/page.rs#L506" "open the source"
    click n_names_array href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/page.rs#L607" "open the source"
    click n_js_string href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/page.rs#L617" "open the source"
    click n_speaker_markup href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/page.rs#L641" "open the source"
    click n_still href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/page.rs#L763" "open the source"
    click n_player href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/page.rs#L878" "open the source"
    classDef entry fill:#1f2335,stroke:#7aa2f7,color:#c0caf5
    class n_black,n_themed,n_checked,n_inline_vtt,n_player entry
    classDef api fill:#1f2335,stroke:#7dcfff,color:#c0caf5
    class n_layout,n_escape,n_data_uri,n_still api
    classDef helper fill:#1f2335,stroke:#bb9af7,color:#c0caf5
    class n_default,n_base64,n_media_type,n_background_markup,n_player_head,n_player_body,n_player_script,n_names_array,n_js_string,n_speaker_markup helper

This site loads no third-party script, so it cannot run Mermaid; the diagram above is the same nodes and edges drawn by the generator instead. GitHub renders the source below directly.

ITEMS

ItemLineDocumentation
Look pub struct62What the picture looks like.
Look::default fn81
Background pub enum94What sits behind the picture.
Look::black pub fn103Black, for somebody who wants the plainest possible picture.
Look::themed pub fn116The same look in another palette.
Look::checked pub fn137Whether these numbers describe a picture that can be drawn.
Layout pub struct175Where each part of the picture goes.
layout pub fn193Work out the layout for a look and a number of speakers.
escape pub fn229Escape text for markup.
base64 fn249Base64, for embedding an image so the page stays one file.
media_type fn276The media type for an image, by extension.
data_uri pub fn297Read an image and turn it into a data: URI.
inline_vtt pub fn326A WebVTT track as a data: URI, so a page opened from disk still has it.
background_markup fn331The background element, and anything worth telling the user about it.
player_head fn384The document head and the stylesheet.
player_body fn436The visible page: the drawing, the audio, the transport and the panel.
player_script fn506The script: lighting the right circle, the transport, and the corrections.
names_array fn607The speakers' names as a JavaScript array literal.
js_string fn617One name, safe to sit inside a double-quoted JavaScript string in HTML.
speaker_markup fn641One speaker's circle and name, as SVG.
Drawn pub struct749What a render produced, and anything the user should know about it.
still pub fn763A single frame, as standalone SVG.
player pub fn878The self-contained page that plays.
player_tests mod1432