[英]How can I convert any random byte string to a playable mp3 file in python3.6?
I have random bytes of data which I need to convert to mp3 format(although it might be noise).我有随机字节的数据,我需要将其转换为 mp3 格式(尽管它可能是噪音)。 And I should be able to play the (noisy) mp3 file.我应该能够播放(嘈杂的)mp3 文件。
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"
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
this is how i got audio in byte strings format, recorded in python using 'speech_recognition` package:这就是我如何获得字节字符串格式的音频,使用“speech_recognition”包记录在 python 中:
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:这是我将其转换为 .wav 文件:
(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")
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.正如其他人所指出的,这里的问题是您选择了format=mp3
所以您告诉ffmpeg ( pydub
用作依赖项)编码/解码format=mp3
以处理您的json
文件 - 它不理解。
From the pydub API Documentation : for AudioSegment(…).from_file()
来自 pydub API 文档:对于AudioSegment(…).from_file()
Supported keyword arguments:支持的关键字参数:
format
|format
| Supports"wav"
and"raw"
natively, requires ffmpeg for all other formats.本机支持"wav"
和"raw"
,所有其他格式都需要 ffmpeg。
"raw"
files require 3 additional keyword arguments,sample_width
,frame_rate
, andchannels
, denoted below with: raw only."raw"
文件需要 3 个额外的关键字参数,sample_width
、frame_rate
和channels
,在下面表示为:仅原始。 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.这个额外的信息是必需的,因为原始音频文件没有像 wav 文件那样在文件本身中包含这个信息的标题。
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.如果您尝试将非音频文件作为音频读取,您需要将格式更改为format=raw
但是,将非音频文件作为原始音频打开会损坏您的扬声器和/或伤害您的耳朵。 I would suggest both removing the DC offset and scaling down the volume as a precaution.作为预防措施,我建议同时去除DC 偏移并缩小音量。 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
|sample_width
| Use1
for 8-bit audio2
for 16-bit (CD quality) and4
for 32-bit.1
表示 8 位音频2
表示 16 位(CD 质量),4
表示 32 位。
channels
|channels
|1
for mono,2
for stereo.1
为单声道,2
为立体声。
frame_rate
|frame_rate
| Also known as sample rate common values are44100
(44.1kHz - CD audio), and48000
也称为采样率的常用值为44100
(44.1kHz - CD 音频)和48000
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.我还建议从您的json
文件中解压缩键值对并将它们转换为字节(除非您想尝试使用 json 结构中的某些内容)或尝试导入其他文件类型。 It is likely you will not hear the results you are expecting, experimentation is key.您可能听不到预期的结果,实验是关键。
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))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.