Search code examples
pythonmp3id3mutagen

How to corrupt mp3 files without altering general informations


I need to make some MP3 available on the internet for educational purpose. And I don't want it to be illegally downloaded. Thus I want to corrupt the MP3 files in such a way as to make them musically unreadable in other media players.

Problem:
I need to keep the metadata untouched (length, tags, etc) because I need to use mutagen.mp3 and mutagen.id3 on those MP3 files.

I did not try anything yet. I was wondering if anyone had an idea on how to do this?


Solution

  • It's been a long while (years) since I cared to work with MP3 bytes so double-check the frame-size numbers in my advice below. If you try something based on my guidance I can help fix any issues.

    note:
    Use a Hex editor to see the inside of an MP3 and follow the bytes structure as explained below.

    Possible solution:

    If your MP3 file has metadata then it's actually two sections joined up...
    (ie: ID3 metadata + MP3 audio data).

    ID3 editors only care about the first section so that part can be edited without affecting the audio.

    The first section is ID3 metadata which begins with 3 bytes of text "ID3" (or bytes: 49 44 33).
    It will have a size (bytes length) listed in the bytes, so you can skip past the ID3 to the start of MP3.

    The second section is MP3 data which begins with 2 bytes of numbers 255 251 (or bytes: FF FB).

    The two bytes FF FB are the typical start of an MP3 frame (MP3 frame header has 4 bytes eg: FF FB XX XX). The XX parts will depend on the MP3 settings like its frequency, bitrate, version, etc.

    To corrupt the MP3 data you could try:

    • Make sure your MP3 files are encoded as constant bitrate or CBR, (not Variable bitrate, or VBR).
      This makes it easier to locate the start of each MP3 frame. Every frame will have a matching FF FB XX XX signature. They will all be the same size so, once you know bytes length from checking first frame, you can skip by that same number to reach next (or any) MP3 frame's start (eg: you can use multiply to reach a specific frame number).

    • To find an MP3 frame's bytes length: See my Answer to a similar Question.
      The formula is FrameSize = 144 * BitRate / (SampleRate + Padding) (CBR = zero padding).
      example : (bitrate=192, sampleRate=44.1 khz)
      144 * 192 / (44.1 + 0) = 626 bytes per audio frame.

    • Replace every FF FB at each frame's start with random bytes like AA AA or even AB CD ... If no longer the expected FF FB then an MP3 player should refuse to play it, giving an error like: "Invalid MP3 file".

    • Later your own app can always put back (replace) the current 2 bytes with the expected FF FB and then do audio playback. You do this un-corruption by skipping past ID3 bytes to get to the first frame's position and replace the found first two bytes as FF FB.