Last active
April 19, 2024 21:53
-
-
Save rileyjshaw/8b76099a4500c1bea3c6d0a755639e60 to your computer and use it in GitHub Desktop.
Run this from a local folder containing whatever you want to go on the Shokz OpenSwim
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Shokz OpenSwim headphones (formerly AfterShokz Xtrainerz) have a bug where | |
# tracks are not played in alphabetical or track order. They are played in the | |
# order that they were copied to the device. Read more about the issue here: | |
# | |
# - https://en.help.shokz.com/s/article/How-to-list-the-track-order-on-OpenSwim-formerly-Xtrainerz-OPENSWIM1408 | |
# - https://en.help.shokz.com/s/get-article?urlName=how-to-list-tracks-order-EN | |
# | |
# After extensive testing, it seems that specifying transmission order alone is | |
# not enough to get tracks playing in order. Otherwise, the following command | |
# would work: | |
# | |
# rsync -avr --delete --exclude=".*" --exclude="System Volume Information" --exclude="*.DS_Store" ./ /Volumes/XTRAINERZ | |
# | |
# It seems that adding a delay between each file allows the device to process | |
# file order correctly. Filenames also seem to matter, so files are renamed to | |
# sequential numbers before copying. | |
# | |
# This script also removes all track metadata to save space, and adds audible | |
# folder titles to assist with navigation. | |
# | |
# Other things I tried that didn’t work: | |
# | |
# - Adding --bwlimit=1024 to rsync to slow down the transfer. | |
# - Adding track number metadata tags. Source: `add-track-numbers.sh`: | |
# id3v2 -T "$((i + 1))/${#FILES[@]}" "${FILES[i]}" | |
# - Editing file modification and creation dates to match the track order: | |
# # Set the modification date. | |
# gtouch -d "+$i minutes" "/Volumes/XTRAINERZ/$d${FILES[i]}" | |
# # Copy the modification date to the creation date. | |
# SetFile -d "$(GetFileInfo -m "/Volumes/XTRAINERZ/$d${FILES[i]}")" "/Volumes/XTRAINERZ/$d${FILES[i]}" | |
# - Adding a random suffix to the end of each file name. | |
# for f in *.mp3; do | |
# mv "$f" "$(mktemp "${f%.mp3} - XXXX").mp3" | |
# done | |
# # mktemp creates some 0 byte files that we need to clean up. | |
# find . -type f ! -name '*.mp3' -delete | |
rsync -Rr . _tmp | |
cd _tmp | |
for d in */; do | |
if [ "$d" = "System Volume Information/" ]; then | |
continue | |
fi | |
cd "$d" | |
# Create title tracks in each directory. Source: `mp3titles.sh`. | |
say "$d" -o "00. Title.aiff" | |
lame -S -m m "00. Title.aiff" "00. Title.mp3" | |
rm "00. Title.aiff" | |
# Remove all track metadata. | |
id3v2 -D *.mp3 | |
# Rename all files to sequential numbers. | |
ls -1p | grep -v "/$" | cat -n | while read n f; do mv -n "${f}" "$(printf "%03d" $n).mp3"; done | |
FILES=(*.mp3) | |
for i in "${!FILES[@]}"; do | |
echo -e "Copying from $d [$(($i + 1))/${#FILES[@]}]: \t${FILES[i]}" | |
# Copy the single file to the USB drive. | |
rsync -a --delete "${FILES[i]}" "/Volumes/XTRAINERZ/$d" | |
sleep 0.5 | |
done | |
cd .. | |
done | |
cd .. | |
rm -rf _tmp |
Note: controlling load order doesn’t necessarily ensure proper song order. The way to be 100% sure is to use FATSort.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Turns out that songs play in the order they were loaded onto the device: https://en.help.shokz.com/s/article/How-to-list-the-track-order-on-OpenSwim-formerly-Xtrainerz-OPENSWIM1408
More info: https://en.help.shokz.com/s/article/How-to-list-the-track-order-on-OpenSwim-formerly-Xtrainerz-OPENSWIM1408