How to pipe data losslessly to and from FFmpeg

audioffmpegvideo

I piped a stream from one instance of FFmpeg to another, but because compression was used on the intermediate stream the final result was ugly. I need a lossless pipe to prevent this, and I want it to contain both audio and video.

I suspect that there is more than one answer to this problem, so bonus points go to anyone who provides an exhaustive list of solutions (compatible containers and codecs that can be piped). Bonus points also go to anyone who accounts for other data, like subtitles.

EDIT: I'm looking for suitable codec/container combinations. I don't know why people were having difficulty figuring that out, since I said I already used a pipe and now I need it to be lossless.

I don't know how to explain this without sounding conceited, but this is an FAQ site. Asking questions that require extremely specific answers will not help the millions of users who reach this site by entering their own problems into search engines. My question was designed to help anyone else who needs to losslessly pipe data between FFmpeg instances without distracting everyone with a wall of narrative and code explaining what I was doing, why it didn't work, and why this is the only option.

Best Answer

How to losslessly pipe video and audio from ffmpeg to ffmpeg

Requirements by the question asker:

  • losslessly pipe from one instance of ffmpeg to another
  • it doesn't matter if it's going to and from /dev/null

Example:

ffmpeg -s 1280x720 -f rawvideo -i /dev/zero -ar 48000 -ac 2 -f s16le -i \
/dev/zero -c copy -f nut pipe:1 | ffmpeg -y -i pipe:0 -c copy -f nut /dev/null

I see no reason why anyone would do this. Also, there are very few reasons to pipe from ffmpeg to ffmpeg when you can most likely just use one ffmpeg process to do whatever you want.

What the options do:

  • -s 1280x720 -f rawvideo – Options to describe the input since /dev/zero is not a typical input format and therefore these additional options are required.

  • -i /dev/zero – The video input. It is being used in this example to generate a video stream out of "nothing". This was used in the example because the question asker refused to provide any information about the inputs being used.

  • -ar 48000 -ac 2 -f s16le – Options to describe the input since /dev/zero is not a typical audio format.

  • -i /dev/zero – The audio input. It is being used in this example to generate an audio stream out of "nothing".

  • -c copyStream copy, or re-mux, the inputs to the output. No re-encoding is being performed so the process is lossless. It is unknown if stream copying is acceptable to the question asker or not. Maybe re-encoding is desired instead?

  • -f nut – You need to tell ffmpeg what format to use for the pipe. Nut is a container format. See ffmpeg -formats for a complete list. Another flexible format is -f matroska, but it is impossible to suggest an appropriate or specific output container format to use without more info from the question asker.

  • pipe:1 – Use the pipe protocol to output to stdout. Alternatively, the number can be omitted (just pipe:) and by default the stdout file descriptor will be used for writing and stdin will be used for reading.

Related Question