Hello Everyone!
I would like to ask for your help in converting the following CLI code to python code.
nc -l -u 3000 | ffmpeg -y -f f32le -ar 44100 -ac 1 -i pipe: /home/xy/microphone.wav
I tried this, but it just makes a buzzing sound:
def udp_pcm_to_audio(data):
wav_io = io.BytesIO()
with wave.open(wav_io, 'wb') as wav_file:
p = pyaudio.PyAudio()
wav_file.setnchannels(1)
wav_file.setsampwidth(2)
wav_file.setframerate(44100)
wav_file.writeframes(data)
wav_io.seek(0)
return wav_io
Thank you very much!
For direct conversion into Python
subprocess module can be used.
Quote:The subprocess module allows you to spawn new processes, connect to their input/output/error pipes, and obtain their return codes.
Would that be the solution?:
import subprocess
Popen(nc -l -u 3000 | ffmpeg -y -f f32le -ar 44100 -ac 1 -i pipe: /home/xy/microphone.wav)
i2s microphone, sent over udp. The CLI code captures a perfect sound, I want this in python
Input #0, f32le, from 'pipe:':
Duration: N/A, bitrate: 1411 kb/s
Stream #0:0: Audio: pcm_f32le, 44100 Hz, mono, flt, 1411 kb/s
Stream mapping:
Stream #0:0 -> #0:0 (pcm_f32le (native) -> pcm_s16le (native))
Output #0, wav, to '/home/xy/hellomicrophone.wav':
Metadata:
ISFT : Lavf58.45.100
Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, mono, s16, 705 kb/s
Metadata:
encoder : Lavc58.91.100 pcm_s16le
^Csize= 576kB time=00:00:06.68 bitrate= 705.7kbits/s speed=1.21x
video:0kB audio:576kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.013231%
Exiting normally, received signal 2.
Okay, I almost got it:
command = ['ffmpeg', '-f', 'f32le', '-ar', '16000', '-ac', '1', '-']
subprocess.run(command,stdout=subprocess.PIPE,stdin=subprocess.PIPE)
But how do I transfer the result of this?:
wav_file.writeframes(data)
What is data in your example? Maybe your problem is implementing "nc -l -u 3000" and the "ffmpeg -y -f f32le -ar 44100 -ac 1" you tried to duplicate in udp_pcm_to_audio() works fine. How are you getting "data"?
The data comes from an i2s microphone connected to esp32 via UDP. This code must work well because in putty terminal
nc -l -u 3000 | ffmpeg -y -f f32le -ar 44100 -ac 1 -i pipe: /home/xy/microphone.wav
records perfect sound. (netcat monitors port 3000, ffmpeg overwrites f32le... ect...) My problem in python is that I cannot get pcm_s16le from the received raw pcm_f32le format. At least I think that's the problem. The point is that I want to send a continuous 'sound' to the recognizer in Python.
ESP32 code:
// Send raw audio 32bit float samples over UDP
Udp.beginPacket(outIp, outPort);
Udp.write((const uint8_t*) audio_block_float,bytesIn*2);
Udp.endPacket();
Python:
UDP_IP = "192.168.0.1"
UDP_PORT = 3000
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP, UDP_PORT))
...
def udp_pcm_to_audio(data):
wav_io = io.BytesIO()
with wave.open(wav_io, 'wb') as wav_file:
wav_file.setparams((1, 2, 44100, 0, 'NONE', 'NONE'))
wav_file.writeframes(data)
wav_io.seek(0)
return wav_io
Maybe the ESP32 code should be converted so that it doesn't send the data in 32-bit float? (wifi microphone)
![[Image: 20241019_095955-scaled.jpg]](https://netkor.hu/wp-content/uploads/2024/10/20241019_095955-scaled.jpg)
Well, how is that?
This should be subprocessed:
nc -l -u 3000 | ffmpeg -y -f f32le -ar 16000 -ac 1 -i pipe: /home/xy/hellomicrophone1.wav
But I don't know:
def udp_pcm_to_audio2(data1):
command = ['ffmpeg', '-f', 'f32le', '-ar', '16000', '-ac', '1', '-']
# subprocess.run(command,stdout=udp_pcm_to_audio2(data1),stdin=udp_pcm_to_audio(data))
subprocess.run(command,stdout=subprocess.PIPE,stdin=udp_pcm_to_audio(data))
#return command