0

Say you have an MP3 file and it's 60,000,000 bytes, and you also have an MP3 advertisement that's 500,000 bytes, both encoded at the same bit rate.

Would it be possible using an nginx or apache module to change the MP3 "Content-Length" header value to 60,500,000 and then control the incoming "Content-Range" requests so the first 500,000 bytes return the advertisement audio, and any range request greater than 500,000 begins returning the regular audio file with a 500,000 byte offset?

Or is it only possible to splice advertisements (or messages) into an MP3 file using an application such as FFmpeg to re-render the entire file?

Apologies if this is a stupid question, I'm just trying to think outside of the box.

Adam
  • 836
  • 2
  • 8
  • 13
  • Technically yes as MP3 is a streaming format. You may get glitches and pops if you don’t make sure to cut it at the correct full frame. MP3 is pretty tolerant to being cut up and spliced. For best results make sure all segments are the same bitrate – Matthew Whited Aug 18 '19 at 23:14

1 Answers1

1

You cannot arbitrarily splice MP3 without artifacts and decoder errors.

You also generally cannot cut/splice MP3 on frame boundaries due to the Bit Reservoir. Basically, a particular MP3 frame may contain data from another frame to more efficiently use the available bandwidth when its needed. Ignoring the bit reservoir can also cause artifacts and/or decoder errors.

What you can do is re-encode your advertisement and eventually re-join the stream. That is, at the point of ad insertion, decode the stream to PCM, mix (or replace in the audio) for your ad, and have this parallel stream re-encoded to PCM. If the encoding parameters are the same, eventually (after a couple of extra MP3 frames), you'll have identical bitstreams, and you can go back to reading the stream from the same buffer.

If you're doing this for ad-insertion on internet radio (live) streams, keep in mind that you'll have to do this on the server for every client (or at least, for each ad variant and timing variant). If this is for podcasts or other pre-recorded content, I'd recommend the FFmpeg route. You won't have to build anything, you can stream and cache the output as its being encoded, and you'll have compatibility with other codecs without building one-off code for each codec/container.

Brad
  • 159,648
  • 54
  • 349
  • 530
  • Thank you for your detailed answer. It would be for podcasts, and I didn't realise you could stream and cache the output whilst it's being encoded, that's very useful to know. I'll start experimenting with FFmpeg and see what I can come up with. Thanks again for sharing your knowledge, it's much appreciated :) – Adam Aug 18 '19 at 23:36
  • 1
    @Adam Sure, no problem! Also, to be clear, I don't know of any off-the-shelf Apache or Nginx modules that do this for you. You'll have to build one or at least script something with the Nginx Lua module. Or, write your own application server that you proxy to. If you're interested, I have code in the form of a Node.js application you can license for your purpose. E-mail me at brad@audiopump.co if you're interested in that. – Brad Aug 18 '19 at 23:50
  • I have quite a bit of experience with Nginx, but I'll make a note of your email if I can't come up with a solution of my own. Thanks again! – Adam Aug 18 '19 at 23:55
  • 1
    @Adam Sounds good. Also, the FFmpeg option for STDIO is just a hyphen `-` instead of the input or output file. And, if at all possible, use Opus. Better sound quality, no licensing issues, streamable in WebM or Ogg. – Brad Aug 19 '19 at 00:04