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

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.

  1. Create a script file named split_cue.sh.
  2. 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
  1. Make the script executable and run it:
chmod +x split_cue.sh
./split_cue.sh album.cue

Method 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"
    }
}