29

I am trying to use ffmpeg to decode audio data. While it works to load from a file, I would like to avoid using files because to do so, means I would have to use a temporary. Instead, I'd like to pipe in the data(which I've previously loaded) using stdin.

Is this possible?

e.g.,

  1. Manually load mp3 file
  2. Pipe it in to the ffmpeg spawned process
  3. Get raw output

(it should work with ffprobe and ffplay also)

med benzekri
  • 490
  • 6
  • 19
AbstractDissonance
  • 1
  • 2
  • 16
  • 31

4 Answers4

35

ffmpeg has a special pipe flag that instructs the program to consume stdin. note that almost always the input format needs to be defined explicitly.

example (output is in PCM signed 16-bit little-endian format):

cat file.mp3 | ffmpeg -f mp3 -i pipe: -c:a pcm_s16le -f s16le pipe:

pipe docs are here
supported audio types are here

MrBar
  • 950
  • 6
  • 15
10

- is the same as pipe:

I couldn't find where it's documented, and I don't have the patience to check the source, but - appears to be the exact same as pipe: according to my tests with ffmpeg 4.2.4, where pipe: does what you usually expect from - in other Linux utilities as mentioned in the documentation of the pipe protocol:

If number is not specified, by default the stdout file descriptor will be used for writing, stdin for reading.

So for example you could rewrite the command from https://stackoverflow.com/a/45902691/895245

ffmpeg -f mp3 -i pipe: -c:a pcm_s16le -f s16le pipe: < file.mp3

a bit more simply as:

ffmpeg -f mp3 -i - -c:a pcm_s16le -f s16le - < file.mp3

Related: What does "dash" - mean as ffmpeg output filename

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
6

I don't have enough reputation to add a comment, so...

MrBar's example

ffmpeg -i file.mp3  -c:a pcm_s16le -f s16le pipe: | ffmpeg -f mp3 -i pipe: -c:a pcm_s16le -f s16le encoded.mp3

should read,

ffmpeg -i file.mp3  -c:a pcm_s16le -f s16le pipe: | ffmpeg -f s16le -i pipe: -f mp3 encoded.mp3
otacky_taka
  • 121
  • 1
  • 7
0

Since you have to set the incoming stream's properties - and you may not feel like it - here's an alternative that I've used: use a fifo or a pipe (not the one mentioned above).

Here is an example using wget as a stream source, but cou can use anything, cat, nc, you name it:

$ mkfifo tmp.mp4 # or any other format
$ wget -O tmp.mp4 https://link.mp4 &
$ ffmpeg -i tmp.mp4 YourFileHere.mp4

Finally you may want to delete the pipe - you remove it like a normal file:

$ rm tmp.mp4

Voila!

Michał Leon
  • 2,108
  • 1
  • 15
  • 15