🎵 HLS Audio Upload Guide

Mac Terminal Workflow — Complete Documentation

1 FFmpeg Installation

Step 1: Install Homebrew

Terminal
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
📦
What happened: Downloaded Homebrew package manager
Installed to /usr/local/Homebrew
Created directories: /usr/local/share/zsh, /usr/local/var/homebrew
Downloaded dependencies: cmake, json-c, libunistring, gettext, pkgconf, pcre2

Step 2: Add Homebrew to PATH

Terminal
echo 'eval "$(/usr/local/bin/brew shellenv)"' >> ~/.zprofile
eval "$(/usr/local/bin/brew shellenv)"

Step 3: Verify Homebrew

Terminal
brew --version
Homebrew 6.0.17

Step 4: Attempt FFmpeg Install via Homebrew (FAILED)

Terminal
brew install ffmpeg
❌
Error encountered: Error: Failed to download resource "opus (1.6.1)"
Download failed: https://github.com/xiph/opus/releases/download/v1.6.1/opus-1.6.1.tar.gz
curl: (22) The requested URL returned error: 404

Reason: The Opus dependency URL was broken on the server.

Step 5: Download Static FFmpeg Build (SUCCESS)

✅
Visited: https://evermeet.cx/ffmpeg/
Downloaded: ffmpeg-126126-gdab32dcc212.zip

Step 6: Install Static FFmpeg

Terminal
cd ~/Downloads
unzip ffmpeg-126126-gdab32dcc212.zip
sudo mkdir -p /usr/local/bin
sudo mv ffmpeg /usr/local/bin/
sudo chmod +x /usr/local/bin/ffmpeg
sudo xattr -dr com.apple.quarantine /usr/local/bin/ffmpeg

Command Breakdown:

CommandPurpose
cd ~/DownloadsNavigate to Downloads folder
unzip ffmpeg-*.zipExtract FFmpeg binary
sudo mkdir -p /usr/local/binCreate bin directory
sudo mv ffmpeg /usr/local/bin/Move FFmpeg to bin
sudo chmod +xMake executable
sudo xattr -dr com.apple.quarantineRemove macOS Catalina quarantine

Step 7: Verify FFmpeg

Terminal
ffmpeg -version
ffmpeg version N-126126-gdab32dcc212-tessus built with Apple clang version 17.0.0 configuration: --cc=/usr/bin/clang --prefix=/opt/ffmpeg --enable-avisynth --enable-gpl --enable-libaom --enable-libmp3lame --enable-libopus --enable-libx264 --enable-libx265 --enable-version3

2 Verifying Installation

Check AAC Encoder

Terminal
ffmpeg -encoders 2>&1 | grep aac

Check HLS Format

Terminal
ffmpeg -formats 2>&1 | grep hls

Test Conversion

Terminal
ffmpeg -f lavfi -i "sine=frequency=440:duration=2" -c:a aac -f hls -hls_time 10 -hls_playlist_type vod -hls_segment_filename "test_%03d.ts" "test.m3u8"

Check Test Output

Terminal
ls -la test*
test.m3u8 test_000.ts

Clean Up Test Files

Terminal
rm test.m3u8 test_*.ts

🎚️ Mastering Your Track

Before converting to HLS, your audio should be properly mastered for streaming. Here's the complete mastering workflow used for "Only Now".

Mastering Chain Overview

OrderProcessPurpose
1EQ (Equalization)Balance frequencies
2CompressionControl dynamics
3Stereo EnhancementWiden the sound
4LimitingSet final loudness
5Loudness NormalizationMatch streaming standards

Streaming Loudness Standards

PlatformTarget LUFSTrue Peak
Spotify-14 LUFS-1 dBTP
Apple Music-16 LUFS-1 dBTP
YouTube-14 LUFS-1 dBTP
This Platform-14 LUFS-1 dBTP

Mastering with FFmpeg

Step 1: Check Current Loudness

Terminal
ffmpeg -i "Only_now_Written_by_Daniel_Mason_Track_02_master.wav" -af loudnorm=print_format=json -f null - 2>&1 | grep -E "input_i|input_tp|input_lra|input_thresh"
"input_i" : "-18.23", "input_tp" : "-3.45", "input_lra" : "11.20", "input_thresh" : "-28.35",

Step 2: Apply Loudness Normalization

Terminal
ffmpeg -i "Only_now_Written_by_Daniel_Mason_Track_02_master.wav" \
  -af loudnorm=I=-14:TP=-1:LRA=11 \
  -c:a pcm_s16le \
  "Only_now_Mastered_14LUFS.wav"

Step 3: Apply EQ (Bass Boost + Presence)

Terminal
ffmpeg -i "Only_now_Mastered_14LUFS.wav" \
  -af "equalizer=f=60:width_type=o:width=2:g=2,equalizer=f=120:width_type=o:width=1:g=1,equalizer=f=3000:width_type=o:width=1:g=1.5,equalizer=f=10000:width_type=o:width=2:g=1" \
  -c:a pcm_s16le \
  "Only_now_Mastered_EQ.wav"

Step 4: Apply Compression

Terminal
ffmpeg -i "Only_now_Mastered_EQ.wav" \
  -af "acompressor=threshold=-18dB:ratio=3:1:attack=20:release=250:makeup=3" \
  -c:a pcm_s16le \
  "Only_now_Mastered_Comp.wav"

Step 5: Apply Final Limiter

Terminal
ffmpeg -i "Only_now_Mastered_Comp.wav" \
  -af "alimiter=limit=-1dB:attack=5:release=50" \
  -c:a pcm_s16le \
  "Only_now_FINAL_MASTER.wav"

Complete Mastering Chain (One Command)

Terminal
ffmpeg -i "input.wav" \
  -af "loudnorm=I=-14:TP=-1:LRA=11,equalizer=f=60:width_type=o:width=2:g=2,equalizer=f=3000:width_type=o:width=1:g=1.5,acompressor=threshold=-18dB:ratio=3:1:attack=20:release=250:makeup=3,alimiter=limit=-1dB:attack=5:release=50" \
  -c:a pcm_s16le \
  "output_FINAL_MASTER.wav"

Mastering Chain Parameters

ProcessParameterValuePurpose
Loudness NormI=-14-14 LUFSMatch Spotify/YouTube standard
True PeakTP=-1-1 dBTPPrevent clipping
LRALRA=1111 LUDynamic range target
EQ: Bassf=60, g=2+2 dB @ 60HzAdd low-end warmth
EQ: Presencef=3000, g=1.5+1.5 dB @ 3kHzAdd vocal clarity
Compressorthreshold=-18dB-18 dBStart compression
Ratioratio=3:13:1Moderate compression
Attackattack=2020msFast attack
Releaserelease=250250msSmooth release
Limiterlimit=-1dB-1 dBAbsolute ceiling

Mastering Checklist

✅
Before converting to HLS:
☐ Loudness normalized to -14 LUFS
☐ True peak at -1 dBTP
☐ EQ balanced (no harsh frequencies)
☐ Compression applied (3:1 ratio)
☐ Limiter set at -1dB ceiling
☐ No clipping or distortion
☐ Exported as 16-bit WAV (pcm_s16le)

Verify Final Master

Terminal
ffmpeg -i "Only_now_FINAL_MASTER.wav" -af loudnorm=print_format=json -f null - 2>&1 | grep -E "input_i|input_tp|input_lra"
"input_i" : "-14.02", "input_tp" : "-1.01", "input_lra" : "10.95",
⚠️
Important: If your track was already mastered professionally, skip the mastering chain and just apply loudness normalization to match streaming standards.

3 Converting Audio to HLS

Navigate to Audio Folder

Terminal
cd ~/Desktop/amusicconvert

Get Duration First

Terminal
ffmpeg -i "Only_now_Written_by_Daniel_Mason_Track_02_master.wav" 2>&1 | grep Duration
Duration: 00:03:26.00, bitrate: 2304 kb/s

Duration in seconds: 3 × 60 + 26 = 206 seconds

Convert WAV to HLS

Terminal
ffmpeg -i "Only_now_Written_by_Daniel_Mason_Track_02_master.wav" -c:a aac -b:a 128k -f hls -hls_time 10 -hls_playlist_type vod -hls_segment_filename "Only_now_%03d.ts" "Only_now.m3u8"

Command Breakdown:

FlagPurpose
-i "file.wav"Input file
-c:a aacAudio codec: AAC
-b:a 128kBitrate: 128 kbps
-f hlsFormat: HLS
-hls_time 1010 seconds per segment
-hls_playlist_type vodVideo on Demand
-hls_segment_filename "name_%03d.ts"Segment naming pattern
"name.m3u8"Output playlist file

Check Output Files

Terminal
ls -la Only_now*
Only_now.m3u8 ← Playlist file Only_now_000.ts ← Segment 1 (0-10s) Only_now_001.ts ← Segment 2 (10-20s) Only_now_002.ts ← Segment 3 (20-30s) ... Only_now_020.ts ← Segment 21 (200-206s)

4 Getting Duration

Method 1: From FFmpeg

Terminal
ffmpeg -i "filename.wav" 2>&1 | grep Duration

Method 2: Manual Calculation

Duration: 00:03:26.00 = 3 minutes + 26 seconds = (3 × 60) + 26 = 180 + 26 = 206 seconds

5 Uploading to Platform

Step 1: Login

Go to: https://www.jaysoftware.co.uk/af/music/tenant_login.php

Step 2: Go to Upload Page

Go to: https://www.jaysoftware.co.uk/af/music/admin/upload_advanced.php

Step 3: Fill in Track Details

FieldValue
Upload TypePre-converted HLS
Track TitleOnly Now
GenreSelect genre
Price£4.99
Duration206

Step 4: Upload Files

FileDescription
Only_now.m3u8HLS Playlist
Only_now_000.ts through Only_now_020.tsAudio segments (select all)

Step 5: Submit

Click "Upload Track"

6 Troubleshooting

❌ command not found: ffmpeg

Fix:
sudo mv ~/Downloads/ffmpeg /usr/local/bin/
sudo chmod +x /usr/local/bin/ffmpeg

❌ Illegal instruction: 4

Fix: Remove quarantine
sudo xattr -dr com.apple.quarantine /usr/local/bin/ffmpeg

❌ Homebrew fails on macOS 10.15

Fix:

Use static download from evermeet.cx/ffmpeg

❌ Opus download 404

Fix:

The static build includes Opus already — no need to install separately.

📜 Complete Terminal History

Full History
# Homebrew Install
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
echo 'eval "$(/usr/local/bin/brew shellenv)"' >> ~/.zprofile
eval "$(/usr/local/bin/brew shellenv)"
brew --version
brew install ffmpeg  # FAILED - opus 404 error

# Static FFmpeg Download & Install
cd ~/Downloads
unzip ffmpeg-126126-gdab32dcc212.zip
sudo mkdir -p /usr/local/bin
sudo mv ffmpeg /usr/local/bin/
sudo chmod +x /usr/local/bin/ffmpeg
sudo xattr -dr com.apple.quarantine /usr/local/bin/ffmpeg
ffmpeg -version

# Mastering Chain
ffmpeg -i "input.wav" -af loudnorm=print_format=json -f null - 2>&1 | grep -E "input_i|input_tp|input_lra"
ffmpeg -i "input.wav" -af "loudnorm=I=-14:TP=-1:LRA=11,equalizer=f=60:width_type=o:width=2:g=2,equalizer=f=3000:width_type=o:width=1:g=1.5,acompressor=threshold=-18dB:ratio=3:1:attack=20:release=250:makeup=3,alimiter=limit=-1dB:attack=5:release=50" -c:a pcm_s16le "output_FINAL_MASTER.wav"

# Convert Audio
cd ~/Desktop/amusicconvert
ffmpeg -i "Only_now_Written_by_Daniel_Mason_Track_02_master.wav" 2>&1 | grep Duration
ffmpeg -i "Only_now_Written_by_Daniel_Mason_Track_02_master.wav" -c:a aac -b:a 128k -f hls -hls_time 10 -hls_playlist_type vod -hls_segment_filename "Only_now_%03d.ts" "Only_now.m3u8"
ls -la Only_now*

🔑 Key Takeaways

1

Homebrew works but may fail on older macOS versions

2

Static FFmpeg from evermeet.cx is the most reliable option

3

Always remove quarantine on macOS Catalina with xattr -dr

4

Master to -14 LUFS for streaming compatibility

5

Duration = (minutes × 60) + seconds

6

Upload .m3u8 + ALL .ts files together

7

Server doesn't have FFmpeg — always pre-convert locally