Slideshow with voiceover: time each slide to its sentence

Make a slideshow with voiceover by holding each slide for its narration line. With Sume, TTS sentence timings become the slide slots in one render.

5 min readSume
All posts

To make a slideshow with voiceover, write one narration line per slide, record or generate the narration, and keep each slide on screen for exactly as long as its line is spoken, with any music mixed quietly under the voice. With Sume, TTS 1.0 speaks the whole script and returns the start and length of each sentence, and one Timeline 1.0 render uses those times as the slide slots over the narration.

Facts come from the TTS 1.0 schema in the Sume API reference, the OpenAPI document behind the API reference docs, and the Timeline 1.0 docs, read on 2026-09-27. Anything described as current behavior is read from Sume's code. For a music-only slideshow with no narration, see Image slideshow video API.

How do I time each slide to its line?

Write the script with one sentence per slide. That is a writing convention, not a Sume rule, but it makes the mapping one to one. Then synthesize the whole script in a single POST /v1/tts-1.0/generate, so the voice runs continuously:

  • segmentation: { "mode": "sentence" } requires timestamps: { "words": true } and returns gapless segments[]: each segment ends exactly where the next one starts.
  • The cut falls 70 ms after a sentence's last word by default (boundary_lead_ms, 0–500), and the next segment absorbs the pause, so each slide changes just after its line ends.
  • In the current code each segment carries index, text, start, end, and duration_seconds. The first starts at 0, and the last ends at the file's duration_seconds.
  • With WAV or raw output, each sentence also gets its own sample-exact audio_url; with MP3 you get the timings only.
curl -X POST https://api.sume.com/v1/tts-1.0/generate \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: trip-slideshow-narration-v1" \
  -d '{
    "transcript": "We landed at dawn. The old tram climbs to the castle. Dinner was by the river.",
    "voice": { "id": "YOUR_VOICE_ID" },
    "output_format": { "container": "wav", "encoding": "pcm_s16le", "sample_rate": 44100 },
    "timestamps": { "words": true },
    "segmentation": { "mode": "sentence" }
  }'

How do I turn the timings into a video?

One Timeline 1.0 render, POST /v1/timeline-1.0/render, plays the narration as its audio spine and holds one still per sentence. Three rules apply to its inputs, and the table shows which TTS numbers to copy into which fields:

  • Every URL must already be your workspace's media.sume.com artifact or asset, such as the output of an earlier Sume job, and an off-host URL is refused with unsupported_media_source. The public API reference documents no upload route for files from your computer, so plan on stills Sume generated, for example with the image API.
  • A still is a static hold. motion is accepted and ignored with a motion_ignored warning, so photos do not zoom or pan.
  • Transitions are optional. Each lasts at most 1 s and at most half of the shorter neighboring slot, and declared starts stay authoritative.
From the Sume API reference, Timeline 1.0, and current code, read 2026-09-27.
TTS resultTimeline 1.0 field
audio_urlaudio.url: the narration spine
duration_secondsaudio.duration_seconds: the output length, 1–1,800 s
segments[i].startvideo[i].start: video[0].start must be 0, and later starts must increase
segments[i].duration_secondsvideo[i].duration: at least 0.2 s
curl -X POST https://api.sume.com/v1/timeline-1.0/render \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: trip-slideshow-render-v1" \
  -d '{
    "audio": { "url": "https://media.sume.com/artifacts/artf_demo/narration.wav", "duration_seconds": 8.16 },
    "video": [
      { "source_url": "https://media.sume.com/artifacts/artf_demo/slide-1.png", "start": 0, "duration": 2.43 },
      { "source_url": "https://media.sume.com/artifacts/artf_demo/slide-2.png", "start": 2.43, "duration": 2.61 },
      { "source_url": "https://media.sume.com/artifacts/artf_demo/slide-3.png", "start": 5.04, "duration": 3.12 }
    ],
    "soundtrack": {
      "url": "https://media.sume.com/artifacts/artf_demo/music.mp3",
      "loop": true, "duck_db": 8, "fade_out_seconds": 2
    }
  }'

How do I add music under the voiceover?

Add a soundtrack to the same render, as in the example above. Its url must also be Sume-hosted. gain_db defaults to −16 dB, a bed level under a spine. loop repeats a short track until the narration ends, fade_out_seconds (up to 10) fades it out, and duck_db (0–20) dips the music while the narration speaks. Add background music to a video covers the bed in detail.

What does a narrated slideshow cost, and what are the limits?

It takes two paid jobs, each plus a 5.5% agent fee by default. Check the render document first with POST /v1/timeline-1.0/plan: it is unbilled and returns the duration and billable minutes without creating a job.

  • Narration: $0.0475 per 1,000 characters, spaces and punctuation included, for up to 20,000 characters and 1,200 seconds of audio per request.
  • Render: $0.10 per output minute on API pricing; the reserve is ceil(audio.duration_seconds / 60) minutes.
  • One render takes 1–200 slots and makes 1–1,800 seconds of video.
  • The output always runs exactly audio.duration_seconds, so with the TTS value there the last slide ends with the narration.

Sources

Related posts

More in Use cases

All Use cases posts

Written by Sume