Bring eligible SoundCloud tracks into your existing Apple Music playlists on Mac. Import tagged MP3s locally; use Apple's sync features for iPhone listening.
Python
10
82 commits
updated Oct 9, 2026
Find music on SoundCloud and keep it alongside the songs in your existing Apple Music playlists. SC2AM is a command-line tool for Mac users: give it a single track link you have permission to download, and it downloads a tagged MP3, imports it into Music.app and optionally adds it to a playlist you choose.
Start here: Install v2.1.0 · Mac → iPhone, offline & CarPlay setup · Watch the 36-second demo
You need macOS, Music.app with Automation permission, Python 3.10+ and FFmpeg. The installation guide uses Homebrew. For iPhone listening, use Apple's Sync Library with Apple Music or iTunes Match, or the separate Finder sync route. Once the track is stored on your iPhone, Apple's Music app handles offline and compatible CarPlay playback.
SC2AM confirms the local Mac import only; it does not automate or guarantee cloud or iPhone sync. Importing an MP3 is separate from Apple's catalog matching: SC2AM does not request or guarantee a catalog match or an audio-quality upgrade.
Watch the 36-second captioned, animated overview of the SoundCloud → Music → iPhone → CarPlay journey. It includes a real Mac Music screenshot, illustrated phone/car scenes and a demo soundtrack; it is not a live recording or a measurement of sync time.
Setup, tested command and credits · Separate device evidence and limits
SC2AM provides a small, repeatable workflow for importing SoundCloud tracks into your macOS Music library:
Artwork is checked as image data and normalized to JPEG; the download result reports when a fallback image is used. See How It Works for repeat/resume behavior and the limits of local import confirmation.
Apple Music automation relies on macOS permissions and Music.app being available locally. Before using SC2AM, make sure:
For a step-by-step checklist, see docs/macos-setup.md.
That guide also explains Apple Music Sync Library, manual Finder sync, offline
listening, and the iPhone/CarPlay path; SC2AM itself only confirms the local Mac
import.
Release preparation is documented in docs/releasing.md,
and user-facing changes are tracked in CHANGELOG.md.
This install path uses the published v2.1.0 GitHub wheel from the
release page;
see the release notes.
It requires macOS, Python 3.10 or newer, and Homebrew for the external ffmpeg and ffprobe
programs. Music.app is needed when importing tracks; a real download also needs
network access.
brew install ffmpeg
git clone https://github.com/zfl4wless/sc2am.git
cd sc2am
python3 -m venv .venv
source .venv/bin/activate
python -m pip install \
"https://github.com/zFl4wless/sc2am/releases/download/v2.1.0/sc2am-2.1.0-py3-none-any.whl"
sc2am doctor
sc2am download "https://soundcloud.com/artist/track"
The wheel installs SC2AM and its Python dependencies into the active virtual
environment. Do not also install requirements.txt; it is a compatibility
wrapper around the same project dependencies. Follow macOS setup
for prerequisites and Music.app permissions before the first real download.
The doctor check reports missing prerequisites without changing Music.
Version 2.1.0 adds share links, safe repeat/resume and --strict-import.
To upgrade an existing installation from v2.0.0 or v2.0.1 to v2.1.0,
activate the same environment and install the released wheel with --upgrade:
python -m pip install --upgrade \
"https://github.com/zFl4wless/sc2am/releases/download/v2.1.0/sc2am-2.1.0-py3-none-any.whl"
python -m pip check
For later upgrades, use the wheel URL for the latest published GitHub release; its version is part of the asset filename and URL. The GitHub releases page is linked from the project's release notes.
The application upgrade does not remove ~/.sc2am/config.yaml, downloaded
tracks, or <download_dir>/.sc2am/history.sqlite3. If an old config contains
settings no longer recognized by this version, keep a backup, remove or correct
only those settings, and retry sc2am doctor. To regenerate defaults, first copy
the config file and then run sc2am config init --force; this replaces only the
selected YAML file. Never remove the download folder's .sc2am directory: it
contains the journal SC2AM uses to safely resume downloads and imports.
For development, clone the repository, create and activate a virtual environment, and install the project with its development tools:
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -e '.[dev]'
The editable install is for contributors who need changes in the checkout to be available immediately. It is not an additional step for end users.
SoundCloud-Links must point to a single track, for example:
https://soundcloud.com/artist/track
or https://www.soundcloud.com/artist/track.
Mobile share links such as https://on.soundcloud.com/<token> are also accepted
by download and batch. SC2AM resolves them before validation and passes the
resolved track URL to the downloader. Resolution makes at most five HTTP HEAD
requests, with a 3-second connection and 5-second read timeout per request.
Redirects to unrelated hosts, loops, expired links, and collections are rejected;
use a fresh share link or a direct track URL if resolution fails. --dry-run
also needs a network connection for share links; direct URLs are validated locally.
Profiles, profile tabs (such as /likes or /tracks), albums, and sets are
rejected. SC2AM also checks the extracted result before downloading audio;
if it is a collection or cannot be verified as a single track, the download stops.
Download a single track:
sc2am download "https://soundcloud.com/artist/track"
Download multiple tracks in one run:
sc2am download \
"https://soundcloud.com/artist/track1" \
"https://soundcloud.com/artist/track2"
If you want to keep processing after one URL fails, use:
sc2am download \
"https://soundcloud.com/artist/track1" \
"https://soundcloud.com/artist/track2" \
--continue-on-error
Download and add to playlist:
sc2am download "https://soundcloud.com/artist/track" --playlist "My Playlist"
If you do not pass --playlist, SC2AM uses the configured default_playlist when one is set. Playlist names are matched against the playlists currently available in Apple Music, and the app will tell you clearly if the playlist is missing or if the name is duplicated.
Names containing commas, quotes or Unicode characters are supported, for example
--playlist "Road, Trip". Matching ignores case and surrounding whitespace;
the original name is preserved for the import. Choose a regular user playlist:
Smart, Genius, folder and system playlists cannot receive tracks. Duplicate
names must be renamed before importing, even when they occur in different folders.
Don't automatically open Music app:
sc2am download "https://soundcloud.com/artist/track" --no-open
For a preview that validates the input and shows the planned actions without
downloading files or accessing Music.app, add --dry-run. Use
--no-open --playlist "" when you want to disable both Music actions.
Create a file urls.txt with one URL per line:
https://soundcloud.com/artist/track1
https://soundcloud.com/artist/track2
# This is a comment
https://soundcloud.com/artist/track3
Then process all URLs:
sc2am batch urls.txt
Batch options:
# Add all tracks to a playlist
sc2am batch urls.txt --playlist "My Playlist"
# Continue processing even if a URL fails
sc2am batch urls.txt --continue-on-error
See the CLI and configuration contract for the complete interface. Precedence is explicit CLI options > environment > selected YAML file > defaults. A custom YAML file replaces the default file. Invalid YAML, unknown keys, and invalid values are reported instead of silently ignored.
SC2AM ignores external yt-dlp configuration files for both track information and
audio downloads (--ignore-config). Personal yt-dlp settings such as
--skip-download, download archives, and match filters do not affect SC2AM.
The SC2AM configuration precedence above remains unchanged.
View current configuration:
sc2am config show
Configuration File (~/.sc2am/config.yaml):
download_dir: ~/Downloads/sc2am
default_playlist: null
open_music_app: true
continue_on_error: false
log_level: INFO
log_file: null
Environment variables:
Use exported variables or prefix the command with assignments. .env files are not
loaded automatically.
SC2AM_DOWNLOAD_DIR=~/Music/Downloads SC2AM_PLAYLIST="My Playlist" SC2AM_LOG_LEVEL=DEBUG \
sc2am download "https://soundcloud.com/artist/track"
Active settings:
| Option | Type | Default | Description |
|---|---|---|---|
download_dir | Path | ~/Downloads/sc2am | MP3 destination |
default_playlist | String or null | null | Default playlist |
open_music_app | Bool | true | Automatically opens MP3s in Music |
continue_on_error | Bool | false | Continues after an input/download failure |
log_level | String | INFO | DEBUG, INFO, WARNING, ERROR, or CRITICAL |
log_file | Path or null | null | Optional detailed log file |
Both download and batch support --no-open / --open,
--continue-on-error / --stop-on-error, --playlist NAME, and --dry-run.
Omitted options inherit configuration. --playlist "" disables the configured
playlist. --no-open leaves playlist actions enabled; use both to avoid Music
interaction. Dry runs validate and preview without downloads, file writes, or
Music actions.
# Use custom config file
sc2am --config /path/to/config.yaml download "..."
# Set log level
sc2am --log-level DEBUG download "..."
Batch download with logging:
sc2am --log-level DEBUG batch urls.txt --continue-on-error
Download to custom directory:
SC2AM_DOWNLOAD_DIR=~/Music sc2am download "..."
SC2AM retries transient download failures and read-only Music queries. Mutations are confirmed against the active Music library before reporting success.
MP3 filenames include the SoundCloud track ID: Title [123456789].mp3.
Tracks with the same title and different IDs are saved separately. A local journal
in <download_dir>/.sc2am/history.sqlite3 records source IDs, verified file hashes
and Music references. Repeating a recorded URL reuses the unchanged MP3 without
network extraction, download or retagging. A new URL resolving to the same source
ID also reuses it, even if the title changed. Missing files can be downloaded
again; changed files stop with an integrity warning. Legacy title-only files are
not migrated.
Music imports store a source marker in the MP3's default English ID3 comment
(preserving existing text) so copied library files can be found after a lost
response. Confirmed persistent IDs are scoped to the active library and checked
on every run. Existing playlist membership is reused. Keep the download folder
and its .sc2am journal together; safe repeat/resume is scoped to this folder.
Do not run concurrent imports from different download folders into one library.
Existing imports from older SC2AM versions can be recognized by their original
file location; copied legacy imports without a marker/history need manual review
before the first run. Confirmation covers the local library only, not cloud sync,
iPhone availability or playback.
SC2AM only tags and imports the verified MP3 path reported by that download. Missing or invalid output paths cause a download error, even when other MP3s already exist in the directory.
SC2AM now returns stable exit codes for scripting:
0 - command completed without input/download failures1 - runtime/download failure or a run that continued past invalid entries2 - usage/configuration error or an input-validation abortMusic import/playlist failures remain warnings and do not change exit status by
default. Add --strict-import to download or batch to return 1 for failed
or unconfirmed Music stages; use --continue-on-error to continue after them.
Summaries separate downloads, confirmed local imports and playlist memberships,
including partial success. Dry runs count previews only and perform no Music
steps. Local confirmation does not verify cloud/iPhone availability.
CLI progress output is written as clean status lines. By default, Python logger output on stderr is limited to warnings and errors so informational log lines do not duplicate the CLI status messages. Explicit --log-level DEBUG (or log_level: DEBUG / SC2AM_LOG_LEVEL=DEBUG) includes diagnostic and informational logs on stderr. To retain logs in a file, configure log_file or SC2AM_LOG_FILE.
When running batch operations with multiple links or URLs from a file, SC2AM provides improved logging and summary output to help you debug and understand the results:
Example output with --no-open --playlist "" --continue-on-error:
──────────────────────────────────────────────
Track 1/3: Processing https://soundcloud.com/artist/track1
Track 1/3: Validating SoundCloud URL...
Track 1/3: OK: Valid SoundCloud URL
Track 1/3: Downloading track...
Track 1/3: OK: Downloaded: track1 [123456789].mp3
Track 1/3: Done!
──────────────────────────────────────────────
Track 2/3: Processing https://soundcloud.com/artist/track2
Track 2/3: Validating SoundCloud URL...
Track 2/3: OK: Valid SoundCloud URL
Track 2/3: Downloading track...
Track 2/3: ERROR: Track not found
──────────────────────────────────────────────
Track 3/3: Processing https://soundcloud.com/artist/track3
Track 3/3: Validating SoundCloud URL...
Track 3/3: OK: Valid SoundCloud URL
Track 3/3: Downloading track...
Track 3/3: OK: Downloaded: track3 [987654321].mp3
Track 3/3: Done!
Downloads: 2 succeeded, 1 failed (66% success rate)
Imports: not requested
Playlists: not requested
Failed tracks:
1. https://soundcloud.com/artist/track2
Error: Track not found
No log file is created by default (log_file: null). Generic errors show how to
enable diagnostics; dependency, path, URL and Music permission errors include
remedies. To see debug output on stderr, replace the example link with the failing
track URL and keep the options from the original command:
sc2am --log-level DEBUG download "https://soundcloud.com/artist/track"
sc2am --log-level DEBUG batch urls.txt --continue-on-error
To save command details, underlying yt-dlp errors and exception tracebacks in a diagnostic log, set a writable log path:
SC2AM_LOG_FILE="$PWD/sc2am-debug.log" sc2am --log-level DEBUG download "https://soundcloud.com/artist/track"
SC2AM_LOG_FILE="$PWD/sc2am-debug.log" sc2am --log-level DEBUG batch urls.txt --continue-on-error
Put global options before download or batch. If using a custom configuration,
keep --config PATH before the subcommand as well. When running from the source
checkout, replace sc2am with python main.py. A configured log file retains
underlying errors and exception tracebacks at the default INFO level too; DEBUG
adds command and progress context. These commands repeat the workflow, so check
the Music library and target playlist before retrying a failed or uncertain
import. Review logs for private URLs and local paths before sharing them.
--dry-run validates and previews only: it suppresses log-file writes and does
not reproduce download or Music failures. config show also does not write a
log file.
pip install yt-dlp --upgrade
open_music_app setting in configdocs/macos-setup.md for the full checklistosascript attempt is limited to 30 seconds. Read-only lookups retry temporary failures and timeouts up to three attempts, with 1- and 2-second delays (at most about 93 seconds).mkdir -p ~/Downloads/sc2am
chmod 755 ~/Downloads/sc2am
Contributions are welcome! Please:
git checkout -b feature/my-feature)# Install with dev dependencies
pip install -r requirements-dev.txt
# Code formatting
black --check .
# Linting
flake8 main.py sc2am tests scripts
# Tests
PYTHONPATH=. pytest -q
CI runs these checks for pull requests, main, and v* release tags. It also
builds sdist/wheel artifacts and checks the installed CLI in fresh environments
on Ubuntu and macOS, without a personal Apple account. See
release validation for scope and limitations.
Dependency source of truth:
pyproject.toml is the canonical dependency definition.requirements.txt and requirements-dev.txt are thin compatibility wrappers that install from project metadata.pyproject.toml with pip-audit; development tools are not included.MIT License - see LICENSE file for details
The current stable release line is 2.x. Older release lines are unsupported; upgrade to the latest 2.x release before requesting help.
For general issues, feature requests, or questions:
For suspected security vulnerabilities, do not open a public issue. Report them privately through GitHub Security Advisories.
Bring eligible SoundCloud tracks into your existing Apple Music playlists on Mac. Import tagged MP3s locally; use Apple's sync features for iPhone listening.
Python
10
82 commits
updated Oct 9, 2026
Find music on SoundCloud and keep it alongside the songs in your existing Apple Music playlists. SC2AM is a command-line tool for Mac users: give it a single track link you have permission to download, and it downloads a tagged MP3, imports it into Music.app and optionally adds it to a playlist you choose.
Start here: Install v2.1.0 · Mac → iPhone, offline & CarPlay setup · Watch the 36-second demo
You need macOS, Music.app with Automation permission, Python 3.10+ and FFmpeg. The installation guide uses Homebrew. For iPhone listening, use Apple's Sync Library with Apple Music or iTunes Match, or the separate Finder sync route. Once the track is stored on your iPhone, Apple's Music app handles offline and compatible CarPlay playback.
SC2AM confirms the local Mac import only; it does not automate or guarantee cloud or iPhone sync. Importing an MP3 is separate from Apple's catalog matching: SC2AM does not request or guarantee a catalog match or an audio-quality upgrade.
Watch the 36-second captioned, animated overview of the SoundCloud → Music → iPhone → CarPlay journey. It includes a real Mac Music screenshot, illustrated phone/car scenes and a demo soundtrack; it is not a live recording or a measurement of sync time.
Setup, tested command and credits · Separate device evidence and limits
SC2AM provides a small, repeatable workflow for importing SoundCloud tracks into your macOS Music library:
Artwork is checked as image data and normalized to JPEG; the download result reports when a fallback image is used. See How It Works for repeat/resume behavior and the limits of local import confirmation.
Apple Music automation relies on macOS permissions and Music.app being available locally. Before using SC2AM, make sure:
For a step-by-step checklist, see docs/macos-setup.md.
That guide also explains Apple Music Sync Library, manual Finder sync, offline
listening, and the iPhone/CarPlay path; SC2AM itself only confirms the local Mac
import.
Release preparation is documented in docs/releasing.md,
and user-facing changes are tracked in CHANGELOG.md.
This install path uses the published v2.1.0 GitHub wheel from the
release page;
see the release notes.
It requires macOS, Python 3.10 or newer, and Homebrew for the external ffmpeg and ffprobe
programs. Music.app is needed when importing tracks; a real download also needs
network access.
brew install ffmpeg
git clone https://github.com/zfl4wless/sc2am.git
cd sc2am
python3 -m venv .venv
source .venv/bin/activate
python -m pip install \
"https://github.com/zFl4wless/sc2am/releases/download/v2.1.0/sc2am-2.1.0-py3-none-any.whl"
sc2am doctor
sc2am download "https://soundcloud.com/artist/track"
The wheel installs SC2AM and its Python dependencies into the active virtual
environment. Do not also install requirements.txt; it is a compatibility
wrapper around the same project dependencies. Follow macOS setup
for prerequisites and Music.app permissions before the first real download.
The doctor check reports missing prerequisites without changing Music.
Version 2.1.0 adds share links, safe repeat/resume and --strict-import.
To upgrade an existing installation from v2.0.0 or v2.0.1 to v2.1.0,
activate the same environment and install the released wheel with --upgrade:
python -m pip install --upgrade \
"https://github.com/zFl4wless/sc2am/releases/download/v2.1.0/sc2am-2.1.0-py3-none-any.whl"
python -m pip check
For later upgrades, use the wheel URL for the latest published GitHub release; its version is part of the asset filename and URL. The GitHub releases page is linked from the project's release notes.
The application upgrade does not remove ~/.sc2am/config.yaml, downloaded
tracks, or <download_dir>/.sc2am/history.sqlite3. If an old config contains
settings no longer recognized by this version, keep a backup, remove or correct
only those settings, and retry sc2am doctor. To regenerate defaults, first copy
the config file and then run sc2am config init --force; this replaces only the
selected YAML file. Never remove the download folder's .sc2am directory: it
contains the journal SC2AM uses to safely resume downloads and imports.
For development, clone the repository, create and activate a virtual environment, and install the project with its development tools:
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -e '.[dev]'
The editable install is for contributors who need changes in the checkout to be available immediately. It is not an additional step for end users.
SoundCloud-Links must point to a single track, for example:
https://soundcloud.com/artist/track
or https://www.soundcloud.com/artist/track.
Mobile share links such as https://on.soundcloud.com/<token> are also accepted
by download and batch. SC2AM resolves them before validation and passes the
resolved track URL to the downloader. Resolution makes at most five HTTP HEAD
requests, with a 3-second connection and 5-second read timeout per request.
Redirects to unrelated hosts, loops, expired links, and collections are rejected;
use a fresh share link or a direct track URL if resolution fails. --dry-run
also needs a network connection for share links; direct URLs are validated locally.
Profiles, profile tabs (such as /likes or /tracks), albums, and sets are
rejected. SC2AM also checks the extracted result before downloading audio;
if it is a collection or cannot be verified as a single track, the download stops.
Download a single track:
sc2am download "https://soundcloud.com/artist/track"
Download multiple tracks in one run:
sc2am download \
"https://soundcloud.com/artist/track1" \
"https://soundcloud.com/artist/track2"
If you want to keep processing after one URL fails, use:
sc2am download \
"https://soundcloud.com/artist/track1" \
"https://soundcloud.com/artist/track2" \
--continue-on-error
Download and add to playlist:
sc2am download "https://soundcloud.com/artist/track" --playlist "My Playlist"
If you do not pass --playlist, SC2AM uses the configured default_playlist when one is set. Playlist names are matched against the playlists currently available in Apple Music, and the app will tell you clearly if the playlist is missing or if the name is duplicated.
Names containing commas, quotes or Unicode characters are supported, for example
--playlist "Road, Trip". Matching ignores case and surrounding whitespace;
the original name is preserved for the import. Choose a regular user playlist:
Smart, Genius, folder and system playlists cannot receive tracks. Duplicate
names must be renamed before importing, even when they occur in different folders.
Don't automatically open Music app:
sc2am download "https://soundcloud.com/artist/track" --no-open
For a preview that validates the input and shows the planned actions without
downloading files or accessing Music.app, add --dry-run. Use
--no-open --playlist "" when you want to disable both Music actions.
Create a file urls.txt with one URL per line:
https://soundcloud.com/artist/track1
https://soundcloud.com/artist/track2
# This is a comment
https://soundcloud.com/artist/track3
Then process all URLs:
sc2am batch urls.txt
Batch options:
# Add all tracks to a playlist
sc2am batch urls.txt --playlist "My Playlist"
# Continue processing even if a URL fails
sc2am batch urls.txt --continue-on-error
See the CLI and configuration contract for the complete interface. Precedence is explicit CLI options > environment > selected YAML file > defaults. A custom YAML file replaces the default file. Invalid YAML, unknown keys, and invalid values are reported instead of silently ignored.
SC2AM ignores external yt-dlp configuration files for both track information and
audio downloads (--ignore-config). Personal yt-dlp settings such as
--skip-download, download archives, and match filters do not affect SC2AM.
The SC2AM configuration precedence above remains unchanged.
View current configuration:
sc2am config show
Configuration File (~/.sc2am/config.yaml):
download_dir: ~/Downloads/sc2am
default_playlist: null
open_music_app: true
continue_on_error: false
log_level: INFO
log_file: null
Environment variables:
Use exported variables or prefix the command with assignments. .env files are not
loaded automatically.
SC2AM_DOWNLOAD_DIR=~/Music/Downloads SC2AM_PLAYLIST="My Playlist" SC2AM_LOG_LEVEL=DEBUG \
sc2am download "https://soundcloud.com/artist/track"
Active settings:
| Option | Type | Default | Description |
|---|---|---|---|
download_dir | Path | ~/Downloads/sc2am | MP3 destination |
default_playlist | String or null | null | Default playlist |
open_music_app | Bool | true | Automatically opens MP3s in Music |
continue_on_error | Bool | false | Continues after an input/download failure |
log_level | String | INFO | DEBUG, INFO, WARNING, ERROR, or CRITICAL |
log_file | Path or null | null | Optional detailed log file |
Both download and batch support --no-open / --open,
--continue-on-error / --stop-on-error, --playlist NAME, and --dry-run.
Omitted options inherit configuration. --playlist "" disables the configured
playlist. --no-open leaves playlist actions enabled; use both to avoid Music
interaction. Dry runs validate and preview without downloads, file writes, or
Music actions.
# Use custom config file
sc2am --config /path/to/config.yaml download "..."
# Set log level
sc2am --log-level DEBUG download "..."
Batch download with logging:
sc2am --log-level DEBUG batch urls.txt --continue-on-error
Download to custom directory:
SC2AM_DOWNLOAD_DIR=~/Music sc2am download "..."
SC2AM retries transient download failures and read-only Music queries. Mutations are confirmed against the active Music library before reporting success.
MP3 filenames include the SoundCloud track ID: Title [123456789].mp3.
Tracks with the same title and different IDs are saved separately. A local journal
in <download_dir>/.sc2am/history.sqlite3 records source IDs, verified file hashes
and Music references. Repeating a recorded URL reuses the unchanged MP3 without
network extraction, download or retagging. A new URL resolving to the same source
ID also reuses it, even if the title changed. Missing files can be downloaded
again; changed files stop with an integrity warning. Legacy title-only files are
not migrated.
Music imports store a source marker in the MP3's default English ID3 comment
(preserving existing text) so copied library files can be found after a lost
response. Confirmed persistent IDs are scoped to the active library and checked
on every run. Existing playlist membership is reused. Keep the download folder
and its .sc2am journal together; safe repeat/resume is scoped to this folder.
Do not run concurrent imports from different download folders into one library.
Existing imports from older SC2AM versions can be recognized by their original
file location; copied legacy imports without a marker/history need manual review
before the first run. Confirmation covers the local library only, not cloud sync,
iPhone availability or playback.
SC2AM only tags and imports the verified MP3 path reported by that download. Missing or invalid output paths cause a download error, even when other MP3s already exist in the directory.
SC2AM now returns stable exit codes for scripting:
0 - command completed without input/download failures1 - runtime/download failure or a run that continued past invalid entries2 - usage/configuration error or an input-validation abortMusic import/playlist failures remain warnings and do not change exit status by
default. Add --strict-import to download or batch to return 1 for failed
or unconfirmed Music stages; use --continue-on-error to continue after them.
Summaries separate downloads, confirmed local imports and playlist memberships,
including partial success. Dry runs count previews only and perform no Music
steps. Local confirmation does not verify cloud/iPhone availability.
CLI progress output is written as clean status lines. By default, Python logger output on stderr is limited to warnings and errors so informational log lines do not duplicate the CLI status messages. Explicit --log-level DEBUG (or log_level: DEBUG / SC2AM_LOG_LEVEL=DEBUG) includes diagnostic and informational logs on stderr. To retain logs in a file, configure log_file or SC2AM_LOG_FILE.
When running batch operations with multiple links or URLs from a file, SC2AM provides improved logging and summary output to help you debug and understand the results:
Example output with --no-open --playlist "" --continue-on-error:
──────────────────────────────────────────────
Track 1/3: Processing https://soundcloud.com/artist/track1
Track 1/3: Validating SoundCloud URL...
Track 1/3: OK: Valid SoundCloud URL
Track 1/3: Downloading track...
Track 1/3: OK: Downloaded: track1 [123456789].mp3
Track 1/3: Done!
──────────────────────────────────────────────
Track 2/3: Processing https://soundcloud.com/artist/track2
Track 2/3: Validating SoundCloud URL...
Track 2/3: OK: Valid SoundCloud URL
Track 2/3: Downloading track...
Track 2/3: ERROR: Track not found
──────────────────────────────────────────────
Track 3/3: Processing https://soundcloud.com/artist/track3
Track 3/3: Validating SoundCloud URL...
Track 3/3: OK: Valid SoundCloud URL
Track 3/3: Downloading track...
Track 3/3: OK: Downloaded: track3 [987654321].mp3
Track 3/3: Done!
Downloads: 2 succeeded, 1 failed (66% success rate)
Imports: not requested
Playlists: not requested
Failed tracks:
1. https://soundcloud.com/artist/track2
Error: Track not found
No log file is created by default (log_file: null). Generic errors show how to
enable diagnostics; dependency, path, URL and Music permission errors include
remedies. To see debug output on stderr, replace the example link with the failing
track URL and keep the options from the original command:
sc2am --log-level DEBUG download "https://soundcloud.com/artist/track"
sc2am --log-level DEBUG batch urls.txt --continue-on-error
To save command details, underlying yt-dlp errors and exception tracebacks in a diagnostic log, set a writable log path:
SC2AM_LOG_FILE="$PWD/sc2am-debug.log" sc2am --log-level DEBUG download "https://soundcloud.com/artist/track"
SC2AM_LOG_FILE="$PWD/sc2am-debug.log" sc2am --log-level DEBUG batch urls.txt --continue-on-error
Put global options before download or batch. If using a custom configuration,
keep --config PATH before the subcommand as well. When running from the source
checkout, replace sc2am with python main.py. A configured log file retains
underlying errors and exception tracebacks at the default INFO level too; DEBUG
adds command and progress context. These commands repeat the workflow, so check
the Music library and target playlist before retrying a failed or uncertain
import. Review logs for private URLs and local paths before sharing them.
--dry-run validates and previews only: it suppresses log-file writes and does
not reproduce download or Music failures. config show also does not write a
log file.
pip install yt-dlp --upgrade
open_music_app setting in configdocs/macos-setup.md for the full checklistosascript attempt is limited to 30 seconds. Read-only lookups retry temporary failures and timeouts up to three attempts, with 1- and 2-second delays (at most about 93 seconds).mkdir -p ~/Downloads/sc2am
chmod 755 ~/Downloads/sc2am
Contributions are welcome! Please:
git checkout -b feature/my-feature)# Install with dev dependencies
pip install -r requirements-dev.txt
# Code formatting
black --check .
# Linting
flake8 main.py sc2am tests scripts
# Tests
PYTHONPATH=. pytest -q
CI runs these checks for pull requests, main, and v* release tags. It also
builds sdist/wheel artifacts and checks the installed CLI in fresh environments
on Ubuntu and macOS, without a personal Apple account. See
release validation for scope and limitations.
Dependency source of truth:
pyproject.toml is the canonical dependency definition.requirements.txt and requirements-dev.txt are thin compatibility wrappers that install from project metadata.pyproject.toml with pip-audit; development tools are not included.MIT License - see LICENSE file for details
The current stable release line is 2.x. Older release lines are unsupported; upgrade to the latest 2.x release before requesting help.
For general issues, feature requests, or questions:
For suspected security vulnerabilities, do not open a public issue. Report them privately through GitHub Security Advisories.