Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 146 additions & 0 deletions MUSIC_TROUBLESHOOTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# Music Island Troubleshooting Guide

This guide helps troubleshoot common issues with the Dynamic Island music display.

## Quick Fixes

### 1. Music Island Not Showing
- **Check if music island is enabled**: In your `userconfig.sh`, ensure `P_DYNAMIC_ISLAND_MUSIC_ENABLED=1`
- **Restart SketchyBar**: After config changes, restart SketchyBar for changes to take effect
- **Check music source**: Ensure `P_DYNAMIC_ISLAND_MUSIC_SOURCE` is set to "Music" or "Spotify" (case sensitive)

### 2. No Song Information Displayed
- **Verify music app is running**: Ensure Apple Music or Spotify is open and playing
- **Check media permissions**: Make sure the music app has proper system permissions
- **Try different song**: Some songs may not have complete metadata

### 3. Music Visualizer Not Working
- **Install cava**: `brew install cava`
- **Install Background Music**: `brew install --cask background-music`
- **Check Background Music is running**: Background Music must be running for audio capture
- **Verify audio output**: Set Background Music as your audio output device

## Debug Mode

Enable debug logging to troubleshoot issues:

1. Edit your `userconfig.sh` file:
```bash
P_DYNAMIC_ISLAND_MUSIC_DEBUG=1
```

2. Restart SketchyBar

3. Watch the logs:
```bash
tail -f /var/log/system.log | grep MUSIC_DEBUG
```

## Common Error Messages

### "Warning: cava not found"
**Solution**: Install cava with `brew install cava`

### "Warning: cava cannot access audio input"
**Solution**:
1. Install Background Music: `brew install --cask background-music`
2. Set Background Music as your output device in System Preferences > Sound
3. Make sure Background Music app is running

### "Warning: Music artwork not available"
**Solution**: This is normal for songs without artwork. The island will still show song/artist info.

### "Error: Failed to configure music island elements"
**Solution**:
1. Check that SketchyBar is running properly
2. Verify your `userconfig.sh` has valid values
3. Try restarting the Dynamic Island

## Configuration Validation

The music island now validates configuration values automatically. If you see warnings like:

```
Warning: P_DYNAMIC_ISLAND_MUSIC_INFO_EXPAND_HEIGHT is not set or not numeric, using default
```

This means your configuration has invalid values. Check your `userconfig.sh` for:
- Non-numeric values where numbers are expected
- Missing required configuration variables
- Negative values where positive values are required

## Performance Issues

### Music Island Animations Lag
1. **Reduce animation complexity**: Lower the expand width/height values in your config
2. **Check system load**: High CPU usage can affect animations
3. **Disable debug mode**: Debug logging can impact performance

### High CPU Usage
1. **Check cava process**: Multiple cava processes may be running
2. **Restart the music island**: `pkill -f music_island.sh` and let it restart
3. **Disable visualizer temporarily**: Comment out visualizer in your config

## Reset Music Island

If the music island gets stuck or behaves unexpectedly:

1. **Kill music island processes**:
```bash
pkill -f music_island.sh
pkill -f pause_island.sh
pkill -f cava
```

2. **Clear cache**:
```bash
rm -f ~/.config/dynamic-island-sketchybar/scripts/islands/previous_island
```

3. **Restart SketchyBar**:
```bash
brew services restart sketchybar
```

## Advanced Troubleshooting

### Check JSON Data
With debug mode enabled, you can see the raw JSON data being processed:
```bash
tail -f /var/log/system.log | grep "Handler called with INFO"
```

### Manual Testing
Test the handler directly:
```bash
export INFO='{"title":"Test Song","artist":"Test Artist","state":"playing"}'
bash ~/.config/dynamic-island-sketchybar/scripts/islands/music/handler.sh
```

### Check SketchyBar Events
Verify that media events are being triggered:
```bash
sketchybar --query mediaListener
```

## Reporting Issues

When reporting music island issues, please include:

1. **System information**: macOS version, hardware model
2. **Configuration**: Your `userconfig.sh` file (remove personal info)
3. **Debug logs**: Output with `P_DYNAMIC_ISLAND_MUSIC_DEBUG=1` enabled
4. **Steps to reproduce**: Exact steps that cause the issue
5. **Music app**: Which music application you're using (Apple Music, Spotify, etc.)

## Related Components

The music island system consists of several files:
- `handler.sh`: Processes music events from SketchyBar
- `music_island.sh`: Main music display logic
- `pause_island.sh`: Handles play/pause states
- `cava.sh`: Audio visualizer (requires Background Music)
- `creator.sh`: Creates SketchyBar items for music island
- `reset.sh` / `reset-resume.sh`: Clean up when music island finishes

All of these files now include improved error handling and validation.
8 changes: 6 additions & 2 deletions scripts/islands/clear.sh
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
#!/usr/bin/env/bash
if [[ $P_DYNAMIC_ISLAND_MUSIC_ENABLED == 1 ]]; then
dynamic-island-sketchybar --animate tanh 10 --set island.small_artwork background.image.scale=0 \
--animate tanh 10 --set island.music_visualizer label.color="$P_DYNAMIC_ISLAND_COLOR_TRANSPARENT"
--animate tanh 10 --set island.music_visualizer label.color="$P_DYNAMIC_ISLAND_COLOR_TRANSPARENT" 2>/dev/null || {
echo "Warning: Failed to animate music island elements during clear" >&2
}
fi

sleep 0.2

if [[ $P_DYNAMIC_ISLAND_MUSIC_ENABLED == 1 ]]; then
dynamic-island-sketchybar --set island.music_visualizer drawing=off \
--set island.small_artwork drawing=off
--set island.small_artwork drawing=off 2>/dev/null || {
echo "Warning: Failed to hide music island elements during clear" >&2
}
fi
91 changes: 84 additions & 7 deletions scripts/islands/music/cava.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,88 @@ CURR_DIR=$(

CONF_FILE="$CURR_DIR/cava.conf"

# Function to cleanup on exit
cleanup() {
if [[ "${P_DYNAMIC_ISLAND_MUSIC_DEBUG:-0}" == "1" ]]; then
echo "[CAVA_DEBUG] Cleaning up cava process..." >&2
fi

# Kill any existing cava processes started by this script
pkill -f "cava -p $CONF_FILE" 2>/dev/null

# Kill any child processes
jobs -p | xargs -r kill 2>/dev/null

exit 0
}

while true
do
cava -p "$CONF_FILE" | sed -u 's/ //g; s/0/▁/g; s/1/β–‚/g; s/2/β–ƒ/g; s/3/β–„/g; s/4/β–…/g; s/5/β–†/g; s/6/β–‡/g; s/7/β–ˆ/g; s/8/β–ˆ/g' | while read line; do
dynamic-island-sketchybar --set $NAME label=$line
done
sleep 5
done
# Set up signal handlers
trap cleanup EXIT TERM INT

# Function to check if cava is available
check_cava() {
# Debug logging for cava
if [[ "${P_DYNAMIC_ISLAND_MUSIC_DEBUG:-0}" == "1" ]]; then
echo "[CAVA_DEBUG] Checking cava availability..." >&2
fi

if ! command -v cava &> /dev/null; then
echo "Warning: cava not found, music visualizer disabled" >&2
return 1
fi

# Check if the config file exists
if [[ ! -f "$CONF_FILE" ]]; then
echo "Warning: cava config file not found at $CONF_FILE" >&2
return 1
fi

# Check if Background Music is available (or any audio input)
# Try a quick test run of cava
if ! timeout 2s cava -p "$CONF_FILE" >/dev/null 2>&1; then
echo "Warning: cava cannot access audio input, check Background Music or audio setup" >&2
return 1
fi

if [[ "${P_DYNAMIC_ISLAND_MUSIC_DEBUG:-0}" == "1" ]]; then
echo "[CAVA_DEBUG] Cava is available and working" >&2
fi

return 0
}

# Main loop with error handling
main_loop() {
local retry_count=0
local max_retries=3

while true; do
if ! check_cava; then
sleep 30 # Wait longer if cava is not available
continue
fi

# Start cava with error handling
if cava -p "$CONF_FILE" 2>/dev/null | sed -u 's/ //g; s/0/▁/g; s/1/β–‚/g; s/2/β–ƒ/g; s/3/β–„/g; s/4/β–…/g; s/5/β–†/g; s/6/β–‡/g; s/7/β–ˆ/g; s/8/β–ˆ/g' | while read -r line; do
if [[ -n "$NAME" && -n "$line" ]]; then
dynamic-island-sketchybar --set "$NAME" label="$line" 2>/dev/null
fi
done; then
retry_count=0
else
retry_count=$((retry_count + 1))
echo "Cava failed (attempt $retry_count/$max_retries)" >&2

if [[ $retry_count -ge $max_retries ]]; then
echo "Max retries reached, disabling visualizer for this session" >&2
sleep 300 # Sleep for 5 minutes before retrying
retry_count=0
else
sleep $((retry_count * 2)) # Exponential backoff
fi
fi
done
}

# Run main loop
main_loop
51 changes: 47 additions & 4 deletions scripts/islands/music/handler.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,49 @@
#!/usr/bin/env bash
TITLE=$(jq -r '.title' <<< "$INFO")
ARTIST=$(jq -r '.artist' <<< "$INFO")
STATE=$(jq -r '.state' <<< "$INFO")

dynamic-island-sketchybar --trigger dynamic_island_queue INFO="music" ISLAND_ARGS="$TITLE|$ARTIST|$STATE"
# Debug logging function
debug_log() {
if [[ "${P_DYNAMIC_ISLAND_MUSIC_DEBUG:-0}" == "1" ]]; then
echo "[MUSIC_DEBUG] $*" >&2
fi
}

debug_log "Handler called with INFO: $INFO"

# Validate that INFO is provided and is valid JSON
if [[ -z "$INFO" ]]; then
debug_log "No INFO provided, exiting"
exit 0
fi

# Safely extract music information with error handling
TITLE=$(echo "$INFO" | jq -r '.title // "Unknown Title"' 2>/dev/null)
ARTIST=$(echo "$INFO" | jq -r '.artist // "Unknown Artist"' 2>/dev/null)
STATE=$(echo "$INFO" | jq -r '.state // "unknown"' 2>/dev/null)

debug_log "Raw extracted values - Title: '$TITLE', Artist: '$ARTIST', State: '$STATE'"

# Validate extracted data (jq returns empty string on parse error)
if [[ -z "$TITLE" || "$TITLE" == "null" ]]; then
TITLE="Unknown Title"
debug_log "Title was empty or null, using fallback"
fi

if [[ -z "$ARTIST" || "$ARTIST" == "null" ]]; then
ARTIST="Unknown Artist"
debug_log "Artist was empty or null, using fallback"
fi

if [[ -z "$STATE" || "$STATE" == "null" ]]; then
STATE="unknown"
debug_log "State was empty or null, using fallback"
fi

debug_log "Final values - Title: '$TITLE', Artist: '$ARTIST', State: '$STATE'"

# Only trigger if we have valid state information
if [[ "$STATE" != "unknown" ]]; then
debug_log "Triggering dynamic island queue with valid state"
dynamic-island-sketchybar --trigger dynamic_island_queue INFO="music" ISLAND_ARGS="$TITLE|$ARTIST|$STATE"
else
debug_log "State is unknown, not triggering dynamic island"
fi
Loading