Process up to 100 direct video or audio file URLs in one run. Probe metadata, extract 16 kHz speech audio, create a thumbnail, remux, or build a lightweight analysis proxy, with one status row per file.
2026-10-19: Trim, MP3/Opus audio, GIF and web/social MP4 (0.1.10)
Features
audio converts the first audio track to MP3, Opus, M4A or WAV, with bitrateKbps, sampleRate and channels.
gif makes an animated GIF of up to 30 seconds with a palette built from the clip (fps, maxWidth). A longer source keeps its first 30 seconds, and the row says so in output.trim.capped.
web_mp4 re-encodes to H.264 for a web page at 480p or 720p (maxHeight), never upscaled, with faststart.
social_mp4 writes an upload-safe H.264 High MP4: at most 1080 wide and 30 fps, AAC at 48 kHz, no edit list. It does not crop or reframe.
trim (startSeconds with endSeconds or durationSeconds) cuts a window for audio, gif, web_mp4, social_mp4, audio16k and proxy. The charge counts the minutes of the window, not of the source. A start at or past the end of the file is INVALID_INPUT with TRIM_OUT_OF_RANGE, uncharged.
Pricing
A web_mp4 or social_mp4 file from a source frame larger than 1280x720 is charged media-transformed-hd ($0.05 per started output minute) once that event is on the pricing tab; until then it is charged as media-transformed. These two operations refuse sources above 1920x1080 with TOO_LARGERESOLUTION_CAP, uncharged.
Improvements
Rows of the new operations, and trimmed audio16k or proxy rows, carry the measured output.format, output.duration_seconds, output.width, output.height and output.trim. Rows of the other operations keep their earlier shape.
The operation picker in the Console names what each operation writes.
audio16k with formatmp3 now points to the audio operation.
2026-10-19: Diagnostic lines in the run log (0.1.9)
Fixes
The run log now shows the FFmpeg build line and each download attempt (with query values redacted). Before, these informational lines were dropped, so a shared run showed only warnings and the final status.
2026-10-18: Integration input with a nested dataset id fails clearly
Fixes
An input that carries the dataset id only inside a webhook body (payload.resource.defaultDatasetId or resource.defaultDatasetId) now ends FAILED with an INVALID_INPUT summary that tells you to set top-level datasetId. Before, the run succeeded without processing any file. In an integration, set datasetId to {{resource.defaultDatasetId}}.
2026-10-12: Fewer false failures, dataset paging and clearer run results (0.1.6)
Features
Process a dataset larger than 100 rows across runs. Set datasetOffset to skip rows; when rows remain, RUN_SUMMARY gives nextDatasetOffset and nextAction names the offset for the next run. source_index is the row's position in the dataset, so generated ids stay the same across those runs.
Top-level options apply to every file, in items mode and in dataset mode. You can now pick the thumbnail position and format, the remux container or the proxy width when the URLs come from a dataset. A file with its own options uses those instead. Invalid top-level options stop the run before anything is downloaded.
Each row has input.sha256, the hash of the downloaded file, so you can recognize the same file behind a new signed URL. It is not part of fingerprint, so new rows stay comparable with earlier ones.
Improvements
A short run timeout keeps most of its time for files. The time held back for the final delivery is 90 seconds on a long run and shrinks on a short one, for example 15 seconds on a 100 second run, which before could not start any file.
probe reports media of any length. maxDurationSeconds now limits transforms only.
An idField value may be a number, and other characters in it become hyphens instead of failing the file.
scraped_at is the time this run finished that file, not the time the batch started.
Fixes
proxy no longer fails on a source with an odd width, or with an odd maxWidth.
remux to MP4 no longer fails when the file has subtitles, font attachments or data tracks: MP4 keeps video and audio. remux to MKV no longer fails on a data track such as a camera timecode; it keeps every other stream.
A thumbnail at atPercent 100, or at atSeconds equal to the duration, now returns the last frame instead of failing.
audio16k on a file without audio, and thumbnail or proxy on a file without video, now return UNSUPPORTED_MEDIA with NO_AUDIO_STREAM or NO_VIDEO_STREAM instead of an ffmpeg error.
An output file too large for the run memory to upload (above about 225 MB at 1024 MB, 565 MB at 2048 MB) is now TOO_LARGE with OUTPUT_TOO_LARGE, uncharged, instead of ending the whole run out of memory. Raise the memory to 2048 MB for larger remux or proxy outputs.
A file stopped by the run timeout is reported as TIMEOUT with RUN_DEADLINE, even when the timeout cut its download or ffmpeg step short. Before, it could read as a slow download, an ffmpeg timeout or an unreadable output.
downloadTimeoutSeconds now limits the whole download of a file, retry included.
A redirect to a host that does not resolve is SOURCE_FAILED with DNS_FAILED, not a blocked address. HTTP 410 is SOURCE_NOT_FOUND.
A download without a Content-Length can no longer use up the share of maxTotalInputBytes held by a file that announced its size.
A long file that does not fit maxTotalChargeUsd no longer turns away shorter files that still fit.
A run in which the run timeout stopped every file now delivers its rows and then ends FAILED with globalFailureRUN_DEADLINE in RUN_SUMMARY. Before, it ended SUCCEEDED with nothing useful. Nothing is charged for those files.
When the outcome of a charge is unknown, RUN_SUMMARY keeps billingStatusUNCERTAIN and does not show exact charged counts, even if later charges in the same run succeeded.
A resumed run publishes every stored row, including when two rows share an id because one is a DUPLICATE_ID rejection.
Pricing and limits
Prices and billing events are unchanged.
2026-10-06: Long batches finish before the run timeout (0.1.5)
Fixes
A batch that runs into the run timeout no longer ends timed out without a summary. Near the timeout, downloads and ffmpeg get only the time that is left, and files that cannot start in time get a TIMEOUT row with error.codeRUN_DEADLINE. They are not charged, finished files stay valid, and RUN_SUMMARY tells you to send the remaining ids again.
Adding a datasetId in the Console no longer fails with "Provide items or a dataset, not both" when the prefilled sample in items was left in place. The untouched sample is dropped and the dataset is processed. Items you edited next to a datasetId are still rejected.
An unexpected error inside the batch, or two different failures at the same time, now end the run with a RUN_SUMMARY and the finished rows delivered, instead of crashing without a summary.
2026-09-26: More reliable requests and spending checks (0.1.4)
Fixes
Spending checks and billing receipts use the effective event prices supplied for your run, including discounts and zero-priced events.
2026-09-24: Per-minute transform pricing and safer downloads (0.1.1)
This version was not yet on the Apify Store.
Features
An interrupted run keeps each finished row and publishes it on resume without charging that row again.
Improvements
The default memory is 1024 MB and the maximum is 2048 MB, so a short file no longer starts on 2048 MB.
A file's full minute price is reserved together, so two long files cannot stall each other.
Downloads stop once maxTotalInputBytes is used. A content-length hold becomes spent bytes as they arrive, so it does not block another file that still fits. Bytes that already arrived stay counted even when the response is cut short.
Gzip responses are decoded. The shared cap counts the wire size, and maxInputBytesPerItem counts the decoded media. Inflation stops at that cap for gzip, raw deflate and Brotli.
An integration should put the dataset id in datasetId (the platform template is {{resource.defaultDatasetId}}). A nested webhook id is not read, and that input finishes without a failed run.
Pricing and limits
A probe costs $0.003. A transform costs $0.01 per started minute of that file, minimum one minute, and the row's billed_units shows how many events were charged.
A transform of a file with no duration is refused instead of being billed as one minute.
Set maxTotalChargeUsd to at least $0.0031. A lower cap is rejected before the run starts, even though one probe at 1024 MB is $0.00305 in events.
2026-09-23: First version (0.1.0)
This version was not yet on the Apify Store. The event prices were provisional until an Apify Cloud cost benchmark was done.
Features
Process up to 100 direct video or audio URLs in one run. Each file gets its own status row.
Successful probe JSON, speech audio, thumbnails, remuxes and analysis proxies are stored in the run Key-Value Store.
A file that fails releases its price reservation, so another file in the same run can still succeed inside maxTotalChargeUsd.
Remux and proxy results are accepted only after ffprobe can read them, and a proxy wider than maxWidth is PROCESSING_FAILED.
Pricing and limits
At the default 2048 MB the platform billed two start events, so the smallest cap that could finish one probe was $0.00110.