Tools for publishing albums to the web and digital stores
Reason this release was yanked:
encoding stopped working
Project description
Bandcrash (formerly pyBlamscamp)
Bandcrash is a standalone program that automatically encodes an album of songs into a bunch of different formats for distribution on various platforms, such as itch.io, or for hosting on your own website. The embedded player is originally based on the one from blamscamp by @blackle, although it has been pretty thoroughly modified at this point.
Features
- Output as mp3, ogg, FLAC, and web preview (HTML5+mp3 at a lower bitrate)
- Optionally upload everything to your page on itch using butler
- High-quality encoding and metadata, with support for cover songs, per-track artwork, embedded lyrics, and more
- Web player also supports per-track artwork
Usage
Bandcrash comes with everything it needs to operate out of the box.
GUI
If you want to build the GUI locally, install Python, poetry, and make
(from your favorite F/OSS package repository). After that you can run:
poetry run bandcrash-gui
to run the app without building it, or
make app
to build it into an executable, which will be stored in the dist/
directory.
The GUI is implemented in the bandcrash.gui
module.
Command-line
For the command-line version, the suggested approach is to install Python, after which you can install Bandcrash with:
pip install bandcrash
bandcrash --help
will provide a lot more detailed information. For the most basic usage you can run:
bandcrash --init input_dir output_dir
which will try to guess the track order, titles, and artwork from the files in that directory, and store the resulting album configuration as input_dir/album.json
. It will then process the album and put its results into output_dir
.
You can also specify the input as a path to the JSON file, e.g.:
bandcrash input_dir/my_album.json output_dir
or if you want to keep the JSON file in a different directory or use a name other than album.json
, you can use a relative path like:
bandcrash input_dir -j ../data/my_album.json
Note that the -j
path is relative to input_dir
, not the current working directory.
The entry point for the CLI is in bandcrash/cli.py
.
Use as a library
Bandcrash can also be used as a Python library in order to embed it into a web service or application. Here is a minimal example of how to use it:
import bandcrash
import bandcrash.options
import collections.defaultdict
import concurrent.futures
config = bandcrash.options.Options()
album = {
'artist': 'My Band',
'title': 'My album',
'tracks': [
{'filename': 'track 1.wav', 'title': 'The First Track'},
],
}
pool = concurrent.futures.ThreadPoolExecutor()
futures = collections.defaultdict(list)
bandcrash.process(config, album, pool, futures)
for task in concurrent.futures.as_completed(list(itertools.chain(*futures.values()))):
try:
task.result()
except Exception:
# handle the exception in some helpful way
- Load your album metadata into a Python
dict
structure (e.g. by doingjson.loads
on a JSON file or the like) - Create a
concurrent.futures.ThreadPoolExecutor
and acollections.defaultdict(list)
to store its futures - Create a
bandcrash.options.Options
and set its options accordingly - Call
bandcrash.process(options, album_data, threadpool, futures_dict
- Wait for all of the futures in the
futures_dict
to complete
The futures_dict
is a mapping from process step → list of futures, and is fully populated after process()
returns. You can use something like list(itertools.chain(*futures_dict.values()))
to collapse it into a single list of futures if you don't care about tracking individual stages in the pipeline.
It is also fine (and, in fact, preferable) to share a ThreadPoolExecutor
across multiple concurrent batches.
Album format
For the CLI and GUI, album information is stored in a JSON file (normally named album.json
) that looks something like this:
{
"artist": "The artist of the album",
"title": "The title of the album",
"bg_color": "black",
"fg_color": "white",
"highlight_color": "#cc00ff",
"artwork": "album_cover.jpg",
"tracks": [{
"filename": "the first track.wav",
"title": "The First Track",
"artwork": "track1_cover.jpg",
"lyrics": ["This is the first line",
"This is the second line",
"This is the third line",
"",
"This is the second verse",
"This song just keeps getting worse"],
"hidden": false,
"preview": true
}]
}
You can also automatically generate a stub album.json
file with the --init
option. Here are a few examples of its use:
# stored as input_dir/album.json
bandcrash --init input_dir output_dir
# stored as input_dir/filename.json
bandcrash --init input_dir/filename.json output_dir
# stored as input_dir/data/filename.json
bandcrash --init input_dir -j data/filename.json output_dir
which will try to guess the track order and titles from the audio files in input_dir
.
Basically, the top-level album contains the following properties (all optional):
artist
: The artist for the album as a wholetitle
: The album's titleyear
: The release yearcomposer
: The album's composerartwork
: an image file to use for the album's cover art (relative or absolute paths okay)bg_color
,fg_color
,highlight_color
: The color theme for the playergenre
: The default genre for all trackstracks
: an array of track descriptions, in album orderdo_mp3
: Whether to build the album in MP3 formatdo_ogg
: Whether to build the album in Ogg Vorbis formatdo_flac
: Whether to build the album in FLAC formatdo_preview
: Whether to build the web previewdo_zip
: Whether to build a zip file of each output formatdo_butler
: Whether to upload the builds to itch.iobutler_target
: The itch.io Butler target (e.g."fluffy/songs-of-substance"
)butler_prefix
: Any prefix to add to the Butler channel name (e.g."bonus-"
will upload it as"fluffy/songs-of-substance:bonus-mp3"
)
And each track contains (all optional except filename
):
filename
: The audio file to encode into the final output track (ideally wav or aif)group
: The title of the track's grouping (i.e. a work with multiple movements)title
: The title of the trackartist
: The performing artist of this trackcomposer
: The composer of this trackcover_of
: The original artist that this track is a cover of, if anygenre
: The genre of this trackartwork
: Track-specific cover artlyrics
: An array of strings, one line of lyrics per string; alternately, the name of a text file to read the lyrics from (relative or absolute paths okay)hidden
: A boolean for whether to hide this track from the web player entirely (e.g. a purchase bonus); defaults tofalse
preview
: A boolen for whether to generate a preview for the web player; defaults totrue
about
: Detailed commentary about the track
See the sample album JSON file for a rough example.
Publishing to Itch
Here's the process for publishing an album to itch.io:
-
Install butler and log in with
butler login
-
Set it as a "soundtrack," with the kind of project being "HTML"
-
Set your pricing, add preview artwork, etc., and save. Don't do any uploading from this interface.
-
Run
bandcrash
with a-b user/project
flag; for example:bandcrash novembeat-2021/wav novembeat-2021/out -b fluffy/novembeat-2021
-
Wait a moment for itch to finish processing; you can use
butler status user/project
(e.g.butler status fluffy/novembeat-2021
) -
Reload your project edit page; you should now have a few targets, such as
preview
,mp3
, etc. -
Set the
preview
target to "This file will be played in the browser". Set all the other targets to "soundtrack" and, optionally, change the display name. -
View the project page, and when you're ready to publish, publish!
Recommended "embed options"
- Set it to "embed in page" with "manually set size"
- Enable "mobile friendly" (with orientation "default") and "automatically start on page load"
- Disable "fullscreen button" and "enable scrollbars"
Publishing to other sites
If you have a website of your own, upload the preview
directory to your site somewhere, and then embed it using an iframe, e.g.
<iframe src="/path/to/album/" width=640 height=360></iframe>
Contributing
Pull requests are welcome! But please note the following:
The generated web player must not receive any added dependencies. The generator must stay as a single, self-contained file that is as small as reasonably possible. The point is for the generated file to be lightweight. Stick to Vanilla JS.
Roadmap
See the github issues for details, but roughly:
- Local GUI and/or web UI to make setting up the
album.json
easier (and easier installation, especially on Windows!) - Various player improvements
- Easy embedding into websites (opengraph et al)
FAQ
How is this different from blamscamp, scritch, etc.?
Blamscamp and scritch are both great programs for publishing album previews on itch.io and other websites! However, their functionality is only to bundle already-encoded audio files into a web-based player. They don't do the difficult work of encoding and tagging your files, which can be an extremely tedious and error-prone process. Bandcrash's intention is to make the process of encoding and uploading your albums easier to as many stores as possible.
Why was it renamed?
Back when this project started, it was named pyBlamscamp as the intention was to be basically a Python version of the blamscamp GUI which would also handle encoding steps for you, but it very quickly drifted away from that and became something else. Unfortunately, the similarity of the names was incredibly confusing.
Currently the only connection between Bandcrash and blamscamp is that Bandcrash uses a highly-modified version of blamscamp's web player. They serve different goals.
Why run it locally instead of as a web app?
You already have your large .wav files on your local hard drive. Your local drive is also a good place to keep your previous encoding results. Your local computer also has a lot more space available than a typical cloud server, doesn't have to juggle cloud storage credentials, doesn't have to worry about the security of the server running the encoder app, the cost of running servers or paying for cloud storage, and so on.
Basically, it's easier for everyone.
Sometimes local apps are just Better™.
Credits
- Main code: @fluffy-critter
- Original player code and this project's name: @blackle
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for bandcrash-0.4.2-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | cc1767c4379dfb39481c09a3d20e501eb92ec6bcc905022a1add2a16b73b4062 |
|
MD5 | 0b14b8f2afd0e2218107c9232be36d90 |
|
BLAKE2b-256 | 50bdd0eaeb247bc057c082b746c5f2b7643bf221948c8df58d3964d23d6c94e9 |