Offload Listenup audio files to cloud storage providers to reduce server bandwidth and improve delivery performance.
Overview
Cloud storage is completely optional and disabled by default. ListenUp works perfectly with local storage for most sites.
Consider cloud storage if you:
- Have high traffic volume
- Want to reduce server bandwidth usage
- Need geographic distribution (CDN)
- Want to separate media delivery from your web server
Supported providers:
- Amazon S3
- Cloudflare R2
- Google Cloud Storage
Benefits
Reduced Bandwidth
Audio files are served directly from cloud infrastructure, not your web server. This reduces:
- Server load
- Bandwidth costs (if your host charges for bandwidth)
- Risk of server overload during traffic spikes
Improved Performance
Cloud providers have global infrastructure:
- Files served from edge locations closer to users
- High-capacity networks designed for media delivery
- Better performance for international audiences
Signed URL Security
All cloud URLs are signed with expiration times:
- URLs are time-limited (prevents permanent sharing)
- Fresh URLs generated for each request
- Prevents unauthorized access and hotlinking
AWS S3 Configuration
Step 1: Create an S3 Bucket
- Log into AWS Console
- Go to S3 service
- Click Create bucket
- Enter a unique bucket name (e.g.,
mysite-listenup-audio) - Select your preferred region
- Keep “Block all public access” enabled (signed URLs don’t require public access)
- Click Create bucket
Step 2: Create IAM Credentials
- Go to IAM service
- Click Users → Create user
- Enter a username (e.g.,
listenup-s3-user) - Click Next
- Select Attach policies directly
- Click Create policy and use this JSON:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::your-bucket-name",
"arn:aws:s3:::your-bucket-name/*"
]
}
]
}
- Name the policy (e.g.,
ListenUpS3Policy) - Attach the policy to your user
- Create the user
- Go to Security credentials tab
- Create an Access key (select “Application running outside AWS”)
- Save the Access Key ID and Secret Access Key
Step 3: Configure in ListenUp
- Go to Settings → ListenUp → Cloud Storage
- Select Amazon S3 as provider
- Enter your credentials:
- Access Key ID
- Secret Access Key
- Bucket Name
- Region (e.g.,
us-east-1)
- Click Test Connection to verify
- Enable cloud storage
- Save settings
Optional: Custom Endpoint
For S3-compatible services (DigitalOcean Spaces, Linode Object Storage, etc.):
- Enter the service endpoint URL
- Configure region as required by the service
Cloudflare R2 Configuration
Cloudflare R2 offers S3-compatible storage with no egress fees.
Step 1: Create an R2 Bucket
- Log into Cloudflare Dashboard
- Go to R2 in the sidebar
- Click Create bucket
- Enter a bucket name
- Select location (optional)
- Click Create bucket
Step 2: Create API Credentials
- In R2 settings, go to Manage R2 API Tokens
- Click Create API token
- Configure permissions:
- Object Read & Write – Required
- Specify bucket or allow all buckets
- Click Create API Token
- Save the credentials:
- Access Key ID
- Secret Access Key
Step 3: Get Account ID and Endpoint
- Your Account ID is in the dashboard URL or R2 overview
- The endpoint format is:
https://<account-id>.r2.cloudflarestorage.com
Step 4: Configure in ListenUp
- Go to Settings → ListenUp → Cloud Storage
- Select Cloudflare R2 as provider
- Enter your credentials:
- Access Key ID
- Secret Access Key
- Bucket Name
- Account ID
- Click Test Connection to verify
- Enable cloud storage
- Save settings
R2 Benefits
- No egress fees – Pay only for storage, not downloads
- S3-compatible – Works with existing S3 tools
- Global network – Cloudflare’s edge network
Google Cloud Storage Configuration
Step 1: Create a GCS Bucket
- Log into Google Cloud Console
- Go to Cloud Storage → Buckets
- Click Create
- Enter a unique bucket name
- Select location type and region
- Choose Standard storage class for frequently accessed files
- Keep default access control (Uniform)
- Click Create
Step 2: Create Service Account
- Go to IAM & Admin → Service Accounts
- Click Create Service Account
- Enter a name (e.g.,
listenup-storage) - Click Create and Continue
- Grant the Storage Object Admin role
- Click Continue → Done
Step 3: Create Service Account Key
- Click on the service account you created
- Go to Keys tab
- Click Add Key → Create new key
- Select JSON format
- Click Create
- Save the downloaded JSON file securely
Step 4: Configure in ListenUp
- Go to Settings → ListenUp → Cloud Storage
- Select Google Cloud Storage as provider
- Enter your credentials:
- Bucket Name
- Service Account JSON – Paste the entire contents of the JSON key file
- Click Test Connection to verify
- Enable cloud storage
- Save settings
GCS Benefits
- Integrated with Google Cloud – If you already use GCP
- Multi-regional options – Global redundancy available
- Fine-grained IAM – Detailed access control
Migrating Existing Audio
When you enable cloud storage, new audio files are automatically uploaded. Existing local files need to be migrated.
Using WP-CLI (Recommended)
# Upload all local files to cloud
wp listenup cloud-upload --all
# Upload specific post
wp listenup cloud-upload --post-id=123
# Re-upload existing cloud files
wp listenup cloud-upload --all --force
# Dry run to see what would be uploaded
wp listenup cloud-upload --all --dry-run
From Admin Interface
- Go to Settings → ListenUp → Audio Library
- Filter by Storage: Local
- Use bulk actions to upload selected posts
Managing Cloud Files
Deleting Audio
When you delete audio from a post:
- Local file is deleted from server
- Cloud file is also deleted (if enabled in settings)
Regenerating Audio
When you regenerate audio:
- Old local file is replaced
- New file is uploaded to cloud
- Old cloud file is deleted
Checking Storage Status
View storage location for all posts:
- Go to Settings → ListenUp → Audio Library
- Storage column shows: Local, Cloud, or both
CORS Configuration
If you experience CORS errors, configure your bucket:
S3 CORS
In bucket settings → Permissions → CORS:
[
{
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET", "HEAD"],
"AllowedOrigins": ["https://yoursite.com"],
"ExposeHeaders": [],
"MaxAgeSeconds": 3600
}
]
R2 CORS
In bucket settings → Settings → CORS Policy:
[
{
"AllowedOrigins": ["https://yoursite.com"],
"AllowedMethods": ["GET", "HEAD"],
"AllowedHeaders": ["*"],
"MaxAgeSeconds": 3600
}
]
GCS CORS
Using gsutil:
gsutil cors set cors.json gs://your-bucket-name
Where cors.json contains:
[
{
"origin": ["https://yoursite.com"],
"method": ["GET", "HEAD"],
"responseHeader": ["Content-Type"],
"maxAgeSeconds": 3600
}
]
Signed URL Expiration
Cloud storage URLs include expiration times for security.
How It Works
- Player initializes on page load
- AJAX request fetches fresh signed URL
- URL is valid for limited time (typically 1 hour)
- New URL generated if needed for downloads
Page Caching Compatibility
ListenUp fetches URLs via AJAX, so:
- Works with all page caching plugins
- Works with CDN caching (Cloudflare, Varnish)
- URLs are always fresh regardless of page cache age
This was improved in version 1.5.13 to prevent expired URL issues.
Cost Considerations
AWS S3 Pricing
- Storage: ~$0.023/GB/month (varies by region)
- Requests: ~$0.005 per 1,000 GET requests
- Data transfer: ~$0.09/GB (first 10TB/month)
Cloudflare R2 Pricing
- Storage: $0.015/GB/month
- Requests: $0.36 per million Class A operations
- Data transfer: Free (no egress fees)
Google Cloud Storage
- Storage: ~$0.020/GB/month (Standard class)
- Requests: $0.05 per 10,000 Class B operations
- Data transfer: ~$0.12/GB (varies by region)
Tip: Cloudflare R2 is often most cost-effective due to free egress.
Troubleshooting
Connection Test Fails
- Verify credentials are correct
- Check bucket name and region
- Verify IAM permissions
- Check network connectivity from server
Upload Fails
- Check bucket write permissions
- Verify bucket exists
- Check for storage quota limits
- Review debug.log for detailed errors
Audio Not Playing from Cloud
- Check CORS configuration
- Verify signed URL is being generated
- Check browser console for errors
- Try clearing page cache
See full Troubleshooting Guide →
Security Best Practices
- Use dedicated credentials – Don’t use root/admin credentials
- Minimum permissions – Only grant required permissions
- Rotate credentials – Periodically rotate access keys
- Enable bucket logging – Monitor access patterns
- Keep bucket private – Don’t enable public access; signed URLs handle access