User Tools

Site Tools


linux:rip-audio-cd

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
linux:rip-audio-cd [2023/05/29 11:55] – external edit 127.0.0.1linux:rip-audio-cd [2026/02/01 13:14] (current) – [Trim silence from start/end] Wuff
Line 31: Line 31:
 </code> </code>
  
 +
 +====== Trim silence from start/end ======
 +
 +This reencodes the file
 +<code>
 +ffmpeg -i input.mp3 -af silenceremove=1:0:-50dB:stop_periods=1:stop_duration=0:stop_threshold=-50dB output.mp3
 +</code>
 +
 +This copies the frames without quality loss:
 +<code bash trim_mp3_silence_copy.sh>
 +#!/usr/bin/env bash
 +set -euo pipefail
 +
 +# trim_mp3_silence_copy.sh
 +#
 +# Usage:
 +#   ./trim_mp3_silence_copy.sh input.mp3 [output.mp3]
 +#
 +# Env vars you can override:
 +#   NOISE_DB   (default: -40dB)  threshold for silencedetect
 +#   MIN_DUR    (default: 0.5)    minimum silence duration to consider (seconds)
 +
 +in="${1:-}"
 +out="${2:-}"
 +
 +if [[ -z "${in}" ]]; then
 +  echo "Usage: $0 input.mp3 [output.mp3]" >&2
 +  exit 1
 +fi
 +
 +if [[ ! -f "${in}" ]]; then
 +  echo "Input file not found: ${in}" >&2
 +  exit 1
 +fi
 +
 +if [[ -z "${out}" ]]; then
 +  base="${in%.*}"
 +  out="${base}.trimmed.mp3"
 +fi
 +
 +NOISE_DB="${NOISE_DB:--40dB}"
 +MIN_DUR="${MIN_DUR:-0.5}"
 +
 +# Get full duration (seconds, as float)
 +duration="$(ffprobe -v error -show_entries format=duration -of default=nw=1:nk=1 "$in")"
 +
 +# Run silencedetect and capture lines
 +sd="$(
 +  ffmpeg -hide_banner -nostats -i "$in" \
 +    -af "silencedetect=noise=${NOISE_DB}:d=${MIN_DUR}" \
 +    -f null - 2>&1 | grep -E 'silence_(start|end):' || true
 +)"
 +
 +if [[ -z "$sd" ]]; then
 +  echo "No silence detected (noise=${NOISE_DB}, d=${MIN_DUR}). Copying original -> ${out}" >&2
 +  cp -f -- "$in" "$out"
 +  exit 0
 +fi
 +
 +# First silence_end => start of audio
 +start_keep="$(awk '/silence_end:/ {print $NF; exit}' <<<"$sd")"
 +
 +# Last silence_start => end of audio (trailing silence start)
 +end_keep="$(awk '/silence_start:/ {v=$NF} END{if(v!="") print v}' <<<"$sd")"
 +
 +# Fallbacks / sanity
 +if [[ -z "${start_keep:-}" ]]; then
 +  # No leading silence_end found; keep from 0
 +  start_keep="0"
 +fi
 +if [[ -z "${end_keep:-}" ]]; then
 +  # No trailing silence_start found; keep to full duration
 +  end_keep="$duration"
 +fi
 +
 +# Ensure start < end (handle edge cases)
 +ok="$(
 +  awk -v s="$start_keep" -v e="$end_keep" 'BEGIN{ if (s+0 < e+0) print "1"; else print "0"; }'
 +)"
 +
 +if [[ "$ok" != "1" ]]; then
 +  echo "Could not determine a valid trim window." >&2
 +  echo "Detected start_keep=${start_keep}, end_keep=${end_keep}, duration=${duration}" >&2
 +  echo "Silencedetect output:" >&2
 +  echo "$sd" >&2
 +  exit 2
 +fi
 +
 +echo "Input:  $in"
 +echo "Output: $out"
 +echo "Keep:   ${start_keep}s -> ${end_keep}s (duration ~ $(awk -v s="$start_keep" -v e="$end_keep" 'BEGIN{printf "%.3f", (e-s)}'))"
 +echo "Detect: noise=${NOISE_DB}, min_silence=${MIN_DUR}s"
 +
 +# Stream-copy trim (no re-encode). Use -ss/-to after -i for more accurate seeking while still copying.
 +ffmpeg -hide_banner -y -i "$in" -ss "$start_keep" -to "$end_keep" -c copy "$out"
 +</code>
 +Then use as
 +<code>
 +chmod +x trim_mp3_silence_copy.sh
 +./trim_mp3_silence_copy.sh input.mp3
 +# or
 +NOISE_DB=-35dB MIN_DUR=0.3 ./trim_mp3_silence_copy.sh input.mp3 out.mp3
 +</code>
linux/rip-audio-cd.1685357734.txt.gz · Last modified: by 127.0.0.1