audio Component Type

Table of Contents

Overview

The audio type extends file and keeps its embedded file value contract, picker/drop/paste acquisition, import/export, singleton, list, and download behavior.

<audio data-smark='{"type":"audio","name":"clip"}'
       controls preload="metadata"></audio>

Bare <audio data-smark> elements infer type: "audio" automatically. Unlike video, an empty audio element has no visual box, so add a singleton wrapper or companion triggers when you want an empty-state upload affordance.

Large export warning: audio values are embedded as base64. Exporting a large clip into the playground textarea serializes the entire payload and can temporarily freeze the browser. This is a limitation of displaying a large JSON/data-URL value in a textarea, not a media playback requirement. Production applications should avoid rendering multi-megabyte exports in a textarea and should submit/store the value through an appropriate binary or server-side path.

Try It

These examples use short public-domain audio excerpts (Beethoven’s 5th Symphony and Moonlight Sonata openings) so they work without a remote media host. You can replace them with your own audio in the preview. The playground’s Import button can also be used with an exported embedded value. Attribution is in docs/assets/audio-demo-attribution.md.

Basic Real Audio Field

🔗
<div id="myForm">
    <strong>Clip</strong>
    <audio data-smark='{"name":"clip"}' controls preload="metadata"></audio>
    <button data-smark='{"action":"pick","context":"clip"}'>Choose or replace audio</button>
</div>
const myForm = new SmarkForm(document.getElementById("myForm"), {
    "value": {"clip": "/assets/audio_beethoven_5th.mp3"}
});

👉 Try it! The <audio> element is the field itself. Because it has native controls, clicking it controls playback; use the button to upload or replace the clip.

👉 Choose an MP3, MP4/AAC, Ogg, WAV or another format your browser supports. The example starts with the opening of Beethoven’s 5th Symphony loaded by demoValue. Attribution is in the repo at docs/assets/audio-demo-attribution.md.

Every example in this section comes with many of the following tabs:

  • HTML: HTML source code of the example.
  • CSS: CSS applied (if any).
  • JS: JavaScript source code of the example.
  • Preview: Live, sandboxed rendering of the example — fully isolated from the page styles.
  • Notes: Additional notes and insights for better understanding. Don't miss it‼️

✨ In the Preview tab, a JSON playground editor is available with handy buttons:

  • ⬇️ Export to export the form data to the JSON playground editor.
  • ⬆️ Import to import data from the JSON playground editor into the form.
  • ♻️ Reset in forms prefilled with sample data, resets the form to its default values.
  • ❌ Clear to clear the whole form.

💡 The JSON playground editor is part of the SmarkForm form itself — it is just omitted from the code snippets to keep the examples focused on what matters.

🛠️ Between the tab labels and the content there is always an edit toolbar:

  • ✏️ Edit — activates edit mode: each source tab turns into a syntax-highlighted code editor (powered by Ace) pre-filled with the full, merged source. Changes are sandboxed — the original example is not affected.
  • 📋 Include playground editor — (only visible in edit mode) controls whether the JSON playground editor is included in the preview. When toggled, the HTML and JS editors update instantly so you can see exactly what code is needed to add or remove it.
  • ▶️ Run — (only visible in edit mode) re-renders the Preview from the current editor contents and switches to the Preview tab.

Singleton With An Editable Name

🔗
<div id="myForm">
    <figure class="audio-card" data-smark='{"type":"audio","name":"clip"}'>
        <audio data-smark controls preload="metadata"></audio>
        <figcaption data-smark='{"action":"rename"}'>edit filename</figcaption>
        <button data-smark='{"action":"pick"}'>Choose or replace audio</button>
        <button data-smark='{"action":"download"}'>Download</button>
    </figure>
</div>
#myForm .audio-card { max-width: 360px; padding: 1rem; border: 2px dashed #999; text-align: center; background: #fafafa; border-radius: .5rem; }
#myForm audio { display: block; width: 100%; }
#myForm figcaption { margin: .75rem 0; padding: .25rem; }
#myForm button { margin: .25rem; }
const myForm = new SmarkForm(document.getElementById("myForm"), {
    "value": {"clip": "/assets/audio_moonlight_sonata.mp3"}
});

👉 The wrapper accepts drops and pastes, while the caption edits the exported filename. Upload a clip, replace edit filename, then use Download.

👉 Native controls supplies playback; the explicit Choose or replace audio button opens the picker. SmarkForm keeps the bytes unchanged and does not transcode the audio.

👉 Initial clip: opening of Beethoven’s Moonlight Sonata. Attribution is in docs/assets/audio-demo-attribution.md.

Every example in this section comes with many of the following tabs:

  • HTML: HTML source code of the example.
  • CSS: CSS applied (if any).
  • JS: JavaScript source code of the example.
  • Preview: Live, sandboxed rendering of the example — fully isolated from the page styles.
  • Notes: Additional notes and insights for better understanding. Don't miss it‼️

✨ In the Preview tab, a JSON playground editor is available with handy buttons:

  • ⬇️ Export to export the form data to the JSON playground editor.
  • ⬆️ Import to import data from the JSON playground editor into the form.
  • ♻️ Reset in forms prefilled with sample data, resets the form to its default values.
  • ❌ Clear to clear the whole form.

💡 The JSON playground editor is part of the SmarkForm form itself — it is just omitted from the code snippets to keep the examples focused on what matters.

🛠️ Between the tab labels and the content there is always an edit toolbar:

  • ✏️ Edit — activates edit mode: each source tab turns into a syntax-highlighted code editor (powered by Ace) pre-filled with the full, merged source. Changes are sandboxed — the original example is not affected.
  • 📋 Include playground editor — (only visible in edit mode) controls whether the JSON playground editor is included in the preview. When toggled, the HTML and JS editors update instantly so you can see exactly what code is needed to add or remove it.
  • ▶️ Run — (only visible in edit mode) re-renders the Preview from the current editor contents and switches to the Preview tab.

Audio List

🔗
<div id="myForm">
    <ul data-smark='{"type":"list","name":"tracks","of":"audio","min_items":0,"max_items":4}'>
        <li>
            <audio data-smark controls preload="metadata"></audio>
            <button data-smark='{"action":"removeItem"}'>Remove</button>
        </li>
    </ul>
    <button data-smark='{"action":"addItem","context":"tracks"}'>Add track</button>
</div>
const myForm = new SmarkForm(document.getElementById("myForm"), {
    "value": {"tracks": [
    "/assets/audio_beethoven_5th.mp3",
    "/assets/audio_moonlight_sonata.mp3"
]}
});

👉 Add tracks with the list picker or drop files onto the list. Audio-capable lists append OS drops instead of replacing an existing item.

Every example in this section comes with many of the following tabs:

  • HTML: HTML source code of the example.
  • CSS: CSS applied (if any).
  • JS: JavaScript source code of the example.
  • Preview: Live, sandboxed rendering of the example — fully isolated from the page styles.
  • Notes: Additional notes and insights for better understanding. Don't miss it‼️

✨ In the Preview tab, a JSON playground editor is available with handy buttons:

  • ⬇️ Export to export the form data to the JSON playground editor.
  • ⬆️ Import to import data from the JSON playground editor into the form.
  • ♻️ Reset in forms prefilled with sample data, resets the form to its default values.
  • ❌ Clear to clear the whole form.

💡 The JSON playground editor is part of the SmarkForm form itself — it is just omitted from the code snippets to keep the examples focused on what matters.

🛠️ Between the tab labels and the content there is always an edit toolbar:

  • ✏️ Edit — activates edit mode: each source tab turns into a syntax-highlighted code editor (powered by Ace) pre-filled with the full, merged source. Changes are sandboxed — the original example is not affected.
  • 📋 Include playground editor — (only visible in edit mode) controls whether the JSON playground editor is included in the preview. When toggled, the HTML and JS editors update instantly so you can see exactly what code is needed to add or remove it.
  • ▶️ Run — (only visible in edit mode) re-renders the Preview from the current editor contents and switches to the Preview tab.

Empty-State Upload Affordance

Without native controls, the <audio> element has no visible surface. Wrap it in a singleton container to provide an empty-state label and upload affordance.

🔗
<div id="myForm">
    <div class="audio-upload" data-smark='{"type":"audio","name":"clip"}'>
        <audio data-smark preload="metadata"></audio>
        <p class="audio-hint">Drop an audio file or click to upload</p>
        <button data-smark='{"action":"pick"}'>Choose audio</button>
        <button data-smark='{"action":"download"}'>Download audio</button>
        <span data-smark='{"action":"rename"}'>edit filename</span>
    </div>
</div>
#myForm .audio-upload { max-width: 360px; padding: 1.5rem; border: 2px dashed #999; text-align: center; background: #fafafa; border-radius: .5rem; }
#myForm .audio-hint { margin: 0 0 .75rem; }
#myForm button { margin: .25rem; }
#myForm [data-smark] { margin-right: .25rem; }
const myForm = new SmarkForm(document.getElementById("myForm"), {
    "value": {"clip": "/assets/audio_beethoven_5th.mp3"}
});

👉 Because the inner <audio> has no controls, the whole wrapper is the drop surface and the button opens the picker. Once a clip is loaded, use Download audio to retrieve the embedded value; add controls if you want a visible player strip.

👉 Initial clip: opening of Beethoven’s 5th Symphony. See docs/assets/audio-demo-attribution.md for attribution.

Every example in this section comes with many of the following tabs:

  • HTML: HTML source code of the example.
  • CSS: CSS applied (if any).
  • JS: JavaScript source code of the example.
  • Preview: Live, sandboxed rendering of the example — fully isolated from the page styles.
  • Notes: Additional notes and insights for better understanding. Don't miss it‼️

✨ In the Preview tab, a JSON playground editor is available with handy buttons:

  • ⬇️ Export to export the form data to the JSON playground editor.
  • ⬆️ Import to import data from the JSON playground editor into the form.
  • ♻️ Reset in forms prefilled with sample data, resets the form to its default values.
  • ❌ Clear to clear the whole form.

💡 The JSON playground editor is part of the SmarkForm form itself — it is just omitted from the code snippets to keep the examples focused on what matters.

🛠️ Between the tab labels and the content there is always an edit toolbar:

  • ✏️ Edit — activates edit mode: each source tab turns into a syntax-highlighted code editor (powered by Ace) pre-filled with the full, merged source. Changes are sandboxed — the original example is not affected.
  • 📋 Include playground editor — (only visible in edit mode) controls whether the JSON playground editor is included in the preview. When toggled, the HTML and JS editors update instantly so you can see exactly what code is needed to add or remove it.
  • ▶️ Run — (only visible in edit mode) re-renders the Preview from the current editor contents and switches to the Preview tab.

Empty State And Playback

An empty field shows an inactive <audio> element. Because an <audio> has no visual box by itself, authors who want an empty-state affordance should wrap the element in a singleton container or add companion triggers.

Use native controls when the field should be a player. Without controls, smark_audio_click: "pick" (the default when controls are absent) makes the audio surface an upload affordance. Use smark_audio_click: "play" for a programmatic player; Space toggles playback and Shift+Space still opens the picker.

<audio data-smark='{"name":"clip","smark_audio_click":"play"}'
       preload="metadata"></audio>

SmarkForm does not transcode or re-encode audio. The stored value remains the original bytes; presentation is handled through the element’s src.

Keyboard And Caption Navigation

The audio itself is one SmarkForm field. Enter moves to the next field and Shift+Enter moves to the previous field. When the audio has focus:

  • Space opens the picker in pick mode, or toggles playback in play mode.
  • Shift+Space opens the picker even in play mode.
  • Delete or Backspace clears the audio when it has a value.

The editable filename caption and trigger buttons are normal browser controls, so Tab and Shift+Tab reach them independently. Delete and Backspace edit the caption while the caption has focus; they clear the audio when the audio field itself has focus.

Validation And Options

Interactive acquisition probes the bytes with an off-DOM <audio> element and rejects malformed media silently. Set smark_audio_validate: false to disable that probe. audio_maxSize rejects oversized files before reading them and dispatches cancellable smark:audioNotice.

Common options:

  • accept defaults to audio/* and filters picker, drop, and paste input.
  • smark_audio_open, smark_audio_drop, and smark_audio_paste disable the corresponding interaction when set to false.
  • smark_audio_clearOnDelete controls Delete/Backspace clearing.
  • smark_audio_click ("auto" | "pick" | "play") resolves the click/Space conflict. "auto" defaults to play when controls is present, otherwise pick.
  • smark_audio_autoPick opens the picker after rendering when true (subject to the browser’s user-gesture policy).
  • audio_maxSize byte cap rejects acquisition above the limit.
  • format and encoding are inherited from file.

The type does not transcode or re-encode audio. Imported values are trusted and embedded; validation applies to interactive acquisition.

Format Recommendations

For universal playback, prefer MP3 or MP4/AAC. WAV and FLAC work in all major browsers if lossless fidelity is needed. Ogg Vorbis/Opus and WebM/Opus are fine on Chromium and Firefox but may fail on Safari.

Singletons And Lists

A wrapper containing exactly one inner <audio> becomes a singleton. Mark an editable filename with the rename trigger action; SmarkForm sets contenteditable and synchronizes the stored filename automatically:

<figure data-smark='{"type":"audio","name":"clip"}'>
  <audio data-smark controls preload="metadata"></audio>
  <figcaption data-smark='{"action":"rename"}'></figcaption>
</figure>

Lists use of: "audio" and inherit file-list acquisition and drop behavior:

<ul data-smark='{"type":"list","name":"tracks","of":"audio"}'>
  <li data-smark='{"type":"audio"}'>
    <audio data-smark controls preload="metadata"></audio>
  </li>
</ul>

OS drops append audio items in an audio-capable list. Captions remain item-local.

When a list item is an audio field, addItem can open the picker immediately as part of the user’s add action. For a form-backed list item containing several fields, use smark_audio_autoPick: true on the particular audio field when an automatic picker is desired. This is opt-in and browser-dependent: a picker opened after an asynchronous render may be blocked when no user gesture is active, so an explicit pick trigger remains the reliable fallback.