add the possibility to read aac encoded audio file
azhenone opened this issue · comments
Hi everyone,
I am stuck with an issue, I have many audio files which are in mp4 format with the codec MPEG-4 HE AAC
. They are quite a long files so I use the function stream_file(...)
to read chunks but I get the error ('failed to init decoder', -1)
.
A little investigation shows that it comes from this section of the code
Line 1022 in 55614d3
My understanding is that lib.ma_decoder_init_file(...)
is not able to decode the file. I am not very familiar with audio files codecs so I am not even sure if what I am requesting actually makes sense.
All I know is that I am just too lazy to convert them to mp3 with ffmpeg and that they seem to take less disk space in their current format
I see in this tutorial that there is a way around to use ffmpeg to read a format that is not natively supported.
import subprocess
import miniaudio
channels = 2
sample_rate = 44100
sample_width = 2 # 16 bit pcm
filename = "samples/music.m4a" # AAC encoded audio file
def stream_pcm(source):
required_frames = yield b"" # generator initialization
while True:
required_bytes = required_frames * channels * sample_width
sample_data = source.read(required_bytes)
if not sample_data:
break
print(".", end="", flush=True)
required_frames = yield sample_data
with miniaudio.PlaybackDevice(output_format=miniaudio.SampleFormat.SIGNED16,
nchannels=channels, sample_rate=sample_rate) as device:
ffmpeg = subprocess.Popen(["ffmpeg", "-v", "fatal", "-hide_banner", "-nostdin",
"-i", filename, "-f", "s16le", "-acodec", "pcm_s16le",
"-ac", str(channels), "-ar", str(sample_rate), "-"],
stdin=None, stdout=subprocess.PIPE)
stream = stream_pcm(ffmpeg.stdout)
next(stream) # start the generator
device.start(stream)
input("Audio file playing in the background. Enter to stop playback: ")
ffmpeg.terminate()
I imagine that this strategy could be used. In my case I want 15s long chunks but I am not sure how to make that to work...
I get an error while trying to iterate over the stream object
required_bytes = required_frames * channels * sample_width
TypeError: unsupported operand type(s) for *: 'NoneType' and 'int'
In general: builtin AAC decoding is never going to be available unless it will be in the miniaudio C library, which is highly unlikely. So yes as you discovered, use an external decoder to use this audio file format.
-
can you post the entire stack trace of that last error? I don't know where it's coming from. In any case, one of those three variables is unknown somehow.
-
"i want 15 seconds chunks" this sounds like a file conversion issue rather than playback. While miniaudio contains some rudimentary support for conversion of audio files, I suggest to simply use ffmpeg only to do this task
closing this now.