Downloading audio from Soundcloud
Brandon Sanderson has been releasing a few chapters a week of his upcoming novel, Wind and Truth, on his publisher’s website leading up to its December 6th release. This includes the audiobook chapters, but they’re posted to Soundcloud and there’s no good way to listen at 1.6x speed. This post is a note sheet on how to download audio from Soundcloud and prepare it for my audiobook reader.
Get a package manager
First step is to get uv. I’ve been very excited to watch this fast tool replace many iffy Python packaging tools!
$ curl -LsSf https://astral.sh/uv/install.sh | sh
See also the full installation documentation.
Install the downloader tool
yt-dlp is a feature-rich command-line audio/video downloader with support for thousands of sites.
Second step is to install yt-dlp
using uv tool install
. uv installs the tool
and its CLI in an isolated virtual environment but makes it available globally
on your system.
$ uv tool install yt-dlp
Resolved 1 package in 106ms
Installed 1 package in 28ms
+ yt-dlp==2024.11.18
Installed 1 executable: yt-dlp
Look how fast it installs with a warm cache!
Download the audio
The chapters for Wind and Truth are indexed here. For example, you can navigate to interludes 3 and 4, scroll to the bottom, then open the Soundcloud embed in a new browser tab and copy the URL.
Third step is to invoke yt-dlp
from the console with the URL as the only
argument (in quotes!). The best thing about this tool is that it has a
plugin-based architecture, so it can deal with basically anything you give it.
$ yt-dlp "https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/1931715512%3Fsecret_token%3Ds-WvtAtAMqqkc&color=%23ff5500&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true&visual=true"
[SoundcloudEmbed] Extracting URL: https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/1931715512%3Fsecret_toke...ser=true&visual=true
[soundcloud] Extracting URL: https://api.soundcloud.com/tracks/1931715512?secret_token=s-WvtAtAMqqkc
[soundcloud] 1931715512: Downloading info JSON
[soundcloud] 1931715512: Downloading hls_mp3 format info JSON
[soundcloud] 1931715512: Downloading http_mp3 format info JSON
[soundcloud] 1931715512: Downloading hls_opus format info JSON
[info] 1931715512: Downloading 1 format(s): hls_opus_64
[hlsnative] Downloading m3u8 manifest
[hlsnative] Total fragments: 136
[download] Destination: Interludes - WIND AND TRUTH by Brandon Sanderson, narrated by Kate Reading and Michael Kramer [1931715512].opus
[download] 100% of 10.10MiB in 00:00:04 at 2.14MiB/s
Convert the audio’s format
The only issue is that it gives output in the
Opus file format, which
isn’t so easy to use. The fourth step is to convert this to
m4b for
easy use with an audiobook reader. After installing ffmpeg (e.g., with
brew install ffmpeg
), run
$ ffmpeg \
-i "Interludes - WIND AND TRUTH by Brandon Sanderson, narrated by Kate Reading and Michael Kramer [1931715512].opus" \
-c:a aac -b:a 128k -vn -f ipod interludes-3-and-4.m4b
ffmpeg version 7.1 Copyright (c) 2000-2024 the FFmpeg developers
built with Apple clang version 16.0.0 (clang-1600.0.26.4)
configuration: --prefix=/opt/homebrew/Cellar/ffmpeg/7.1_3 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags='-Wl,-ld_classic' --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libaribb24 --enable-libbluray --enable-libdav1d --enable-libharfbuzz --enable-libjxl --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox --enable-audiotoolbox --enable-neon
libavutil 59. 39.100 / 59. 39.100
libavcodec 61. 19.100 / 61. 19.100
libavformat 61. 7.100 / 61. 7.100
libavdevice 61. 3.100 / 61. 3.100
libavfilter 10. 4.100 / 10. 4.100
libswscale 8. 3.100 / 8. 3.100
libswresample 5. 3.100 / 5. 3.100
libpostproc 58. 3.100 / 58. 3.100
Input #0, ogg, from 'Interludes - WIND AND TRUTH by Brandon Sanderson, narrated by Kate Reading and Michael Kramer [1931715512].opus':
Duration: 00:22:12.36, start: 0.000000, bitrate: 63 kb/s
Stream #0:0: Audio: opus, 48000 Hz, stereo, fltp
Metadata:
encoder : Lavc58.91.100 libopus
Stream mapping:
Stream #0:0 -> #0:0 (opus (native) -> aac (native))
Press [q] to stop, [?] for help
Output #0, ipod, to 'interludes-3-and-4.m4b':
Metadata:
encoder : Lavf61.7.100
Stream #0:0: Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s
Metadata:
encoder : Lavc61.19.100 aac
[out#0/ipod @ 0x6000016e4000] video:0KiB audio:20840KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: 1.175908%
size= 21086KiB time=00:22:12.34 bitrate= 129.6kbits/s speed=43.8x
[aac @ 0x151004f50] Qavg: 668.452
Easy listening
I’m using BookPlayer, an open source project to listen to books. I usually sync them by using AirDrop to send the m4b files to my phone, then using its import menu.
Happy listening!
P.S., I wrote a script that automates crawling the Wind and Truth index, downloading, and converting these files.