This commit is contained in:
teitoku
2025-07-16 16:01:42 +09:00
committed by teo3300
commit d71ffb714f
9 changed files with 290 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
tmp/
music/*
!music/.keep

8
README.md Normal file
View File

@ -0,0 +1,8 @@
# How does it work?
Basically, I forgot, I know that you have to download music somehow, create
some rules in csv format, just check `music_db/terraria.csv` and use it as
template, then run `scripts/music_import.py` to copy the music in the
`music` directory
After this you can run the command `. ./mood` to play music

1
minecraft.csv Normal file
View File

@ -0,0 +1 @@
game/sweden.ogg 6x_sweden.ogg
1 game/sweden.ogg 6x_sweden.ogg

72
mood Executable file
View File

@ -0,0 +1,72 @@
#!/bin/sh
MUSIC_PATH="music"
urlencode() {
echo $1 \
| sed 's#/#\%2F#g' \
| sed 's# #\%20#g' #\
#| tr -d '"'
}
if [[ -z $MOOD_ipinfo ]]; then
export MOOD_ipinfo=$(curl ipinfo.io/json 2>/dev/null)
fi
jqurl() {
echo $(urlencode $(echo $MOOD_ipinfo | jq -r $1))
}
gethour() {
echo $RESP \
| jq -r $1 \
| cut -dT -f2
}
location=$(jqurl '.loc')
timezone=$(jqurl '.timezone')
URL="https://api.open-meteo.com/v1/forecast?current=weather_code&forecast_days=1&daily=sunrise,sunset"
URL="$URL&timezone=$timezone"
URL="$URL&latitude=$(echo $location | cut -d, -f1)"
URL="$URL&longitude=$(echo $location | cut -d, -f2)"
RESP=$(curl $URL 2>/dev/null)
CODE=$(echo $RESP | jq -r '.current.weather_code')
TIME="$(gethour '.current.time')"
SUNRISE="$(gethour '.daily.sunrise[0]')"
SUNSET="$(gethour '.daily.sunset[0]')"
if [[ ( $TIME > $SUNRISE ) && ( $TIME < $SUNSET ) ]]; then
TIME='day'
else
TIME='night'
fi
echo "Obtained weather code: $CODE"
T=""
[ $CODE -ge 0 ] && T=$TIME
[ $CODE -ge 40 ] && T='fog'
[ $CODE -ge 50 ] && T='rain'
[ $CODE -ge 70 ] && T='snow'
[ $CODE -ge 80 ] && T='rain'
[ $CODE -ge 85 ] && T='snow'
[ $CODE -ge 90 ] && T='storm'
CODE=$T
echo "Playing playlist for: $CODE"
echo ""
FILES=$(find $MUSIC_PATH -regex "$MUSIC_PATH/${CODE}_.*" \
| sort -R)
setopt shwordsplit
for line in $FILES; do echo "${line%.*}" | sed "s#^${MUSIC_PATH}/${CODE}_##"; done
unsetopt shwordsplit
killall mpv &>/dev/null 2>/dev/null
$(echo $FILES | mpv --playlist=- </dev/null &>/dev/null 2>/dev/null &)
# disown

0
music/.keep Normal file
View File

58
music_db/terraria.csv Normal file
View File

@ -0,0 +1,58 @@
day_journey_end.webm "1.4.1 Journey's End (End Credits Theme) Full Original High Quality Soundtrack [l69Txf0jPgU].webm"
day_underground_hallow.webm "12 - Underground Hallow [elJPMUnPFUI].webm"
day_alternate_day.webm "Alternate Day [vB7lYs4z7kE].webm"
night_alternate_underground.webm "Alternate Underground [l7d77DYkpsw].webm"
storm_boss_1.webm "Boss 1 [jp_rl-1rYpQ].webm"
storm_boss_2.webm "Boss 2 [8E8YdqLG5c8].webm"
storm_boss_3.webm "Boss 3 [XdLq3b6uZj8].webm"
night_corruption.webm "Corruption [HkZ-Z0u5eGc].webm"
night_crimson.webm "Crimson [p1QY1CAFiK0].webm"
day_day.webm "Day [x23I8f9PwlI].webm"
type_.webm "Deerclops Boss Theme OST Terraria x Don't Starve Together An Eye for an Eye Update [47lkXk79K1g].webm"
day_desert.webm "Desert [sELjOl9gP-k].webm"
storm_duke_fishron.webm "Duke Fishron Theme Terraria 1.4 Journey's End Soundtrack [Mg4ekEx4vho].webm"
night_dungeon.webm "Dungeon [cxRovfKFoI4].webm"
night_eclipse.webm "Eclipse [pMNUlKUMw0E].webm"
night_eerie.webm "Eerie [R2Hs-v5XEFQ].webm"
storm_empress_of_light.webm "Empress of Light Theme Original Soundtrack High Quality Journey's End OST [mP3RAMSgrnI].webm"
snow_frost_moon.webm "Frost Moon [32mi7fttwnQ].webm"
night_goblin_army.webm "Goblin Army [azRSVHjhbXU].webm"
type_.webm "Golem [ifzNfr6DAFk].webm"
night_grave_yard.webm "Graveyard [xy59jRi55o4].webm"
snow_hallow.webm "Hallow [IOEjEbjAR3c].webm"
snow_ice.webm "Ice [WvrciA9TTTw].webm"
day_journey_beginning.webm "Journey's Beginning (Title Screen) [X2frO5mx5C8].webm"
day_space_day.webm "Journey's End OST Space Day (Console Space) [SCdSLlnKOw0].webm"
rain_jungle.webm "Jungle [ehMCqtBBUXU].webm"
type_.webm "Lihzahrd [_LxrYpJH-v0].webm"
storm_lunar_tower.webm "Lunar Towers [I4bHZF6bOdY].webm"
storm_martian_madness.webm "Martian Madness [2xpOGAkYR_s].webm"
night_moon)lord.webm "Moon Lord [2o0_30JaUhY].webm"
rain_morning_rain.webm "Morning Rain (Console Tutorial) [CFr5rYfzgaI].webm"
night_mushrooms.webm "Mushrooms [7wp1xknPA5A].webm"
night_night.webm "Night [5Amwk16RgEo].webm"
day_ocean.webm "Ocean [fdi06Y6oFDo].webm"
night_ocean_night.webm "Ocean Night (Console Ocean) [hQWyBbDx2oY].webm"
snow_aether.webm "OST - 'Aether' [3F-bKs9ox_A].webm"
type_.webm "Pirate Invasion [E2neOO8N8G8].webm"
storm_plantera.webm "Plantera [g9Nk_TPIB-w].webm"
storm_pumpkin_moon.webm "Pumpkin Moon [lOyhMudpA48].webm"
storm_queen_bee.webm "Queen Bee [Mm1cUubLqaA].webm"
day_queen_slime.webm "Queen Slime [bC4xn3Vh9gk].webm"
rain_rain.webm "Rain [0dmzWlm4_V0].webm"
day_sandstorm.webm "Sandstorm [4FfrhUgvgDw].webm"
rain_slime_rain.webm "Slime Rain [CHSY3tl9Gs4].webm"
night_space.webm "Space [EroCygxKHwk].webm"
rain_surface_jungle.webm "Surface Jungle Night [tf1D5wIemmY].webm"
storm_thunderstorm.webm "Thunderstorm [2cNbAmSTvT0].webm"
day_title_screen.webm "Title Screen [LFmnZ6VMd_4].webm"
day_town_day.webm "Town Day Theme Terraria 1.4 Journey's End Soundtrack [h8Q0CyunBHo].webm"
night_town_night.webm "Town Night Spoiler [wTKF3JWPS_E].webm"
night_underground.webm "Underground [c-OttnZEXZo].webm"
night_underground_corruption.webm "Underground Corruption [cZEpGtePF4M].webm"
night_undergroun_crimson.webm "Underground Crimson [1MPrk78diZo].webm"
day_underground_desert.webm "Underground Desert [07RSUhz6EVo].webm"
snow_underground_ice.webm "Underground Ice [cYPgRwuAO4I].webm"
rain_undergeound_jungle.webm "Underground Jungle [xIqix-XEp0A].webm"
night_underworld.webm "Underworld [d5tEk9puWH4].webm"
day_windy_day.webm "Windy Day Spoiler [Ecqe_U_IDCo].webm"
Can't render this file because it contains an unexpected character in line 1 and column 22.

28
scripts/data.py Normal file
View File

@ -0,0 +1,28 @@
ENV = {
'usage': [
'music_import.py',
'<translation_db>',
'<source_directory>',
'[destination_directory]'
],
'help': [
"Provide a translation, a source and a destination path to copy the files renaming them accordingly, ",
"The translation file is a csv, containing the following entries:",
""
"<source_file>" "<destination_file>"
"",
"Using relative path for source and destination file",
"Destination file name should looke something like:",
"",
"<CODE>_<description>.<extension>",
"",
"CODE: weather condition name",
"description: just a way for you to recognize the file and for the system's FS to not overwrite files",
"extension: any format supported by mpv should be ok",
"",
"CODE recognized values are:", "'day' 'night' 'fog' 'rain' 'snow' 'thunder'",
"Only when teh weather is clear (day/night): a check on current time is performed against the known",
"sunset/sunrise time to determine which to pick"
],
'dst_dir': './music'
}

View File

@ -0,0 +1,49 @@
import json, os, platform, shutil, sys
'''
Copies audio files from indescript hashed folders to named sorted folders.
You may need to change output path.
'''
MC_ASSETS = ''
# This section should work on any system as well
# print("Your OS is " + platform.system())
if platform.system() == "Windows":
MC_ASSETS = os.path.expandvars(r"%APPDATA%/.minecraft/assets")
elif platform.system() == "Darwin":
MC_ASSETS = os.path.expanduser(r"~/Library/Application Support/minecraft/assets")
else:
MC_ASSETS = os.path.expanduser(r"~/.minecraft/assets")
# Find the latest installed version of minecraft (choose the last element in assets/indexes)
MC_VERSION = os.listdir(MC_ASSETS+"/indexes/")[-1]
# print("Your latest installed version of minecraft is " + MC_VERSION[:-5])
# Change this if you want to put the sound files somewhere else
OUTPUT_PATH = os.path.normpath(os.path.expandvars(os.path.expanduser(sys.argv[1] if len(sys.argv) > 1 else f"./tmp")))
# These are unlikely to change
MC_OBJECT_INDEX = f"{MC_ASSETS}/indexes/{MC_VERSION}"
MC_OBJECTS_PATH = f"{MC_ASSETS}/objects"
MC_SOUNDS = r"minecraft/sounds/"
with open(MC_OBJECT_INDEX, "r") as read_file:
# Parse the JSON file into a dictionary
data = json.load(read_file)
# Find each line with MC_SOUNDS prefix, remove the prefix and keep the rest of the path and the hash
sounds = {k[len(MC_SOUNDS):] : v["hash"] for (k, v) in data["objects"].items() if k.startswith(MC_SOUNDS)}
for fpath, fhash in sounds.items():
if fpath.startswith('music'):
# Ensure the paths are good to go for Windows with properly escaped backslashes in the string
src_fpath = os.path.normpath(f"{MC_OBJECTS_PATH}/{fhash[:2]}/{fhash}")
dest_fpath = os.path.normpath(f"{OUTPUT_PATH}/sounds/{fpath}")
# Make any directories needed to put the output file into as Python expects
os.makedirs(os.path.dirname(dest_fpath), exist_ok=True)
# Copy the file
shutil.copyfile(src_fpath, dest_fpath)

71
scripts/music_import.py Normal file
View File

@ -0,0 +1,71 @@
import sys
import os
from data import ENV
def eprint(*args):
print(*args, file=sys.stderr)
def solve_or_escape(param):
if not param[0] == '$':
return param
if x[1] == '$':
return param[1:]
return ENV[param[1:]]
def l_map(x,y): return list(map(x,y))
def cp_file(command):
dst = os.path.normpath(f"{ENV['dst']}/{command[0]}")
src = os.path.normpath(f"{ENV['src']}/{command[1]}")
eprint(f'Copying ... "{src}" to "{dst}"')
shutil.copy(src, dst)
import shutil
def file_import(commands):
try:
l_map(cp_file, commands)
except FileNotFoundError as e:
eprint('Error:', e)
def main():
if "-h" in sys.argv or "--help" in sys.argv:
eprint(); eprint(' ', sys.argv[0])
eprint(); eprint(' -', ' '.join(ENV['usage']))
eprint(); [eprint(' ', x) for x in ENV['help']]
eprint()
exit(0)
if len(sys.argv) < len(ENV['usage']):
eprint('Usage:', ' '.join(ENV['usage']))
exit(1)
if len(sys.argv) == len(ENV['usage']):
ENV['dst'] = os.path.normpath(sys.argv[-1])
ENV['src'] = os.path.normpath(sys.argv[-2])
ENV['mus_db'] = os.path.normpath(sys.argv[-3])
dst_dir = ENV['dst']
src_dir = ENV['src']
mus_db = ENV['mus_db']
if not os.path.isfile(mus_db):
eprint(f"{mus_db}: Not a file")
if not os.path.isdir(src_dir):
eprint(f"{src_dir}: Not a directory")
if not os.path.isdir(dst_dir):
eprint(f"{dst_dir}: Not a directory")
import csv
config = []
with open(mus_db, newline='') as csvfile:
config = [row for row in csv.reader(csvfile, delimiter=' ')]
file_import(config)
if __name__ == "__main__":
main()