Last active
November 27, 2023 20:47
-
-
Save AlexKrupa/0a4eff86435152cf3dd41c32eca56a89 to your computer and use it in GitHub Desktop.
Shokz OpenSwim — large audio file segmentation & tempo adjustment — Fish shell script
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
# Prepare a podcast or audiobook MP3 file to use on Shokz OpenSwim swimming headphones. | |
# | |
# It does 2 things: | |
# 1. Speeds up the tempo. I usually prefer listening to spoken content at 1.5x–2x. | |
# 2. Splits the file into equal-length segments to make rewind/fast-forward possible on the headphones. | |
# This is a workaround for lack of built-in fine-grained rewind/fast-forward controls on the headphones. | |
# The headphones can only do previous/next. | |
# Now imagine doing it accidentally on a several-hours long audiobook. | |
# That's why I wrote this script. | |
function shokz | |
set tempo "1.5" | |
set segment_length_s 60 | |
set source_file $argv | |
set prefix (string split -r -m1 . $source_file)[1] # Trim file extension. | |
set suffix -%03d.mp3 # 000, 001, 002, etc. | |
set subdir $prefix | |
set segment $subdir/$prefix$suffix | |
echo "source_file=$source_file, prefix=$prefix, suffix=$suffix, subdir=$subdir, segment=$segment, tempo=$tempo, segment_length_s=$segment_length_s" | |
# Create a subdirectory to keep segments in, instead of polluting the source directory. | |
mkdir -p $subdir | |
# Change tempo. | |
# Note that tempo is not the same as speed, as it doesn't affect pitch. | |
# This keeps the sound normal instead of "chipmunking" it. | |
# Then pipe the sped-up output and split the file into equal-length segments. | |
ffmpeg -i $source_file -map 0:a -filter:a "atempo=$tempo" -f mp3 pipe: | \ | |
ffmpeg -f mp3 -i pipe: -f segment -segment_time $segment_length_s -segment_start_number 1 -c:a copy $segment | |
# Regarding playback order, unfortunately I don't remember which one of these was true. Either: | |
# 1. The headphones play tracks ordered by their "download" order, i.e. the order in which they were copied onto the device. | |
# 2. Or by their "title" tag. | |
# In case of 2, the following code set each segment's 'title' tag to its trimmed file name. | |
cd $subdir | |
set prefix "tmp-" | |
for file in *.mp3 | |
set title (string split -r -m1 . $file)[1] # Trim file extension. | |
# Set 'title' tag to trimmed file name. | |
# New temp file has 'tmp-' prefix.' | |
ffmpeg -i $file -acodec libmp3lame -aq 0 -metadata title=$title -metadata track=$title -metadata date=$title -id3v2_version 3 -write_id3v1 1 $prefix$file | |
rm $file # Remove original segment. | |
mv $prefix$file $file # Rename tagged segment to original name. | |
end | |
cd .. | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment