8

Is there a way to play mp3 from bytes directly using python? If not, can I convert the binary to a different audio format and make the binary playable?

Edit: The following code works for wav files but not mp3

from pygame import mixer, time

mixer.pre_init(44100, -16, 2, 2048)
mixer.init()

data = open('filename.mp3', 'rb').read()
sound = mixer.Sound(buffer=data)

audio = sound.play()
while audio.get_busy():
    time.Clock().tick(10)

Edit: The problem has been solved, see my answer below if you're facing a similar issue

tushar
  • 741
  • 1
  • 8
  • 21
  • Just to clarify, you have a file in .mp3 format and you want to play it using Python? And what operating system are you using? – cameronroytaylor May 12 '17 at 16:20
  • I don't, I'm streaming mp3 binary and I don't want to write it to disk. I'm using mac but a solution for linux is also fine. – tushar May 12 '17 at 16:21
  • 1
    Just to clarify when you say binary, is it an array of amplitudes, or is it actually in mp3 format? And when you say streaming, do you mean it has to be done in real-time? – cameronroytaylor May 12 '17 at 16:25
  • Not sure how to do this in real-time, but if you find that you can write short snippets to disk, maybe you could use `os.system("afplay path/temp.mp3")`. Might need more detail to get a more helpful answer. – cameronroytaylor May 12 '17 at 16:41
  • Yes, it's done in real time and I want to play audio after receiving a few thousand bytes. Sorry, I shouldn't be using the word binary. It's actual mp3 formatted bytes. – tushar May 12 '17 at 16:41
  • 1
    I'm using afplay and tempfiles currently but I want to do it without having to save to disk like I mentioned. – tushar May 12 '17 at 16:42
  • You might be able to put the data in a `StringIO` or `BytesIO` instance and pass that to whatever plays mp3s like it was a file. – martineau May 12 '17 at 16:47
  • That's what I want to find – tushar May 12 '17 at 16:56

2 Answers2

16

For anyone who might be facing a similar problem, this works

from pydub import AudioSegment
from pydub.playback import play
import io

data = open('filename.mp3', 'rb').read()

song = AudioSegment.from_file(io.BytesIO(data), format="mp3")
play(song)
tushar
  • 741
  • 1
  • 8
  • 21
3

I saw your pygame tag, so I'll to do this in pygame. Pygame can load files from bytes with this line: sound = pygame.mixer.Sound(bytes) or sound = pygame.mixer.Sound(buffer=bytes). I can't guarantee this will work with mp3 files, though, you may need to use OGG or WAV files, as bytes.

makeworld
  • 1,266
  • 12
  • 17
  • I've added a code snippet in my post. This works for `wav` but `mp3` files sound corrupted. – tushar May 13 '17 at 07:36