Frame provides comprehensive audio conversion and processing capabilities, supporting both audio-only formats and audio streams within video files.
Audio-Only Containers
Frame supports the following audio-only container formats:
MP3 Universal lossy audio format
M4A MPEG-4 audio container (AAC/ALAC)
WAV Uncompressed PCM audio
FLAC Lossless audio compression
Audio Codecs
Frame supports both lossy and lossless audio codecs:
Lossy Codecs
Codec Containers Bitrate Description aacmp4, m4a, mov, mkv 64-320 kbps Advanced Audio Coding - universal compatibility ac3mp4, mkv, mov 64-640 kbps Dolby Digital - surround sound support libopuswebm, mp4, mkv 64-256 kbps Opus - best quality at low bitrates mp3mp3, mp4, mkv, mov 64-320 kbps MPEG Audio Layer III - universal
Lossless Codecs
Codec Containers Description alacm4a, mp4, mkv, mov Apple Lossless - iTunes/Apple ecosystem flacflac, mkv, mov Free Lossless Audio Codec pcm_s16lewav, mov, mkv Uncompressed 16-bit PCM
Lossless codecs do not use bitrate settings. The audioBitrate parameter is ignored for flac, alac, and pcm_s16le.
Implementation (codec.rs:57-66):
pub fn add_audio_codec_args ( args : & mut Vec < String >, config : & ConversionConfig ) {
args . push ( "-c:a" . to_string ());
args . push ( config . audio_codec . clone ());
let lossless_audio_codecs = [ "flac" , "alac" , "pcm_s16le" ];
if ! lossless_audio_codecs . contains ( & config . audio_codec . as_str ()) {
args . push ( "-b:a" . to_string ());
args . push ( format! ( "{}k" , config . audio_bitrate));
}
}
Bitrate Configuration
For lossy codecs, configure audio bitrate in kilobits per second:
config . audioCodec = 'aac' ;
config . audioBitrate = '128' ; // kbps
Recommended bitrates by codec:
AAC:
96 kbps - Low quality, podcasts
128 kbps - Standard quality (default)
192 kbps - High quality
256-320 kbps - Very high quality
Opus (libopus):
64 kbps - Speech
96 kbps - Standard quality
128-192 kbps - High quality music
MP3:
128 kbps - Standard quality
192 kbps - High quality
320 kbps - Maximum quality
AC3:
192 kbps - Stereo
384 kbps - 5.1 surround
448-640 kbps - High quality surround
Channel Configuration
Control the output channel layout:
config . audioChannels = 'original' ; // Preserve source channels (default)
config . audioChannels = 'stereo' ; // Downmix to stereo (2.0)
config . audioChannels = 'mono' ; // Downmix to mono (1.0)
Implementation (codec.rs:67-77):
match config . audio_channels . as_str () {
"stereo" => {
args . push ( "-ac" . to_string ());
args . push ( "2" . to_string ());
}
"mono" => {
args . push ( "-ac" . to_string ());
args . push ( "1" . to_string ());
}
_ => {}
}
Downmixing multi-channel audio (5.1, 7.1) to stereo is useful for compatibility with devices that don’t support surround sound.
Audio Track Selection
Many video files contain multiple audio tracks (different languages, commentary, etc.). Frame allows you to select specific tracks:
// Select all audio tracks (default)
config . selectedAudioTracks = [];
// Select specific tracks by index
config . selectedAudioTracks = [ 0 , 2 ]; // Keep tracks 0 and 2, discard others
Track metadata is available in the source file probe data:
interface AudioTrack {
index : number ; // Stream index
codec : string ; // Source codec (e.g., "aac", "ac3")
channels : string ; // Channel layout (e.g., "stereo", "5.1")
language ?: string ; // Language code (e.g., "eng", "spa")
label ?: string ; // Track label/title
bitrateKbps ?: number ; // Source bitrate
sampleRate ?: string ; // Sample rate (e.g., "48000")
}
Validation (args.rs:23-47):
fn collect_selected_audio_tracks <' a >(
config : & ConversionConfig ,
probe : & ' a ProbeMetadata ,
) -> Result < Vec < & ' a AudioTrack >, ConversionError > {
if config . selected_audio_tracks . is_empty () {
return Ok ( probe . audio_tracks . iter () . collect ());
}
config . selected_audio_tracks . iter () . map ( | index | {
probe . audio_tracks . iter ()
. find ( | track | track . index == * index )
. ok_or_else ( || ConversionError :: InvalidInput (
format! ( "Selected audio track #{} was not found in source" , index )
))
}) . collect ()
}
Volume Adjustment
Adjust output volume as a percentage of the original:
config . audioVolume = 100 ; // Original volume (default)
config . audioVolume = 150 ; // Increase by 50%
config . audioVolume = 50 ; // Reduce to 50%
config . audioVolume = 200 ; // Double volume
Implementation (filters.rs:92-95):
if ( config . audio_volume - 100.0 ) . abs () > VOLUME_EPSILON {
let volume_factor = config . audio_volume / 100.0 ;
filters . push ( format! ( "volume={:.2}" , volume_factor ));
}
The VOLUME_EPSILON constant (0.01) prevents applying the filter for negligible changes.
Volume adjustment requires re-encoding. It is not available in stream copy mode.
Audio Normalization
Enable loudness normalization for consistent volume levels:
config . audioNormalize = true ;
Frame uses the loudnorm filter with EBU R128 standards:
Implementation (filters.rs:88-90):
if config . audio_normalize {
filters . push ( "loudnorm=I=-16:TP=-1.5:LRA=11" . to_string ());
}
Parameters:
I=-16 - Integrated loudness target (-16 LUFS)
TP=-1.5 - True peak limit (-1.5 dBTP)
LRA=11 - Loudness range (11 LU)
Normalization is especially useful for:
Mixing content from different sources
Ensuring consistent volume across a playlist
Preparing content for streaming platforms (YouTube, podcasts, etc.)
Audio Filter Chain
Audio filters are applied in the following order:
Normalization (if enabled)
Volume adjustment (if not 100%)
Implementation (filters.rs:85-98):
pub fn build_audio_filters ( config : & ConversionConfig ) -> Vec < String > {
let mut filters = Vec :: new ();
if config . audio_normalize {
filters . push ( "loudnorm=I=-16:TP=-1.5:LRA=11" . to_string ());
}
if ( config . audio_volume - 100.0 ) . abs () > VOLUME_EPSILON {
let volume_factor = config . audio_volume / 100.0 ;
filters . push ( format! ( "volume={:.2}" , volume_factor ));
}
filters
}
Container-Codec Compatibility
Each container supports specific audio codecs. Frame validates compatibility and provides helpful error messages:
MP3 container:
M4A container:
aac (default)
alac (lossless)
WAV container:
Only pcm_s16le (uncompressed PCM)
FLAC container:
MP4 container:
aac (default)
ac3
libopus
mp3
alac
MKV/MOV containers:
All codecs supported (wildcard *)
WebM container:
Default codec mapping (media-rules.json:86-92):
{
"defaultAudioCodec" : {
"mp3" : "mp3" ,
"wav" : "pcm_s16le" ,
"flac" : "flac" ,
"m4a" : "aac" ,
"webm" : "libopus"
},
"defaultAudioCodecFallback" : "aac"
}
Audio-Only Conversion
When converting to an audio-only container, video streams are automatically discarded:
config . container = 'mp3' ;
config . audioCodec = 'mp3' ;
config . audioBitrate = '192' ;
config . audioChannels = 'stereo' ;
FFmpeg args (args.rs:235-248):
if is_audio_only {
args . push ( "-vn" . to_string ()); // No video
if ! config . selected_audio_tracks . is_empty () {
for track_index in & config . selected_audio_tracks {
args . push ( "-map" . to_string ());
args . push ( format! ( "0:{}" , track_index ));
}
} else {
args . push ( "-map" . to_string ());
args . push ( "0:a?" . to_string ());
}
add_audio_codec_args ( & mut args , config );
}
Example Configurations
{
container : 'mp3' ,
audioCodec : 'mp3' ,
audioBitrate : '192' ,
audioChannels : 'stereo' ,
audioVolume : 100 ,
audioNormalize : true
}
Lossless Audio Archive
{
container : 'flac' ,
audioCodec : 'flac' ,
audioChannels : 'original' ,
audioVolume : 100 ,
audioNormalize : false
}
Podcast Optimization
{
container : 'mp3' ,
audioCodec : 'mp3' ,
audioBitrate : '96' ,
audioChannels : 'mono' ,
audioVolume : 100 ,
audioNormalize : true
}
Apple Ecosystem (Lossless)
{
container : 'm4a' ,
audioCodec : 'alac' ,
audioChannels : 'original' ,
audioVolume : 100 ,
audioNormalize : false
}
Web Streaming (Opus)
{
container : 'webm' ,
audioCodec : 'libopus' ,
audioBitrate : '128' ,
audioChannels : 'stereo' ,
audioVolume : 100 ,
audioNormalize : true
}
Built-in Audio Presets
Frame includes several built-in audio presets (presets.ts:218-380):
Audio MP3 (preset ID: audio-only):
MP3 container with 128 kbps stereo
Audio FLAC (preset ID: audio-flac):
Lossless FLAC compression
Audio ALAC (preset ID: audio-alac):
Apple Lossless in M4A container
Audio WAV (preset ID: audio-wav):
Related Features
Video Conversion Configure video codecs and settings
Presets Save and reuse audio conversion settings
Batch Processing Convert multiple audio files efficiently