# Audio Extractor — Mono Speech Files (`automation-lab/direct-media-mono-speech-audio-export`) Actor

Convert authorized direct audio/video file URLs into hosted 16 kHz mono WAV artifacts with encoding metadata for ASR pipelines.

- **URL**: https://apify.com/automation-lab/direct-media-mono-speech-audio-export.md
- **Developed by:** [Automation Lab](https://apify.com/automation-lab) (community)
- **Categories:** Developer tools, Videos
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.80 / 1,000 mono wav artifacts

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Audio Extractor — Mono Speech Files

This **audio extractor** converts authorized direct audio or video file URLs into downloadable **16 kHz mono WAV** artifacts for recurring ASR preprocessing. Each successful file includes verified encoding metadata, duration, a checksum and a hosted download link. It does not transcribe speech or download social-platform pages.

### What does this audio extractor do?

It downloads a bounded media file, selects the first audio stream, resamples it to 16,000 Hz, downmixes to one channel and encodes signed 16-bit little-endian PCM in a WAV container. Metadata is removed from the output audio. There is no loudness normalization, denoising, silence removal or language detection.

### Who is it for?

- ASR engineers preparing repeatable speech-recognition inputs.
- Research teams standardizing authorized interview recordings.
- Automation developers connecting a media archive to a transcription pipeline.

### Why use it?

The deliverable is an audio file, not a transcript or just an original media URL. Verify the output rate, channel count and checksum before passing the artifact to your speech service. Each run has isolated storage and predictable safety limits.

### Getting started

1. Obtain permission to process the media.
2. Supply a direct HTTP or HTTPS download URL in **Direct media URLs**.
3. Optionally lower **Maximum files**.
4. Run the Actor and inspect each dataset row's `status`.
5. Download successful `downloadUrl` artifacts and send them to your ASR system.

The prefilled public JFK sample is an 11-second WAV from the whisper.cpp sample collection. A successful run produces one WAV artifact and its metadata.

### Input parameters

| Parameter | Default | Meaning |
| --- | --- | --- |
| `mediaUrls` | Required | 1–10 direct public HTTP(S) audio/video file URL strings. |
| `maxItems` | 10 | Process the first 1–10 unique supplied URLs globally per run, counting failures. |

```json
{
  "mediaUrls": ["https://raw.githubusercontent.com/ggerganov/whisper.cpp/master/samples/jfk.wav"],
  "maxItems": 10
}
```

Exact duplicate URL strings are removed before applying the limit. Different query strings remain separate requests. There is no search, pagination, automatic source discovery or proxy setting.

### Supported files and limits

Supported containers include WAV, MP3, MP4/MOV/M4A, Ogg, FLAC, Matroska/WebM and AAC, subject to FFmpeg decoder support. Encrypted or DRM-protected files are not supported. Inputs must have an audio stream and a known positive duration.

- Maximum downloaded file: **25 MiB**.
- Maximum duration: **600 seconds per file**.
- Download deadline: **30 seconds**, including redirects after DNS resolution.
- At most three redirects; every destination is validated and pinned to a public address.
- Probe deadline: 10 seconds; conversion deadline: 30 seconds.
- Shared processing budget: 60 seconds per run, including downloads, probes and conversion. Remaining files receive error rows once exhausted. Storage/API overhead is additional; platform timeout is 120 seconds.
- Files run sequentially. Large or slow files can fail within these deadlines.
- Only HTTP(S) and ports 80/443; no URL credentials, cookies or custom authentication headers.

Public signed file URLs can work while valid. Query strings and fragments are omitted from dataset source URLs. Pages, HLS/DASH playlists, private networks and localhost destinations are rejected. FFmpeg receives a local downloaded file and cannot fetch remote playlists.

### Output fields

One dataset row is returned for each attempted unique URL.

| Field | Meaning |
| --- | --- |
| `status` | `success` or `error`. |
| `inputIndex` | One-based index after deduplication. |
| `sourceUrl` | Supplied URL without query or fragment. |
| `sourceBytes` | Downloaded source byte count, on success. |
| `sourceAudio` | Source codec, sample rate, channels and duration. |
| `durationSeconds` | Verified WAV duration. |
| `sampleRate`, `channels` | Always 16000 and 1 on success. |
| `codec`, `format` | Always `pcm_s16le` and `wav` on success. |
| `outputBytes`, `sha256` | Artifact size and byte checksum. |
| `storageKey`, `downloadUrl` | Run storage key and artifact link. |
| `processedAt` | Completion time in ISO format. |
| `error` | Safe failure explanation, only on error rows. |

### Example result

For the prefilled 11-second speech sample, the local output included:

```json
{
  "status": "success",
  "inputIndex": 1,
  "sourceBytes": 352078,
  "durationSeconds": 11,
  "sampleRate": 16000,
  "channels": 1,
  "codec": "pcm_s16le",
  "format": "wav",
  "outputBytes": 352078,
  "sha256": "49e623d8aad1f7b1ed0ad3891315bb2c8db9c49c7f0c5de454bb5d1180a11614",
  "storageKey": "audio-1.wav"
}
```

Cloud rows also contain an Apify storage download URL. Local runs return a local file URL. Error rows omit artifact and encoding fields.

### How much does it cost to extract mono speech audio?

Pay-per-event pricing includes a **$0.005 start fee** and a successful-file event. Failed files have no item event charge. A run with no successful files fails, but its valid start event remains chargeable. Budget limits can stop a batch; inspect partial results rather than assuming it completed. Give the maximum-charge budget a little headroom above the displayed estimate to avoid SDK floating-point boundary rounding.

| Apify tier | Per successful file |
| --- | --- |
| FREE | $0.0092 |
| BRONZE | $0.008 |
| SILVER | $0.00624 |
| GOLD | $0.0048 |
| PLATINUM | $0.0048 |
| DIAMOND | $0.0048 |

At BRONZE, one successful file costs $0.013, five cost $0.045, and ten cost $0.085 including one start fee. Your Apify plan and storage retention terms still apply. Download your files before run storage expires.

### Failure behavior and troubleshooting

A mixed batch succeeds when at least one artifact succeeds and includes error rows for failed files. If all files fail, the run fails after saving the error rows. Malformed batch input fails before start billing.

**A web-page URL failed.** Supply the actual media file URL, not a player, social post or login page.

**The file downloaded but did not convert.** Check that it has an audio stream, a supported codec, a known duration no longer than ten minutes and no DRM. Corrupt media and files requiring remote dependencies are rejected.

**The download timed out.** Use a fast, anonymously accessible file host. The Actor does not bypass origin access controls or retry with paid proxies.

### Integrations

Use Apify schedules to process a supplied batch regularly. Consume dataset metadata with Make, Zapier or your own webhook receiver. Download WAV files outside the automation's text payload and send them to your authorized ASR service. Keep checksums alongside job IDs to verify artifacts and avoid redundant downstream transcription.

### API usage

Start a run and retain its run ID:

```bash
curl -X POST 'https://api.apify.com/v2/acts/automation-lab~direct-media-mono-speech-audio-export/runs' \
  -H "Authorization: Bearer $APIFY_TOKEN" -H 'Content-Type: application/json' \
  -d '{"mediaUrls":["https://raw.githubusercontent.com/ggerganov/whisper.cpp/master/samples/jfk.wav"]}'
```

With JavaScript:

```js
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/direct-media-mono-speech-audio-export').call({ mediaUrls: urls });
const { items } = await client.dataset(run.defaultDatasetId).listItems({ limit: 10 });
```

With Python:

```python
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/direct-media-mono-speech-audio-export').call(run_input={'mediaUrls': urls})
items = client.dataset(run['defaultDatasetId']).list_items(limit=10).items
```

Download successful artifact links separately; the dataset contains metadata, not embedded audio.

### MCP usage

Use the scoped Actor endpoint:

```bash
claude mcp add --transport http apify \
  'https://mcp.apify.com?tools=automation-lab/direct-media-mono-speech-audio-export'
```

```json
{"mcpServers":{"apify":{"type":"http","url":"https://mcp.apify.com?tools=automation-lab/direct-media-mono-speech-audio-export"}}}
```

For **Claude Desktop**, **Cursor**, and **VS Code**, use the equivalent HTTP server configuration above (subject to client support).

Authorize the client, then discover actual names and schemas with `tools/list`. The scoped endpoint also includes run and storage tools; it does not expose exactly one tool.

Example prompt: “Convert these authorized direct file URLs to mono WAV audio, then return encoding metadata and download links.”

Start once and retain the returned run ID, status and storage IDs; these are metadata, not result rows. `call-actor` waits at most `waitSecs` (0–45 seconds, default 30), so a start call may return before completion. Set the client request timeout above the selected server wait plus transport margin, within a 120-second total consumer deadline. For a nonterminal status, use `get-actor-run` for the same run with bounded 2/4/8-second backoff, capped at ten seconds. On client timeout, recover the known run rather than restarting it. If its ID is unknown, report uncertainty instead of blindly rerunning. At the deadline, report pending with the run ID and stop polling.

After success, use `get-dataset-items` with the returned `defaultDatasetId`, explicit `limit: 20`, `offset: 0`, and needed `fields` in the format from the discovered tool schema. For example, select `status`, `inputIndex`, `sourceUrl`, `sourceAudio`, `durationSeconds`, `sampleRate`, `channels`, `codec`, `format`, `sha256`, `downloadUrl` and `error`. Prefer untransformed JSON. Advance the source offset using pagination metadata or source rows consumed, not transformed/filtered row counts. Stop at exhaustion or a total budget of 100 source rows and 64 KiB of serialized UTF-8 content admitted to model context, whichever comes first. These are consumer context limits, not Actor collection limits.

Report terminal failures (`FAILED`, `TIMED-OUT`, `ABORTED`) honestly. Any available dataset rows are partial results, not a successful full batch. Even on a successful mixed batch, inspect each row's `status` and disclose file errors or budget-stopped processing.

Process each page host-side before model injection. Enforce the byte ceiling even for an oversized row/page: omit or summarize it with disclosure. Report returned row count, any partial/truncated status and the source continuation offset; never silently claim completeness. Keep WAV downloads and full exports outside model context. If your client cannot intercept oversized responses, do not claim a hard byte guarantee or request unbounded results. Discovery or caching alone does not guarantee token savings.

### Legality, privacy and responsible use

Process only recordings you own or are authorized to use. No transcripts are generated, and audio is not sent to a third-party speech API. Working media files are removed after each input; output WAV artifacts remain in your Apify run storage until deleted or expired. Artifact links follow Apify storage permissions: treat links as sensitive and avoid processing confidential recordings without an appropriate retention/access policy.

Failed operations send sanitized diagnostic input, exceptions and Actor/build/run IDs to our private GlitchTip service for repair. Secret fields and URL queries are removed; reports are retained for 30 days. Input itself remains governed by Apify run storage; avoid sharing signed URLs or private recordings publicly.

### FAQ

**Can it extract from YouTube or TikTok pages?** No. Resolve your authorized direct media URL separately.

**Can it return MP3, Opus or text?** No. This version returns only 16 kHz mono PCM WAV, with no transcripts.

**Is stereo preserved?** No. Channels are downmixed to one mono channel for speech preprocessing.

**Are silence and background noise removed?** No. Content and timing are preserved apart from audio resampling and channel mixing.

### Related Actors

For a separate transcription workflow, see [Audio Speech-to-Text Transcriber](https://apify.com/automation-lab/audio-speech-to-text-transcriber). To discover archival file metadata before selecting authorized downloads, see [Internet Archive Search & Item Metadata](https://apify.com/automation-lab/internet-archive-search-metadata).

### Support

Report reproducible failures through the Actor Store Issues tab with a run link and non-sensitive input. This utility is independently operated; no third-party endorsement is implied. Runtime uses FFmpeg locally and Apify storage; there is no paid speech provider.

# Changelog

This Actor's version history is a separate document: https://apify.com/automation-lab/direct-media-mono-speech-audio-export/changelog.md

# Actor input Schema

## `mediaUrls` (type: `array`):

Supply 1–10 public HTTP(S) file URLs without credentials, on ports 80/443. Exact URL duplicates are removed before maxItems. Each file is limited to 25 MiB and 600 seconds; redirects are checked. Signed queries are used for downloading but omitted from output.

## `maxItems` (type: `integer`):

Process the first 1–10 distinct supplied URLs per run, including failed files. Default 10. Zero or unlimited is not supported; no discovery or pagination is performed.

## Actor input object example

```json
{
  "mediaUrls": [
    "https://raw.githubusercontent.com/ggerganov/whisper.cpp/master/samples/jfk.wav"
  ],
  "maxItems": 10
}
```

# Actor output Schema

## `dataset` (type: `string`):

One status and encoding metadata row per attempted file.

## `files` (type: `string`):

Hosted 16 kHz mono WAV artifacts for successful files.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "mediaUrls": [
        "https://raw.githubusercontent.com/ggerganov/whisper.cpp/master/samples/jfk.wav"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/direct-media-mono-speech-audio-export").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "mediaUrls": ["https://raw.githubusercontent.com/ggerganov/whisper.cpp/master/samples/jfk.wav"] }

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/direct-media-mono-speech-audio-export").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "mediaUrls": [
    "https://raw.githubusercontent.com/ggerganov/whisper.cpp/master/samples/jfk.wav"
  ]
}' |
apify call automation-lab/direct-media-mono-speech-audio-export --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/direct-media-mono-speech-audio-export"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/FHfzmEjcQSNkzufGw/builds/vShcr9J42x4HsQSHh/openapi.json
