# Where Generated Audio Files Are Stored and Served From in Ace-Step-UI

> Discover where Ace-Step-UI stores and serves generated audio files. Learn about the LocalStorageProvider and Vite's role in managing audio assets for your application.

- Repository: [fspecii/ace-step-ui](https://github.com/fspecii/ace-step-ui)
- Tags: how-to-guide
- Published: 2026-04-29

---

**TLDR:** Generated and uploaded audio files in ace-step-ui are physically stored in the server's `public/audio` directory and served to clients via the virtual path `/audio/<filename>`, with the `LocalStorageProvider` class handling disk writes and URL construction while Vite's static file handling manages delivery.

The ace-step-ui repository implements a local storage strategy for managing audio assets, utilizing the filesystem for persistence and virtual paths for client access. Understanding exactly where generated audio files are stored and served from is critical for configuring deployments, debugging 404 errors, and managing disk space in production environments.

## Server-Side Storage Implementation

The storage backend resides in [`server/src/services/storage/local.ts`](https://github.com/fspecii/ace-step-ui/blob/main/server/src/services/storage/local.ts) and implements the `LocalStorageProvider` class. This provider handles both the physical persistence of audio data and the generation of public URLs that clients use to retrieve assets.

### Physical Storage Location

The provider defines a constant `AUDIO_DIR` that resolves to the `public/audio` folder relative to the server source location. When the `upload(key, data, _contentType)` method receives audio data, it writes the raw buffer directly to disk using Node.js `writeFile`, persisting the file at `public/audio/<filename>`.

### URL Generation Logic

The same service constructs public-facing URLs through the `getUrl()` and `getPublicUrl()` methods. These methods normalize the input key by stripping any existing `/audio/` prefix to prevent duplication, then return a standardized path formatted as `/audio/<clean-filename>`. This ensures all stored audio assets receive consistent virtual paths regardless of how the key was originally provided.

## Client-Side Audio URL Resolution

On the frontend, the `getAudioUrl()` function in [`services/api.ts`](https://github.com/fspecii/ace-step-ui/blob/main/services/api.ts) normalizes audio URLs before they reach the browser. The implementation checks if the provided URL already begins with `/audio/`:

- If true, it returns the URL as-is, causing the browser to request `https://<host>/audio/<filename>` from the server
- If false, it returns the original value unchanged, supporting external audio sources

This dual-path logic ensures that locally stored assets map correctly to the static file endpoint while preserving compatibility with third-party audio URLs.

## Temporary Audio Handling During Video Export

Not all audio files persist to the `public/audio` directory. In [`components/VideoGeneratorModal.tsx`](https://github.com/fspecii/ace-step-ui/blob/main/components/VideoGeneratorModal.tsx), the video generation workflow writes audio data to an in-memory FFmpeg filesystem using `ffmpeg.writeFile('audio.mp3', new Uint8Array(audioDataCopy))`. This `audio.mp3` file exists only temporarily within the FFmpeg virtual filesystem during the encoding process. Once the video export completes, this temporary audio is encoded into the final video output and immediately discarded, never touching the physical storage layer.

## Static File Serving Configuration

The project relies on Vite's built-in static file handling to serve persisted audio assets. Because the `public/audio` directory resides within the Vite `public` folder, files written there by the `LocalStorageProvider` are automatically accessible at the root URL path. No explicit Express routes or server middleware configuration is required—requests to `/audio/<filename>` are transparently mapped to the corresponding physical file on disk, delivering the asset directly via the development server or production build.

## Code Examples

### Uploading an Audio File from the Client

```typescript
import { storage } from '../services/api';

// Assuming `file` is a `File` object selected by the user
const arrayBuffer = await file.arrayBuffer();
await storage.upload(`my-song.mp3`, Buffer.from(arrayBuffer), 'audio/mpeg');

// Get the public URL to embed in a song record
const audioUrl = await storage.getPublicUrl(`my-song.mp3`); 
// Returns: "/audio/my-song.mp3"

```

### Resolving Audio URLs for Playback

```tsx
import { getAudioUrl } from '../services/api';

const rawUrl = song.audio_url;               // e.g., "/audio/my-song.mp3"
const url = getAudioUrl(rawUrl, song.id);    // Returns: "/audio/my-song.mp3"

return <audio src={url} controls />;

```

### Server-Side Static Serving

No server code is required to serve the files. Placing a file at `public/audio/example.mp3` makes it immediately reachable at:

```

https://your-domain.com/audio/example.mp3

```

## Summary

- **Storage Location:** Audio files are written to `public/audio` on the server filesystem by the `LocalStorageProvider` in [`server/src/services/storage/local.ts`](https://github.com/fspecii/ace-step-ui/blob/main/server/src/services/storage/local.ts)
- **URL Pattern:** All stored audio assets are served via the virtual path `/audio/<filename>` constructed by the `getUrl()` method
- **Client Resolution:** The `getAudioUrl()` helper in [`services/api.ts`](https://github.com/fspecii/ace-step-ui/blob/main/services/api.ts) normalizes URLs to ensure they point to the correct static endpoint
- **Temporary Files:** Audio used during video export in [`VideoGeneratorModal.tsx`](https://github.com/fspecii/ace-step-ui/blob/main/VideoGeneratorModal.tsx) is processed in-memory by FFmpeg and never persisted to disk
- **Serving Mechanism:** Vite's static file handling automatically maps `/audio/` requests to the `public/audio` directory without additional configuration

## Frequently Asked Questions

### What directory does ace-step-ui use for audio storage?

The application stores audio files in `public/audio` relative to the project root. The `LocalStorageProvider` class in [`server/src/services/storage/local.ts`](https://github.com/fspecii/ace-step-ui/blob/main/server/src/services/storage/local.ts) defines this path via the `AUDIO_DIR` constant and uses it as the destination for all `upload()` operations.

### How does the client access uploaded audio files?

Clients access audio through virtual URLs starting with `/audio/`. The `getAudioUrl()` function in [`services/api.ts`](https://github.com/fspecii/ace-step-ui/blob/main/services/api.ts) ensures that stored asset paths are returned as-is (e.g., `/audio/song.mp3`), which the browser then requests from the server. Vite's static file middleware handles these requests by serving the corresponding file from `public/audio`.

### Are temporary audio files during video export saved to disk?

No. During video generation in [`components/VideoGeneratorModal.tsx`](https://github.com/fspecii/ace-step-ui/blob/main/components/VideoGeneratorModal.tsx), audio is written only to the in-memory FFmpeg filesystem using `ffmpeg.writeFile()`. This temporary data is encoded into the final video output and discarded immediately after; it never reaches the `public/audio` storage directory.

### Do I need to configure a custom route to serve audio files?

No additional route configuration is necessary. Because `public/audio` resides within the Vite `public` directory, the framework automatically serves files placed there at the `/audio/<filename>` endpoint. The `LocalStorageProvider` leverages this convention by writing files to that directory and returning matching virtual paths.