Skip to content

Latest commit

 

History

History
194 lines (157 loc) · 7.76 KB

script.md

File metadata and controls

194 lines (157 loc) · 7.76 KB

Pivid play script JSON format

A "play script" is a JSON object describing the content Pivid should display. Play script JSON may be sent to a running pivid_server using the /play request, or supplied as a file to pivid_play --script.

A new play script may be sent to the server at any time, and playback will switch seamlessly. You choose whether to send only short term instructions and revise the script periodically, or send long sequences and only revise if necessary.

Play scripts may also include content preloading directives, anticipating content you might use in upcoming scripts (see the architecture overview).

Play script JSON format

Syntax legend:
«angle brackets» mark value placeholders (⏱️ indicates a time-varying value)
✳️ marks required values (other values are optional)
🔁 marks repeated items
▶️ 🔘 radio 🔘 buttons ◀️ describe alternative forms

{
  "zero_time": «timestamp baseline (default=server start)»,
  "main_loop_hz": «output timeline update frequency (default=30)»,

  "screens": {
    🔁 "«hardware connector, eg. HDMI-1»": {
      ✳️ "mode": ▶️ 🔘 [«video mode width», «height», «refresh rate»] 🔘 null ◀️,
      "update_hz": «content update frequency (default=mode refresh rate)», 
      "layers": [
        🔁 {
          ✳️ "media": "«media file, relative to media root»",
          "play": ⏱️ «seek position within media in seconds (default=0.0)», 
          "buffer": «media readahead in seconds (default=0.2)», 
          "from_xy": [
            ⏱️ «source media clip box left (default=0)»,
            ⏱️ «source media clip box top (default=0)»
          ],
                
          "from_size": [
            ⏱️ «source media clip box width (default=media width)»,
            ⏱️ «source media clip box height (default=media height)»
          ],
                
          "to_xy": [
            ⏱️ «screen region left (default=0)»,
            ⏱️ «screen region top (default=0)»
          ],
                
          "to_size": [
            ⏱️ «screen region width (default=media width)»,
            ⏱️ «screen region height (default=media height)»
          ],
                
          "opacity": ⏱️ «alpha value (default=1.0)» ,
          "reflect": «true to swap left/right before rotation (default=false)»,
          "rotate": «0, 90, 180, or 270 clockwise degrees (default=0)»
        }, ···
      ]
    }, ···
  }
  
  "buffer_tuning": {
    🔁 "«media file to configure, relative to media root»": {
      "seek_scan_time": «threshold for seeking vs reading (default=1.0)», 
      "decoder_idle_time": «retention time for unused decoders (default=1.0)», 
      🔽
      🔘 "pin": «seconds to always keep loaded from start of media»
      🔘 "pin": [«begin time within media», «end time within media»]
      🔘 "pin": [🔁 [«begin time within media», «end time within media»], ···]
      🔼
    }, ···
  }
}

General structure

Play scripts list all active outputs in "screens". (Use the pivid_scan_displays tool to show screen names.) For each screen, the script gives the video mode to use (see below), and a stack of layers to display.

Each layer references a single media file (still image or video), describing which part of the source image should be clipped out, and where it should be placed on screen. The clipped image will be resized as necessary to fit the destination region.

Play scripts may supply further options for specific media files in "media", independent of screens and layers which use the file. (If the default options are satisfactory, a media file need not be listed here.) These options include "preload" definitions which instruct pivid to cache portions of the media, anticipating script updates.

Time reference and zero_time

Pivid script timing is based on wall-clock Unix time. (It's best to make sure your server's clock is synced.)

The top level zero_time value is a Unix timestamp as a raw number (eg. 1651893234.4 for 2022-05-06 8:13:54.4pm PT). Other time values in the script are offsets from this value. If zero_time is 0.0, other timestamps are absolute Unix times. If not set, zero_time defaults to the time when the server was started.

Time-varying values

Many values in pivid scripts (marked with ⏱️ in the syntax above) may be set to change over time. This is the basis of all animation, including basic video playback (a time-varying "play" position).

If the value should not actually vary with time, a simple number may be used (the third format below).

🔽
🔘 {
     "segments": [
       🔁 {
         🔽
         🔘 "t": [«begin timestamp», «end timestamp»],
         🔘 "t": «begin timestamp (default=0.0)», "length": «seconds (default=infinite)»,
         🔼

         🔽
         🔘 "v": [«value at begin», «control point», «control point», «value at end»],
         🔘 "v": [«value at begin», «value at end»],
         🔘 "v": «value at begin», "rate": «units per second (default=0.0)»,
         🔼
       }, ···
     ],

     "repeat": ▶️ 🔘 «loop period» 🔘 true ◀️
   }

🔘 {
     "t": «same as "t" above»,
     "v": «same as "v" above»,
     "repeat": «same as "repeat" above»
   }

🔘 «constant value for all time»
🔼

In the most general case (the first format above), the value is defined piecewise as a collection of segments with begin and end times. Segments must be listed in time order and may not overlap. Before, between, and after defined segments, the value is undefined and reverts to its default.

Within each segment, the value is described by a 1-dimensional cubic Bézier curve. The Bézier curve may be described by the value at the ends of the segment, plus optional control points at 1/3 and 2/3 from begin to end, or by the starting point and a slope.

If "repeat" is set, the value loops with the given period (if provided) or after the last segment ends (if true).

If there is only one segment, a simplified format (the second format above) lists the segment by itself without a top-level object; the repeat value (if present) is now in the single segment. An even more simplified format (the third format above) gives a single value which never changes.

Video modes

For each screen, play scripts list the video mode resolution and refresh rate to use (null to disable the display). Pivid attempts to find a matching mode defined by these standards:

  • CTA-861 (consumer TV modes)
  • VESA DMT (list of computer monitor modes)
  • VESA CVT (general formula for computer monitors)

If no mode timings can be found, the script is rejected.

The connected display's capabilities are not checked in this process. For pivid's use cases, consistent and direct video mode control is normally preferred. To adapt to display capabilities, clients may use the /screens request and choose modes as desired.

Next: Development notes and links