4

I'm processing a variety of audio files in a bunch of different formats and I'd like to unify their format and configuration using FFMPEG and SoX.

There are two steps to my process:

  1. Convert the file, whatever it may originally be, to a PCM 16-bit little-endian WAV file:
    ffmpeg -i input.wav -c:a pcm_s16le output.wav
  2. Process the file in Sox to make it conform to the sample rate and channel count that we need:
    sox input.wav output.flac channels 2 rate 44.1k

I'd ideally like to pipe these two commands together so as to avoid creating an unnecessary file.

I'm having a lot of trouble actually getting the format to work properly, though.

SoX complains that it needs to explicitly know the format of the incoming audio, which is something that I don't even know at execution time. I know the format of the PCM audio, but I'm not sure the channel count nor of the sample rate of the incoming audio.

Is there a way to pipe these two commands together, or better, to only have to use one tool for the job?

The reason I've used two tools rather than just trying to do it with one:

FFMPEG

  • Not sure if there's a way to safely convert a mono audio stream to a stereo audio stream by duplicating the channels. (SoX does this natively.)
  • Not sure how to change sample rate. (SoX does this natively.)
  • Not sure how to output to FLAC using the best compression rate.

SoX

  • Not able to do audio format detection as well as FFMPEG does. If I have a file without an extension, SoX asks me to manually specify the format, which doesn't work at all for my application.
4
  • How are the commands chained? You've posted two independent commands. Did you mean sox output.wav …? Commented Nov 5, 2013 at 22:51
  • Yes. I'd like to do something like ffmpeg {params} | sox {params} if possible. I currently use ffmpeg to create a file named output-standardized.wav and then have sox use this file to create a file named output-fixed.flac. Commented Nov 5, 2013 at 23:32
  • Sox only uses the file name to determine the file format if it can't do it from the file header. Are you sure that ffmpeg is really doing more detection than sox and not just applying some default that happens to be ok for your test case? Commented Nov 5, 2013 at 23:39
  • Yep, pretty sure. FFMPEG looks into the file structure to form a more educated guess as to the stream type(s). Commented Nov 5, 2013 at 23:41

2 Answers 2

3

Decode with FFmpeg, pipe with the sox format to avoid format detection issues, output in 16 bits with level 8 FLAC compression.

ffmpeg -hide_banner -i input.wav -f sox - |
 sox -t sox - -b 16 -C 8 output.flac channels 2 rate 44.1k
1
  • example for a ffmpeg | sox | ffmpeg pipe: ffmpeg -hide_banner -i src.ac3 -f sox - | sox -t sox - -t sox - speed $(echo 24 25 | awk '{ print $1/$2 }') | ffmpeg -f sox -i - -c ac3 -b:a 192k -y dst.ac3 as a workaround for missing rubberband filter in ffmpeg: ffmpeg -i src.ac3 -af rubberband=tempo=24/25 -c ac3 -b:a 192k -y dst.ac3
    – milahu
    Commented Nov 15, 2023 at 9:32
1

I think sox needs to seek its input if it is to determine the input format from the file's header, and that's incompatible with a pipe.

I think ffmpeg can do all you want, though I'm not completely sure. I'm unfamiliar with it and the documentation is clear as mud.

ffmpeg -i "$input" -compression_level 9 -ac 2 -ab 44100 output.flac

Alternatively, mencoder should be able to do a similar job.

mencoder "$input" -oac lavc -lavcopts=acodec=flac:abitrate=44.1:o=compression_level=9 -af channels=2 output.flac
2
  • Yeah, the documentation really is as clear as mud. In the end, I'm just using my temporary file. Commented Nov 24, 2013 at 3:05
  • "I think ffmpeg can do all you want" - not if i want the rubberband filter for timestretch, but ffmpeg was compiled without librubberband, then i have to pipe ffmpeg | sox | ffmpeg or ffmpeg | rubberband | ffmpeg
    – milahu
    Commented Nov 15, 2023 at 9:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .