Reputation: 1
I have random bytes of data which I need to convert to mp3 format(although it might be noise). And I should be able to play the (noisy) mp3 file.
from pydub import AudioSegment
from pydub.playback import play
import io
data=open("cipher.json","rb").read()
recording = AudioSegment.from_file(io.BytesIO(data), format="mp3")
recording.export('new.mp3', format='mp3') # for export
play(recording) # for play
Error is as follows:
Traceback (most recent call last):
File "temp.py", line 17, in <module>
recording = AudioSegment.from_file(io.BytesIO(data), format="mp3")
File "/home/shreyas/.local/lib/python3.6/site-packages/pydub/audio_segment.py", line 704, in from_file
p.returncode, p_err))
pydub.exceptions.CouldntDecodeError: Decoding failed. ffmpeg returned error code: 1
Output from ffmpeg/avlib:
b"ffmpeg version 3.4.4-0ubuntu0.18.04.1 Copyright (c) 2000-2018 the FFmpeg developers\n built with gcc 7 (Ubuntu 7.3.0-16ubuntu3)\n configuration: --prefix=/usr --extra-version=0ubuntu0.18.04.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --disable-stripping --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband --enable-librsvg --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libopencv --enable-libx264 --enable-shared\n libavutil 55. 78.100 / 55. 78.100\n libavcodec 57.107.100 / 57.107.100\n libavformat 57. 83.100 / 57. 83.100\n libavdevice 57. 10.100 / 57. 10.100\n libavfilter 6.107.100 / 6.107.100\n libavresample 3. 7. 0 / 3. 7. 0\n libswscale 4. 8.100 / 4. 8.100\n libswresample 2. 9.100 / 2. 9.100\n libpostproc 54. 7.100 / 54. 7.100\n[mp3 @ 0x564e0e6d4fa0] Header missing\n[mp3 @ 0x564e0e6d3900] decoding for stream 0 failed\n[mp3 @ 0x564e0e6d3900] Could not find codec parameters for stream 0 (Audio: mp3, 0 channels, s16p): unspecified frame size\nConsider increasing the value for the 'analyzeduration' and 'probesize' options\nInput #0, mp3, from 'pipe:':\n Duration: N/A, start: 0.000000, bitrate: N/A\n Stream #0:0: Audio: mp3, 0 channels, s16p\nStream mapping:\n Stream #0:0 -> #0:0 (mp3 (native) -> pcm_s16le (native))\n[mp3 @ 0x564e0e6d72e0] Header missing\nError while decoding stream #0:0: Invalid data found when processing input\nFinishing stream 0:0 without any data written to it.\n[abuffer @ 0x564e0e6dba80] Value inf for parameter 'time_base' out of range [0 - 2.14748e+09]\n Last message repeated 3 times\n[abuffer @ 0x564e0e6dba80] Error setting option time_base to value 1/0.\n[graph_0_in_0_0 @ 0x564e0e6db980] Error applying options to the filter.\nError configuring filter graph\nConversion failed!\n"
Upvotes: 0
Views: 5182
Reputation: 960
This works for me
import base64
from pydub import AudioSegment
import io
base_64_string = "AAAAIGZ0eXBpc29tAAAAAGlzbzhtcDQxZGFzaGNtZmMAAAP7b" # And more ...
def base64_from_string(string : str):
return base64.b64decode(string)
def export_mp3_from_base64(b : bytes):
# Do not specify `AudioSegment` `format` property
audio_segmant = AudioSegment.from_file(io.BytesIO(b))
# Export the audio file
audio_segmant.export('new.mp3', format='mp3')
export_mp3_from_base64(base64_from_string(base_64_string))
Upvotes: 0
Reputation: 1027
As others have indicated, the issue here is that you've selected format=mp3
so you're telling ffmpeg (that pydub
uses as a dependency) to encode/decode mp3s to process your json
file - which it doesn't understand.
From the pydub API Documentation: for AudioSegment(…).from_file()
Supported keyword arguments:
format
| Supports"wav"
and"raw"
natively, requires ffmpeg for all other formats.
"raw"
files require 3 additional keyword arguments,sample_width
,frame_rate
, andchannels
, denoted below with: raw only. This extra info is required because raw audio files do not have headers to include this info in the file itself like wav files do.
If you are attempting to read non audio files as audio you need to change the format to format=raw
However, opening non audio files as raw audio can break your speakers, and/or hurt your ears. I would suggest both removing the DC offset and scaling down the volume as a precaution. Depending on the input data you may get sharp digital noise or nothing at all.
For example, you can try:
from pydub import AudioSegment
from pydub.playback import play
import io
data=open("cipher.json","rb").read()
recording = AudioSegment.from_file(io.BytesIO(data), format="raw",
frame_rate=44100, channels=2,
sample_width=2).remove_dc_offset()
# AudioSegments are immutable so we create a new one that is 3.5dB quieter
quieter = recording - 3.5
quieter.export('new.mp3', format='mp3') # for export
play(quieter) # for play
You will need to experiment with these parameters:
sample_width
| Use1
for 8-bit audio2
for 16-bit (CD quality) and4
for 32-bit.
channels
|1
for mono,2
for stereo.
frame_rate
| Also known as sample rate common values are44100
(44.1kHz - CD audio), and48000
I would also suggest unpacking the key value pairs from your json
file and converting those to bytes (unless there’s something in the json structure you want to try to use) or experimenting with other file types to import. It is likely you will not hear the results you are expecting, experimentation is key.
Upvotes: 0
Reputation: 3123
this is how i got audio in byte strings format, recorded in python using 'speech_recognition` package:
import speech_recognition as sr
recognizer = sr.Recognizer()
with mic as source:
recognizer.adjust_for_ambient_noise(source)
captured_audio = recognizer.record(source=mic, duration=30)
audio_file = captured_audio.get_wav_data(convert_rate=44100)
this is I converted it to .wav file:
(your audio may be a class and a method of it may have actual bytestring data of your audio, which is the case with me)
import io
audio_in_bytestring = captured_audio.get_wav_data(convert_rate=44100)
recording = AudioSegment.from_file(io.BytesIO(audio_in_bytestring), format="wav")
recording.export("about_speech_recognition.wav", format="wav")
Upvotes: 0
Reputation: 379
Try this
from pydub import AudioSegment
from pydub.playback import play
import io
recording = AudioSegment.from_file(io.BytesIO(<put bytes here>), format="mp3")
recording.export('new.mp3', format='mp3') # for export
play(recording) # for play
Upvotes: 4