Skip to content

Instantly share code, notes, and snippets.

@jmatthewturner
Last active May 29, 2025 17:58
Show Gist options
  • Save jmatthewturner/32a84e2f45e5fe8dbe7a738ac6ca5ffd to your computer and use it in GitHub Desktop.
Save jmatthewturner/32a84e2f45e5fe8dbe7a738ac6ca5ffd to your computer and use it in GitHub Desktop.
BASH script for stripping hidden fields from id3 tags.
#!/bin/bash
# This script was written entirely by Claude.ai, with prompts by jmatthewturner.
# It does what I need well enough, so I'm not taking the time to refine it.
# But I still wanted to share in case anyone else finds it useful.
#
# It's purpose is to strip hidden fields from id3 tags, as part of a larger
# project to get a Kenwood Excelon head unit working properly with USB MP3s.
# Details of the larger project are here:
# https://jmatthewturner.wordpress.com/2025/05/29/usb-mp3-functionality-on-kenwood-excelon-head-units/
#
# Known issue: Sometimes, for reasons I have not investigated, it renames
# the artist as “[artist] album [artist]”; i.e., the Artist field goes
# from “Metallica” to “Metallica album Metallica.” Probably a delimiter
# issue, but I don't see the problem at first glance, and I’ve spent
# enough time on this already. As it happens, the fix is just to run
# the script again, and it fixes the issue on the second pass. Go figure.
#
# https://gist.github.com/jmatthewturner/32a84e2f45e5fe8dbe7a738ac6ca5ffd
#
# Everything after this line is AI generated. -JMT
# Script to rebuild MP3 tags in ID3v2.3 format with comprehensive year handling
# This script removes all tags and rebuilds them to eliminate problematic UserTextFrames
echo "This script will remove all ID3 tags and rebuild them in ID3v2.3 format."
echo "It will retain title, artist, album, year, and track number information."
echo "Are you sure you want to continue? (y/n)"
read confirm
if [[ ! "$confirm" =~ ^[Yy] ]]; then
echo "Operation cancelled."
exit 0
fi
# Make a backup directory
backup_dir="./tag_backup_$(date +%Y%m%d_%H%M%S)"
mkdir -p "$backup_dir"
echo "Created backup directory: $backup_dir"
# Counter for processed files
count=0
# Process each MP3 file
for file in *.mp3; do
# Skip if no MP3 files found
if [ "$file" = "*.mp3" ]; then
echo "No MP3 files found in the current directory."
exit 1
fi
echo "Processing: $file"
# Extract and save current tag information
echo "Extracting tag information..."
title=$(eyeD3 "$file" | grep "title:" | sed -e 's/title: //')
artist=$(eyeD3 "$file" | grep "artist:" | sed -e 's/artist: //')
album=$(eyeD3 "$file" | grep "album:" | sed -e 's/album: //')
year=$(eyeD3 "$file" | grep "recording date:" | sed -e 's/recording date: //')
track=$(eyeD3 "$file" | grep "track:" | sed -e 's/track: //' | awk '{print $1}')
#eyeD3 --write-images=. "$file"
# Save tag info to backup file
tag_info="$backup_dir/${file%.mp3}.tags"
echo "File: $file" > "$tag_info"
echo "Title: $title" >> "$tag_info"
echo "Artist: $artist" >> "$tag_info"
echo "Album: $album" >> "$tag_info"
echo "Year: $year" >> "$tag_info"
echo "Track: $track" >> "$tag_info"
echo "Saved tag backup to $tag_info"
# Remove all ID3 tags using id3v2 if available, otherwise eyeD3
echo "Removing all ID3 tags..."
if command -v id3v2 &> /dev/null; then
id3v2 --delete-all "$file"
else
eyeD3 --remove-all "$file"
fi
# Add tags back with ID3v2.3 format and proper year handling
echo "Adding tags back in ID3v2.3 format..."
eyeD3 --to-v2.3 \
--title="$title" \
--artist="$artist" \
--album="$album" \
--release-date="$year" \
--recording-date="$year" \
--orig-release-date="$year" \
--track="$track" \
"$file"
# Set the TYER frame as well for maximum compatibility
if command -v id3v2 &> /dev/null; then
id3v2 --TYER "$year" "$file"
fi
#if [ -f "FRONT_COVER.jpg" ]; then
# echo "FRONT_COVER.jpg successfully extracted from $file."
# cover_img="FRONT_COVER.jpg"
#elif [ -f "FRONT_COVER.png" ]; then
# echo "FRONT_COVER.png successfully extracted from $file."
# cover_img="FRONT_COVER.png"
# else
# # At this point, all attempts to locate artwork have failed.
# echo "No cover image found!"
#fi
# Re-embed cover art
#eyeD3 -Q --add-image "$cover_img:FRONT_COVER" "$file"
# Verify the tags
echo "Verifying tags..."
eyeD3 "$file" | grep -E "title:|artist:|album:|recording date:|track:"
# Check if UserTextFrames are still present
if eyeD3 "$file" | grep -q "UserTextFrame:"; then
echo "WARNING: UserTextFrames still present in $file after removal."
else
echo "SUCCESS: No UserTextFrames detected in $file"
fi
# Increment counter
((count++))
echo "Completed: $file"
echo "----------------------------"
done
echo "Complete! Processed $count files."
echo "Tag information was backed up to: $backup_dir"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment