How to strip id3 tags from many mp3s with the server-safe path
- Step 1Confirm the Ghoster is server-safe and pick a tier — Audio ID3 Ghoster is in the server-safe security set, so the runner returns base64 rather than a browser download. The tool's minimum tier is Pro; for unlimited batch slots and a 2 GB per-file limit, use Developer. Pro caps at 100 MB / 5 slots, Pro-media at 500 MB / 50.
- Step 2Enumerate your input files — Build the list of
.mp3files to clean. The runner processes one file per call, so your loop iterates the folder and POSTs each file individually — there is no single multi-file request. - Step 3POST each file to the runner — Send the MP3 bytes for tool id
audio-id3-ghoster. The runner runsstripId3Tagsserver-side: ID3v2 at the start (synchsafe size), then APEv2/ID3v1/Lyrics3 at the end, returning only the audio between. - Step 4Parse the JSON response — The response is JSON with
outputBase64,inputBytes,outputBytes,removedBytes, andmime: "audio/mpeg". ReadremovedBytesfor your audit log; it is the total tag weight removed from that file. - Step 5Decode and write the cleaned file — Base64-decode
outputBase64into binary and write it as<name>-tagless.mp3. The bytes are anaudio/mpegstream with every recognized tag region removed; play one to confirm. - Step 6Verify a sample — Spot-check a few outputs: run them through hex-header-inspector and confirm the first bytes are an MPEG frame sync (
FF Fx), notID3. Hash a before/after pair with multi-hash-fingerprinter to confirm only metadata changed.
Server-safe response fields
The JSON returned by the runner for tool id audio-id3-ghoster. These are the exact keys your script reads.
| Field | Type | Meaning |
|---|---|---|
outputBase64 | string | The cleaned MP3 binary, base64-encoded — decode to recover the file |
inputBytes | number | Size of the original file in bytes |
outputBytes | number | Size of the cleaned (tagless) file in bytes |
removedBytes | number | inputBytes minus outputBytes — total tag weight removed |
mime | string | Always audio/mpeg |
Tier capacity for batch work
Per-file size limit and batch slots by tier. The runner processes one file per call regardless; batch slots govern the interactive dropzone.
| Tier | Per-file limit | Batch slots | Best for |
|---|---|---|---|
| Free | Blocked | n/a | Cannot run the Ghoster at all |
| Pro | 100 MB | 5 | Small folders, occasional cleanup |
| Pro-media | 500 MB | 50 | Seasons of episodes, larger files |
| Developer | 2 GB | unlimited | Full archives, automated pipelines |
Browser run vs server-safe path
Same strip logic, different delivery. Pick the path that matches your workload.
| Aspect | Browser run | Server-safe path |
|---|---|---|
| Files per invocation | First file only | One file per call (loop for many) |
| Output | Downloadable audio/mpeg blob | JSON with outputBase64 |
| Metrics returned | inputBytes, outputBytes, durationMs | inputBytes, outputBytes, removedBytes, mime |
| Where bytes live | In-page, never uploaded | Processed by the JAD runner |
Cookbook
Batch patterns against the server-safe path. The strip is identical to the browser; only the orchestration differs.
Loop a folder and write tagless copies
The core pattern: iterate files, POST each, decode the base64, write the cleaned file. One call per file because the runner processes a single input.
for each file in ./demos/*.mp3: resp = POST file to runner (tool: audio-id3-ghoster) data = parse JSON resp bytes = base64_decode(data.outputBase64) write bytes to ./clean/<name>-tagless.mp3 print name, data.removedBytes
Audit how much metadata each file carried
Because the response includes removedBytes, you can build a report of metadata weight per file and total it — useful for proving a library was anonymized.
totals = 0
for each file:
data = strip(file)
totals += data.removedBytes
log { name, inputBytes: data.inputBytes,
removedBytes: data.removedBytes }
print "total metadata removed:", totals, "bytes"Skip files that had nothing to strip
A file with no ID3/APE/Lyrics3 markers returns removedBytes near zero. Detect that to flag already-clean files instead of rewriting them.
data = strip(file) if data.removedBytes == 0: log skip(name, "already tagless") else: write base64_decode(data.outputBase64) log cleaned(name, data.removedBytes)
Verify a sample with a hash diff
To prove only metadata changed, the audio payload of input and output should match once tags are excluded. A practical check: hash the cleaned file, then re-run the strip on it and confirm it is now a no-op (removedBytes 0).
clean = strip(original) # removedBytes = 4278 write original-tagless.mp3 recheck = strip(original-tagless) # removedBytes = 0 assert recheck.removedBytes == 0 # idempotent: nothing left
Respect the per-file limit in the loop
On Pro the per-file cap is 100 MB. Guard the loop so an oversized file is routed to a higher-tier run rather than failing the batch.
for each file:
if size(file) > tier_limit: # 100MB Pro / 500MB Pro-media / 2GB Dev
queue_for_higher_tier(file)
continue
data = strip(file)
write base64_decode(data.outputBase64)Edge cases and what actually happens
Empty input sent to the runner
Error: no fileLike the browser path, the strip requires a file. An empty or missing input throws "No file provided." Validate each file exists and is non-empty before POSTing.
Caller below the Pro tier
Rejected: plan requiredThe Ghoster's minimum tier is Pro. A Free-tier caller is rejected with "Audio ID3 Ghoster requires the pro plan" before any file is processed. Run the batch under a Pro or higher account.
A file in the batch exceeds the per-file limit
Rejected: too largePer-file limits are 100 MB (Pro), 500 MB (Pro-media), 2 GB (Developer). One oversized file is rejected; guard the loop so it does not abort the whole run — route it to a higher tier or skip with a logged warning.
File already has no tags
By designNo ID3 magic and no trailing TAG/APETAGEX/LYRICS200 markers means nothing matches; the response carries the file essentially unchanged with removedBytes near zero. Use that to skip rewriting already-clean files.
Re-stripping an already-tagless file
IdempotentRunning the strip on a -tagless.mp3 is a no-op: there are no tags left, so removedBytes is 0 and the bytes come back unchanged. The operation is safe to repeat, which simplifies retry logic in a pipeline.
Non-MP3 file slips into the batch
Wrong toolA WAV/FLAC/M4A file does not use ID3/APE/Lyrics3 structures, so the marker scan finds little and the output is not a cleaned version of that format. Filter the batch to .mp3 (confirm with magic-byte-validator) before stripping. For MP4-container audio, use /video-tools/metadata-scrubber.
Album art dominates removedBytes for some files
ExpectedFiles with embedded APIC cover art show large removedBytes (100-500 KB) while text-only files show a few KB. This variance is normal — the figure reflects how much metadata each file actually carried, art included.
Lyrics3 footer with a corrupt size in a batch file
PreservedIf a file's Lyrics3v2 footer has a non-numeric or implausible 6-digit size, the lyrics block is left in place rather than risk cutting audio; ID3v1 is still trimmed. The file is still processed — just with that one block retained — so the batch continues.
ID3v2 footer present on some files
ExpectedThe leading tag size is taken from the synchsafe size at bytes 6-9 only; the rare ID3v2 footer flag adds 10 bytes not subtracted, so a few footer bytes can remain at the front of those files. Harmless to playback; the audio is intact.
Truncated file in the batch
ExpectedIf an ID3v2 synchsafe size overruns a truncated file, the computed audio start lands at or past the end and the output is tiny or empty. Flag any output whose outputBytes is implausibly small relative to inputBytes and re-fetch the source.
Frequently asked questions
Can the Ghoster process a whole folder in one request?
No — the runner processes one file per call, and the browser run strips only the first dropped file. To clean many MP3s, loop your file list and POST each one to the server-safe path, decoding outputBase64 from each response. There is no single multi-file request.
Is the server-safe strip the same as the browser one?
Yes. Both call the identical stripId3Tags logic — ID3v2 at the start via the synchsafe size, then APEv2, ID3v1, and Lyrics3v2 at the end — and copy the MPEG audio frames unchanged. The only difference is delivery: the browser returns a download, the runner returns JSON with outputBase64.
What does the server-safe response contain?
JSON with five fields: outputBase64 (the cleaned binary, base64-encoded), inputBytes, outputBytes, removedBytes (input minus output), and mime (always audio/mpeg). Decode outputBase64 to recover the file; read removedBytes for auditing.
How do I recover the cleaned MP3 from the response?
Base64-decode the outputBase64 string into binary and write it to disk as <name>-tagless.mp3. The result is an audio/mpeg stream with every recognized ID3/APE/Lyrics3 region removed and the audio frames intact.
How can I tell which files actually had metadata?
Check removedBytes in each response. A value near zero means the file had no ID3/APE/Lyrics3 markers and was already clean; a large value (often 100-500 KB) usually means embedded album art was removed. Logging this field gives you a per-file metadata audit.
What tier should I run a batch under?
Pro is the minimum (Free is blocked). For large archives use Developer: it raises the per-file limit to 2 GB and batch slots to unlimited. Pro caps at 100 MB / 5 slots and Pro-media at 500 MB / 50 — the per-file limit is the one that matters for the runner.
Is re-running the strip safe?
Yes — it is idempotent. A file with no tags left returns removedBytes 0 and unchanged bytes, so re-stripping a -tagless.mp3 is a no-op. That makes retry logic simple: a failed write can be retried without double-stripping audio.
Does it re-encode audio during batch processing?
No. Every file is sliced with buf.slice(start, end) to keep only the MPEG audio frames; nothing in the audio stream is re-encoded. Across the whole batch, bitrate, sample rate, and audio bytes are preserved — only metadata is removed.
How do I keep one bad file from failing the whole batch?
Guard each iteration: validate the file is a non-empty .mp3 within your tier's per-file limit before POSTing, and handle the "no file", "too large", and "requires the pro plan" cases per file. An oversized or non-MP3 file should be logged and skipped, not abort the loop.
How do I verify the batch output is correct?
Spot-check samples: run a cleaned file through hex-header-inspector and confirm it opens on an MPEG frame sync (FF Fx), not ID3. Re-strip a cleaned file and confirm removedBytes is 0. Hash before/after with multi-hash-fingerprinter to confirm only metadata changed.
What about non-MP3 audio in the batch?
Filter it out first. WAV/FLAC/M4A do not use ID3/APE/Lyrics3 structures, so the strip would not produce a cleaned version of those formats. Confirm types with magic-byte-validator; for MP4-container audio use the video metadata scrubber at /video-tools/metadata-scrubber.
Which other JAD security tools fit an automated pipeline?
office-doc-property-wiper is also server-safe and strips author/comments from .docx/.xlsx/.pptx, so a doc+audio pipeline can share orchestration. Use magic-byte-validator to gate inputs and multi-hash-fingerprinter to checksum outputs.
Privacy first
Every JAD Security operation runs entirely in your browser. Files, passwords, and PGP private keys never leave your device — verified by zero outbound network requests during processing.