CLI to python code

Well, how is that?
This should be subprocessed:

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

Can you show an example of a command line, how ffmpeg is able to receive data from some input stream?
Because in the original shell string, ffmpeg doesn’t work with the input stream but the path to the file.
First, you need to understand exactly what kind of shell call you want to recreate in python.

Isn’t easy to do

import os
os.system("ffmpeg -y -f f32le -ar 16000 -ac 1 -i pipe: /home/xy/hellomicrophone1.wav")

or if filename is unknown

import os
os.system("ffmpeg -y -f f32le -ar 16000 -ac 1 -i pipe: /home/xy/" variablename)

or am i thinking to simple?

I understand that the goal is to use a command with real stream redirection. And not just do it as it is.

Esp32 sends 32-bit float PCM on UDP. This works well because running the code below from a terminal produces a perfectly good quality .wav file. I want to run this terminal code in python.

nc -l -u 3000 | ffmpeg -y -f f32le -ar 44100 -ac 1 -i pipe: /mnt/usb1/UDP/hellomicrophone.wav

It just happens to have a simple example of streaming data from stdout:

import subprocess

# Running 'ls' command and piping the result to 'grep'
p1 = subprocess.Popen(['ls'], stdout=subprocess.PIPE)
p2 = subprocess.Popen(['grep', 'py'], stdin=p1.stdout, stdout=subprocess.PIPE)

# Close p1's stdout to ensure proper termination of the pipe
p1.stdout.close()

# Reading the output from p2 line by line
with p2.stdout:
    for line in p2.stdout:
        print(line.decode().strip())  # Decode and strip each line before printing

# Wait for p2 to complete
p2.wait()

That’s why I asked you exactly what the original command you want to implement looks like. Above, you were given an example of what it looks like, it’s easy to redo it to what you need.

When I do this I use pipefds = os.pipe() to obtain a pipe. I provide
the read end of the pipe (pipefds[0]) as stdin for the ffmpeg and
the write end of the pipe as stdout for the nc. Which is exactly what
the shell will be doing for the above. After dispatch via Popen the
Python process closes it’s pipe file descriptors.

There are still apis like subprocess.run and olds like subprocess.call, subprocess.check_call, subprocess.check_output. Do they have this behavior too?

They should be fine. The point is to set up a real pipe and hook your
subprocesses to it. My own flows tend to use Popen so that I can kick
things off and collect them at a later point in time, but the
synchronous modes (.run, .call et al) should work fine. I do not
know if .communicate is clever enough to know when eg .stdout is
hooked to a pipe and should be ignored.

Actually, just to this: the trouble with the synchronous calls is that you can’t kick off multiple subprocesses, which is kind of the point of a pipeline. I suppose you could use a Thread for each call, but you still can’t connect them together without some cumbersome data copying mechanism.

Just making a pipe and passing its fds as the appropriate streams to Popen works well.

This was the correct solution, but I found another solution:

ffmpeg_cmd = [
    'ffmpeg',
    '-y',                  # Overwrite output files without asking
    '-f', 'f32le',         # Input format: 32-bit float little-endian PCM
    '-ar', '44100',        # Input sample rate: 44100 Hz
    '-ac', '1',            # Input channels: 1 (mono)
    '-i', 'pipe:',         # Input comes from a pipe
    '/home/xy/microphone.wav'
]
 
ffmpeg_proc = subprocess.Popen(ffmpeg_cmd, stdin=subprocess.PIPE)

A simpler solution:

import numpy as np
....
        pcm_data = np.frombuffer(data, dtype=np.float32)
        frames.append(pcm_data)

But weren’t you talking about the other command?