Compare commits
3 Commits
3d9d30123b
...
8a8ef0b3b4
Author | SHA1 | Date | |
---|---|---|---|
8a8ef0b3b4 | |||
46b18734b3 | |||
e83ed2f6b4 |
72
Makefile
72
Makefile
@ -1,56 +1,72 @@
|
|||||||
# ---- Project Settings --------------------------------------------------------
|
# ---- Project Settings --------------------------------------------------------
|
||||||
|
|
||||||
B2_BUCKET =
|
SSH_LOCATION =
|
||||||
PROJECT_NAME =
|
CELLAR_BOTTLE =
|
||||||
|
PROJECT_ID =
|
||||||
|
INSTALL_DIR =
|
||||||
|
|
||||||
INSTALL_DIR =
|
CELLAR_TRACKS = $(CELLAR_BOTTLE)/$(PROJECT_ID)/tracks
|
||||||
|
CELLAR_METADATA = $(CELLAR_BOTTLE)/$(PROJECT_ID)/metadata.csv
|
||||||
B2_TRACKS = $(B2_BUCKET)/$(PROJECT_NAME)/tracks
|
CELLAR_ARTWORK = $(CELLAR_BOTTLE)/$(PROJECT_ID)/artwork.png
|
||||||
B2_ARTWORK = $(B2_BUCKET)/$(PROJECT_NAME)/artwork
|
|
||||||
|
|
||||||
# ---- Makefile Settings -------------------------------------------------------
|
# ---- Makefile Settings -------------------------------------------------------
|
||||||
|
|
||||||
TRACK_LIST := $(notdir $(shell b2 ls $(B2_TRACKS)))
|
TRACK_LIST := $(shell ssh $(SSH_LOCATION) "ls $(CELLAR_TRACKS)")
|
||||||
FLAC_FILES := $(addprefix out/, $(addsuffix .flac, $(TRACK_LIST)))
|
FLAC_FILES := $(addprefix out/, $(addsuffix .flac, $(TRACK_LIST)))
|
||||||
|
|
||||||
GREEN = \e[32m
|
GREEN = \e[32m
|
||||||
CYAN = \e[36m
|
CYAN = \e[36m
|
||||||
END = \e[0m
|
END = \e[0m
|
||||||
|
|
||||||
.PHONY: all install
|
.PHONY: all install clean setup
|
||||||
.PRECIOUS: out/%.flac
|
|
||||||
|
|
||||||
# ---- Pipeline ----------------------------------------------------------------
|
# ---- Pipeline ----------------------------------------------------------------
|
||||||
|
|
||||||
all: $(FLAC_FILES)
|
all: setup install
|
||||||
|
|
||||||
install:
|
setup:
|
||||||
@mamba run -n Instrumental_Music_Collection python src/install.py \
|
@printf "%b %s\n" "$(CYAN)[ > ]$(END) Create working directory structure"
|
||||||
-td out \
|
@mkdir -p data/tracks
|
||||||
-m data/metadata.csv \
|
@mkdir -p out/
|
||||||
-d "$(INSTALL_DIR)"
|
@printf "%b %s\n" "$(GREEN)[ ✓ ]$(END) Create working directory structure"
|
||||||
|
|
||||||
data/tracks/%.track:
|
data/tracks/%.track:
|
||||||
@printf "%b %s\n" "$(CYAN)[ > ]$(END) Download" "$(notdir $@)"
|
@printf "%b %s\n" "$(CYAN)[ > ]$(END) Download" "$(notdir $@)"
|
||||||
@b2 file download --no-progress \
|
@rsync -az -s "$(SSH_LOCATION):$(CELLAR_TRACKS)/$(basename $(notdir $@))" "$@"
|
||||||
$(B2_BUCKET)/$(PROJECT_NAME)/tracks/$(basename $(notdir $@)) \
|
|
||||||
$@ > /dev/null
|
|
||||||
@printf "%b %s\n" "$(GREEN)[ ✓ ]$(END) Download" "$(notdir $@)"
|
@printf "%b %s\n" "$(GREEN)[ ✓ ]$(END) Download" "$(notdir $@)"
|
||||||
|
|
||||||
data/artwork:
|
data/metadata.csv:
|
||||||
@printf "%b\n" "$(CYAN)[ > ]$(END) Download Artwork"
|
@printf "%b %s\n" "$(CYAN)[ > ]$(END) Download" "$(notdir $@)"
|
||||||
@mkdir -p $@
|
@rsync -az -s "$(SSH_LOCATION):$(CELLAR_METADATA)" "$@"
|
||||||
@b2 sync --no-progress \
|
@printf "%b %s\n" "$(GREEN)[ ✓ ]$(END) Download" "$(notdir $@)"
|
||||||
$(B2_ARTWORK) \
|
|
||||||
$@ > /dev/null
|
|
||||||
@printf "%b\n" "$(GREEN)[ ✓ ]$(END) Download Artwork"
|
|
||||||
|
|
||||||
out/%.flac: data/tracks/%.track data/metadata.csv | data/artwork
|
data/artwork.png:
|
||||||
|
@printf "%b %s\n" "$(CYAN)[ > ]$(END) Download" "$(notdir $@)"
|
||||||
|
@rsync -az -s "$(SSH_LOCATION):$(CELLAR_ARTWORK)" "$@"
|
||||||
|
@printf "%b %s\n" "$(GREEN)[ ✓ ]$(END) Download" "$(notdir $@)"
|
||||||
|
|
||||||
|
out/%.flac: data/tracks/%.track data/metadata.csv data/artwork.png
|
||||||
@printf "%b %s\n" "$(CYAN)[ > ]$(END) Encode" "$(notdir $@)"
|
@printf "%b %s\n" "$(CYAN)[ > ]$(END) Encode" "$(notdir $@)"
|
||||||
@mamba run -n Instrumental_Music_Collection python src/encode.py \
|
@python src/encode.py \
|
||||||
-t $< \
|
-t $< \
|
||||||
-id $(basename $(notdir $@)) \
|
-id $(basename $(notdir $@)) \
|
||||||
-m data/metadata.csv \
|
-m data/metadata.csv \
|
||||||
-a data/artwork \
|
-a data/artwork.png \
|
||||||
-o $@
|
-o $@
|
||||||
@printf "%b %s\n" "$(GREEN)[ ✓ ]$(END) Encode" "$(notdir $@)"
|
@printf "%b %s\n" "$(GREEN)[ ✓ ]$(END) Encode" "$(notdir $@)"
|
||||||
|
|
||||||
|
install: $(FLAC_FILES)
|
||||||
|
@printf "%b %s\n" "$(CYAN)[ > ]$(END) Copy files to target directory"
|
||||||
|
@python src/install.py \
|
||||||
|
-td out/ \
|
||||||
|
-m data/metadata.csv \
|
||||||
|
-d "$(INSTALL_DIR)"
|
||||||
|
@printf "%b %s\n" "$(GREEN)[ ✓ ]$(END) Copy files to target directory"
|
||||||
|
|
||||||
|
# ---- Cleanup -----------------------------------------------------------------
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@printf "%b %s\n" "$(CYAN)[ > ]$(END) Clean working directories"
|
||||||
|
@rm -rf out/
|
||||||
|
@rm -rf data/
|
||||||
|
@printf "%b %s\n" "$(GREEN)[ ✓ ]$(END) Clean working directories"
|
||||||
|
61
README.md
61
README.md
@ -1,26 +1,69 @@
|
|||||||
# Instrumental Music Collection
|
<div align="center">
|
||||||
|
<img src="extra/icon.svg" alt="NCH Logo" width="64" height="64">
|
||||||
|
<div>
|
||||||
|
<br>
|
||||||
|
<code>201.001</code>
|
||||||
|
</div>
|
||||||
|
<h1 align="center">Instrumental Music Collection</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
<p>
|
||||||
|
<a align="center" href="https://git.ami.sc/ami/instrumental-music-collection">
|
||||||
|
<img height="16" width="16" src="https://cdn.simpleicons.org/git/00B8FF/00B8FF"/>
|
||||||
|
Starlane
|
||||||
|
</a>
|
||||||
|
 
|
||||||
|
<a align="center" href="https://github.com">
|
||||||
|
<img height="16" width="16" src="https://cdn.simpleicons.org/github/00B8FF/00B8FF"/>
|
||||||
|
GitHub
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<img height="4" width="100%" src="extra/gradient.png"/>
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
This repository contains scripts to automate encoding and metadata management of instrumental tracks.
|
A collection of scripts to encode and tag my personal instrumental music collection.
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
The project depends on the following:
|
System dependencies:
|
||||||
|
|
||||||
|
- `make`
|
||||||
|
- `rsync`
|
||||||
- `ffmpeg`
|
- `ffmpeg`
|
||||||
- `metaflac`
|
- `metaflac`
|
||||||
|
|
||||||
|
This project is managed through a `conda` environment. To install the required dependencies, run the following:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
conda env create -f environment.yml
|
||||||
|
```
|
||||||
|
|
||||||
## Running
|
## Running
|
||||||
|
|
||||||
To encode all files to `.flac` and write metadata, run:
|
First, activate the `conda` environment:
|
||||||
|
|
||||||
```sh
|
```bash
|
||||||
make all -j 14
|
conda activate IMS
|
||||||
```
|
```
|
||||||
|
|
||||||
To install the encoded files to a target location, run:
|
Then, run the processing pipeline with:
|
||||||
|
|
||||||
```sh
|
```bash
|
||||||
make install INSTALL_DIR=/path/to/dir
|
make all -j $(nproc) \
|
||||||
|
SSH_LOCATION=user@location \
|
||||||
|
CELLAR_BOTTLE=/path/to/bottle \
|
||||||
|
PROJECT_ID=201.001 \
|
||||||
|
INSTALL_DIR=/path/to/install/dir
|
||||||
|
```
|
||||||
|
|
||||||
|
The finalized collection will be installed to the specified `INSTALL_DIR`.
|
||||||
|
|
||||||
|
To clean up the working directories, run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make clean
|
||||||
```
|
```
|
||||||
|
6
environment.yml
Normal file
6
environment.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
name: IMS
|
||||||
|
channels:
|
||||||
|
- conda-forge
|
||||||
|
dependencies:
|
||||||
|
- pandas
|
||||||
|
- python
|
BIN
extra/gradient.png
Normal file
BIN
extra/gradient.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 506 KiB |
25
extra/icon.svg
Normal file
25
extra/icon.svg
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="256" height="256" version="1.1"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="Gradient" x1="0" x2="0" y1="0" y2="1">
|
||||||
|
<stop offset="0%" style="stop-color:#1A5FB4;stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:#8FF0A4;stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
<filter id="alpha-to-white">
|
||||||
|
<feColorMatrix in="SourceGraphic" type="matrix"
|
||||||
|
values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
|
||||||
|
</filter>
|
||||||
|
<g id="child-svg"><svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 512 512"><path opacity="1" fill="#1E3050" d="M499.1 6.3c8.1 6 12.9 15.6 12.9 25.7v72V368c0 44.2-43 80-96 80s-96-35.8-96-80s43-80 96-80c11.2 0 22 1.6 32 4.6V147L192 223.8V432c0 44.2-43 80-96 80s-96-35.8-96-80s43-80 96-80c11.2 0 22 1.6 32 4.6V200 128c0-14.1 9.3-26.6 22.8-30.7l320-96c9.7-2.9 20.2-1.1 28.3 5z" /></svg></g>
|
||||||
|
</defs>
|
||||||
|
<rect
|
||||||
|
width="256"
|
||||||
|
height="256"
|
||||||
|
fill="url(#Gradient)"
|
||||||
|
ry="128"
|
||||||
|
x="0"
|
||||||
|
y="0" />
|
||||||
|
<use xlink:href="#child-svg" filter="url(#alpha-to-white)"
|
||||||
|
transform="matrix(8,0,0,8,64,64)" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
@ -27,19 +27,19 @@ def encode():
|
|||||||
required = True)
|
required = True)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-m", "--metadata_file",
|
"-m", "--metadata_file",
|
||||||
type=str,
|
type = str,
|
||||||
help="Path to .csv metadata file.",
|
help = "Path to .csv metadata file.",
|
||||||
required=True)
|
required = True)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-a", "--artwork_dir",
|
"-a", "--artwork_file",
|
||||||
type=str,
|
type = str,
|
||||||
help="Path to directory containing artwork files.",
|
help = "Path to .png artwork file.",
|
||||||
required=True)
|
required = True)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-o", "--output_file",
|
"-o", "--output_file",
|
||||||
type=str,
|
type = str,
|
||||||
help="Path to .csv file to store individual sample metadata.",
|
help = "Path to encoded output .flac file.",
|
||||||
required=True)
|
required = True)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
metadata_df = pd.read_csv(args.metadata_file)
|
metadata_df = pd.read_csv(args.metadata_file)
|
||||||
@ -90,13 +90,14 @@ def encode():
|
|||||||
# Write the new metadata.
|
# Write the new metadata.
|
||||||
cmd = [
|
cmd = [
|
||||||
"metaflac",
|
"metaflac",
|
||||||
f"--set-tag=ALBUM={track_metadata['Album'].item()}",
|
"--set-tag=ALBUM=Instrumental Music Collection",
|
||||||
|
"--set-tag=ALBUMARTIST=Various Artists",
|
||||||
f"--set-tag=ARTIST={track_metadata['Artist'].item()}",
|
f"--set-tag=ARTIST={track_metadata['Artist'].item()}",
|
||||||
f"--set-tag=TITLE={track_metadata['Title'].item()}",
|
f"--set-tag=TITLE={track_metadata['Title'].item()} [From {track_metadata['Album'].item()}]",
|
||||||
f"--set-tag=TRACKNUMBER={track_metadata['Track'].item()}",
|
f"--set-tag=TRACKNUMBER={track_metadata['Track'].item()}",
|
||||||
f"--set-tag=DATE={track_metadata['Year'].item()}",
|
f"--set-tag=DATE={track_metadata['Year'].item()}",
|
||||||
f"--set-tag=DISCNUMBER={track_metadata['Disc'].item()}",
|
"--set-tag=DISCNUMBER=1",
|
||||||
f"--import-picture-from={args.artwork_dir}/{track_metadata['Artwork File'].item()}",
|
f"--import-picture-from={args.artwork_file}",
|
||||||
args.output_file
|
args.output_file
|
||||||
]
|
]
|
||||||
run_cmd(cmd)
|
run_cmd(cmd)
|
||||||
|
@ -39,24 +39,22 @@ def install():
|
|||||||
for track in track_list:
|
for track in track_list:
|
||||||
track_metadata = metadata_df[metadata_df["Code"] == track.split(".")[0]]
|
track_metadata = metadata_df[metadata_df["Code"] == track.split(".")[0]]
|
||||||
|
|
||||||
# Create album directory (if it does not exist).
|
# Create output directory (if it does not exist).
|
||||||
album_dir = os.path.join(args.dir, track_metadata["Album"].item())
|
|
||||||
cmd = [
|
cmd = [
|
||||||
"mkdir",
|
"mkdir",
|
||||||
"-p",
|
"-p",
|
||||||
album_dir
|
args.dir
|
||||||
]
|
]
|
||||||
run_cmd(cmd)
|
run_cmd(cmd)
|
||||||
|
|
||||||
# Copy song to target directory.
|
# Copy song to target directory.
|
||||||
disc_number = track_metadata["Disc"].item()
|
|
||||||
track_number = track_metadata["Track"].item()
|
track_number = track_metadata["Track"].item()
|
||||||
song_title = track_metadata["Title"].item()
|
album_title = track_metadata["Album"].item().replace("/", " - ")
|
||||||
song_title = song_title.replace("/", " - ")
|
song_title = track_metadata["Title"].item().replace("/", " - ")
|
||||||
|
|
||||||
track_path = os.path.join(
|
track_path = os.path.join(
|
||||||
album_dir,
|
args.dir,
|
||||||
f"{disc_number:>02}-{track_number:>02} {song_title}.flac")
|
f"{track_number:>02} {song_title} [From {album_title}].flac")
|
||||||
|
|
||||||
cmd = [
|
cmd = [
|
||||||
"cp",
|
"cp",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user