Java execute ffmpeg commands with (pipe) "... -f nut - | ffmpeg -i - ..." just hangs

The pipe will not be interpreted when passed directly in a command this way, it will be just another argument to the first ffmpeg at the beginning of your command. Consider using /bin/sh -c "command1 | command2" as wrapper (assuming non-Windows OS...).

Consider adding -nostdin to first ffmpeg command to avoid a number of issues with ffmpeg trying to read stdin when you're not expecting it to (not in second one obviously).

Consider using String.format to build complex strings with variables.

Consider using ProcessBuilder for easier process creation. Here I'm redirecting errors so they end up to your java process stderr, so you can read your child process's stdout without using a thread. See alternatives

So here is a suggestion:

public static void main(String[] args) throws IOException, InterruptedException {
    String INPUT_FILE = "/path/to/media";
    String FFMPEG_PATH = "/path/to/ffmpegFolder";

    for (int i = 0; (i + 4) < 40; i += 4) {

        String command1 = String.format(
                "%s/ffmpeg_4.1.1 -nostdin -ss %d -t 4 -i '%s' -ac 1 -acodec pcm_s16le -ar 16000 -f nut -",
                FFMPEG_PATH, i, INPUT_FILE);

        String command2 = String.format(
                "%s/ffmpeg_4.1.1 -i - -lavfi showspectrumpic=s=128x75:legend=disabled:saturation=0:stop=8000",
                FFMPEG_PATH);

        Process process = new ProcessBuilder("sh", "-c", command1 + " | " + command2)
                .redirectError(ProcessBuilder.Redirect.INHERIT)
                .start();

        BufferedImage image = ImageIO.read(process.getInputStream());
        // ...
    }
}