Convert BIN CUE to FLAC with FFmpeg
This article explains how to split an audio CD image (BIN/CUE) into individual FLAC tracks using FFmpeg. You will learn how to extract tracks manually using precise timestamps and how to automate the entire process using a simple command-line script.
Understanding the BIN/CUE Format
A .bin file contains the raw audio data of the entire
CD, while the .cue file is a text metadata sheet containing
track names, artists, and precise start/end time markers.
While FFmpeg can read CUE files, it does not have a single native command to automatically output split files based on CUE tracks. To achieve this, you can either extract tracks manually or use a script to automate FFmpeg.
Method 1: Extracting Tracks Manually
If you only need to extract a few tracks, you can use FFmpeg’s
seeking options (-ss for start time and -to
for end time) to extract specific portions of the .bin
file.
Run the following command in your terminal:
ffmpeg -i input.bin -ss 00:02:30 -to 00:05:45 -c:a flac track01.flac-i input.bin: Specifies the input audio CD image.-ss 00:02:30: The start time of the track (hh:mm:ss).-to 00:05:45: The end time of the track.-c:a flac: Encodes the output using the lossless FLAC codec.
Method 2: Automated Splitting via Script (Linux/macOS)
To split the entire album into individual tracks automatically
without manually typing timestamps, you can use a Bash script that
parses the .cue file and passes the timings to FFmpeg.
- Create a script file named
split_cue.sh. - Paste the following code into the file:
#!/bin/bash
# Usage: ./split_cue.sh input.cue
cue_file="$1"
bin_file="${cue_file%.*}.bin"
# Read track times and titles from cue file
tracks=($(grep -E "TRACK|INDEX 01" "$cue_file" | awk '{print $NF}'))
# Extract tracks using FFmpeg
for ((i=0; i<${#tracks[@]}; i+=2)); do
track_num=$((i/2+1))
start_time=${tracks[i+1]}
# Convert MM:SS:FF (CUE format) to HH:MM:SS.ms for FFmpeg
IFS=: read -r m s f <<< "$start_time"
ms=$((f * 1000 / 75)) # Convert 75fps CD sectors to milliseconds
ffmpeg_start=$(printf "00:%02d:%02d.%03d" $m $s $ms)
if [ $i -lt $((${#tracks[@]}-2)) ]; then
next_time=${tracks[i+3]}
IFS=: read -r nm ns nf <<< "$next_time"
nms=$((nf * 1000 / 75))
ffmpeg_end=$(printf "00:%02d:%02d.%03d" $nm $ns $nms)
ffmpeg -i "$bin_file" -ss "$ffmpeg_start" -to "$ffmpeg_end" -c:a flac "track_$(printf "%02d" $track_num).flac"
else
# Last track goes to the end of the file
ffmpeg -i "$bin_file" -ss "$ffmpeg_start" -c:a flac "track_$(printf "%02d" $track_num).flac"
fi
done- Make the script executable and run it:
chmod +x split_cue.sh
./split_cue.sh album.cueMethod 3: Automated Splitting via PowerShell (Windows)
For Windows users, you can achieve the same automated splitting using this PowerShell script:
$cueFile = "album.cue"
$binFile = "album.bin"
$cue = Get-Content $cueFile
$times = $cue | Select-String "INDEX 01" | ForEach-Object { $_.Line.Split()[-1] }
for ($i = 0; $i -lt $times.Count; $i++) {
$trackNum = ($i + 1).ToString("00")
$start = $times[$i]
# Format MM:SS:FF to HH:MM:SS.ms
$parts = $start -split ":"
$ms = [math]::Round(([int]$parts[2] * 1000) / 75)
$startFormatted = "00:$($parts[0]):$($parts[1]).$ms"
if ($i -lt ($times.Count - 1)) {
$next = $times[$i + 1]
$nextParts = $next -split ":"
$nextMs = [math]::Round(([int]$nextParts[2] * 1000) / 75)
$endFormatted = "00:$($nextParts[0]):$($nextParts[1]).$nextMs"
ffmpeg -i $binFile -ss $startFormatted -to $endFormatted -c:a flac "track_$trackNum.flac"
} else {
ffmpeg -i $binFile -ss $startFormatted -c:a flac "track_$trackNum.flac"
}
}