Skip to main content

Overview

The AWS S3 storage client enables automatic upload of recorded streams, VOD files, and preview images to Amazon S3 or any S3-compatible storage service (DigitalOcean Spaces, Wasabi, OVH, Minio, etc.).

Features

S3-Compatible

Works with Amazon S3 and any S3-compatible service

Multipart Upload

Automatic multipart upload for large files (>5MB)

Storage Classes

Support for all S3 storage classes (Standard, Glacier, etc.)

Custom Permissions

Full control over ACLs and access permissions

Configuration

Spring Bean Configuration

Add the S3 storage client bean to your application’s red5-web.xml:
<bean id="app.storageClient" class="io.antmedia.storage.AmazonS3StorageClient">
  <property name="enabled" value="true" />
  <property name="storageName" value="your-bucket-name" />
  <property name="accessKey" value="YOUR_ACCESS_KEY" />
  <property name="secretKey" value="YOUR_SECRET_KEY" />
  <property name="region" value="us-east-1" />
  <property name="permission" value="public-read" />
  <property name="storageClass" value="STANDARD" />
</bean>

S3-Compatible Services

For S3-compatible services (DigitalOcean, Wasabi, OVH, etc.), specify a custom endpoint:
<bean id="app.storageClient" class="io.antmedia.storage.AmazonS3StorageClient">
  <property name="enabled" value="true" />
  <property name="storageName" value="your-bucket-name" />
  <property name="accessKey" value="YOUR_ACCESS_KEY" />
  <property name="secretKey" value="YOUR_SECRET_KEY" />
  <property name="region" value="us-east-1" />
  <property name="endpoint" value="https://nyc3.digitaloceanspaces.com" />
  <property name="pathStyleAccessEnabled" value="false" />
</bean>

Configuration Parameters

ParameterTypeDescriptionRequiredDefault
enabledbooleanEnable S3 storage integrationYesfalse
storageNamestringS3 bucket nameYes-
accessKeystringAWS access key IDYes*-
secretKeystringAWS secret access keyYes*-
regionstringAWS region (e.g., us-east-1, eu-west-1)Yes-
endpointstringCustom S3 endpoint for S3-compatible servicesNo-
permissionstringFile ACL permissionsNopublic-read
cacheControlstringCache-Control header valueNono-store, no-cache, must-revalidate, max-age=0
storageClassstringS3 storage classNoSTANDARD
pathStyleAccessEnabledbooleanUse path-style access instead of virtual-hosted-styleNofalse
multipartUploadThresholdlongFile size threshold for multipart upload (bytes)No5242880 (5MB)
transferBufferSizeintTransfer buffer size for uploadsNo-
IAM Credentials: If running on EC2, you can use IAM roles instead of providing accessKey and secretKey. Leave them unset to use instance credentials.

Storage Classes

S3 supports multiple storage classes for cost optimization:
  • STANDARD - Frequent access, low latency
  • STANDARD_IA - Infrequent access
  • INTELLIGENT_TIERING - Automatic cost optimization
  • ONEZONE_IA - Lower cost, single AZ
  • GLACIER - Archive with retrieval time
  • GLACIER_IR - Instant retrieval archive
  • DEEP_ARCHIVE - Lowest cost, long-term archive
<property name="storageClass" value="INTELLIGENT_TIERING" />

Permission (ACL) Options

Configure file access permissions:
PermissionDescription
public-readPublic read access, owner has full control
privateOnly owner has access
public-read-writePublic read and write access
authenticated-readAWS authenticated users can read
bucket-owner-readBucket owner can read
bucket-owner-full-controlBucket owner has full control
aws-exec-readEC2 can read for image bundles
log-delivery-writeLog Delivery group can write
<property name="permission" value="private" />

AWS IAM Setup

Required IAM Permissions

Create an IAM user or role with these permissions:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:PutObjectAcl",
        "s3:GetObject",
        "s3:DeleteObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::your-bucket-name/*",
        "arn:aws:s3:::your-bucket-name"
      ]
    }
  ]
}

Advanced Configuration

Multipart Upload

Large files are automatically uploaded using multipart upload. Configure the threshold:
<property name="multipartUploadThreshold" value="10485760" /> <!-- 10MB -->

Path-Style Access

Some S3-compatible services require path-style access:
<property name="pathStyleAccessEnabled" value="true" />
Virtual-hosted-style: https://bucket-name.s3.amazonaws.com/key
Path-style: https://s3.amazonaws.com/bucket-name/key

Progress Monitoring

Monitor upload progress programmatically:
ProgressListener progressListener = progressEvent -> {
    if (progressEvent.getEventType() == ProgressEventType.TRANSFER_COMPLETED_EVENT) {
        logger.info("Upload completed");
    } else if (progressEvent.getEventType() == ProgressEventType.TRANSFER_FAILED_EVENT) {
        logger.error("Upload failed");
    }
};

storageClient.save(key, file, true, progressListener);

Common Use Cases

DigitalOcean Spaces

<bean id="app.storageClient" class="io.antmedia.storage.AmazonS3StorageClient">
  <property name="enabled" value="true" />
  <property name="storageName" value="my-space-name" />
  <property name="accessKey" value="DO_SPACES_KEY" />
  <property name="secretKey" value="DO_SPACES_SECRET" />
  <property name="region" value="nyc3" />
  <property name="endpoint" value="https://nyc3.digitaloceanspaces.com" />
</bean>

Wasabi

<bean id="app.storageClient" class="io.antmedia.storage.AmazonS3StorageClient">
  <property name="enabled" value="true" />
  <property name="storageName" value="my-bucket" />
  <property name="accessKey" value="WASABI_KEY" />
  <property name="secretKey" value="WASABI_SECRET" />
  <property name="region" value="us-east-1" />
  <property name="endpoint" value="https://s3.wasabisys.com" />
</bean>

MinIO (Self-Hosted)

<bean id="app.storageClient" class="io.antmedia.storage.AmazonS3StorageClient">
  <property name="enabled" value="true" />
  <property name="storageName" value="my-bucket" />
  <property name="accessKey" value="MINIO_ACCESS_KEY" />
  <property name="secretKey" value="MINIO_SECRET_KEY" />
  <property name="region" value="us-east-1" />
  <property name="endpoint" value="http://minio.example.com:9000" />
  <property name="pathStyleAccessEnabled" value="true" />
</bean>

File Operations

Upload Files

// Upload and delete local file
storageClient.save("recordings/stream123.mp4", file, true);

// Upload and keep local file
storageClient.save("recordings/stream123.mp4", file, false);

// Upload from input stream with wait
storageClient.save("recordings/stream123.mp4", inputStream, true);

Delete Files

// Delete single file
storageClient.delete("recordings/stream123.mp4");

// Delete multiple files matching pattern
storageClient.deleteMultipleFiles("recordings/stream123", ".*\\.mp4$");

Check File Existence

boolean exists = storageClient.fileExist("recordings/stream123.mp4");

Retrieve Files

InputStream stream = storageClient.get("recordings/stream123.mp4");

Troubleshooting

  • Verify your endpoint URL is correct
  • Check firewall rules allow outbound HTTPS (443)
  • Increase connection timeout if needed (default: 120 seconds)
  • Verify accessKey and secretKey are correct
  • Check IAM permissions include required S3 actions
  • Ensure bucket name matches exactly (case-sensitive)
  • Verify storageName (bucket name) is correct
  • Check region matches bucket region
  • For S3-compatible services, verify endpoint is correct
  • Confirm enabled is set to true
  • Check application logs for error details
  • Verify network connectivity to S3/endpoint
  • Test with small file first

Performance Tuning

Connection Pool

The S3 client uses a connection pool with these defaults:
  • Max connections: 100
  • Connection timeout: 120 seconds
  • Max retries: 15
These are optimized for most use cases but can be adjusted in the source code if needed.

Transfer Manager

Multipart uploads use AWS Transfer Manager for optimal performance:
  • Automatic parallel part uploads
  • Automatic retry on failures
  • Progress tracking
Important: Uploads are asynchronous by default. Use waitForCompletion parameter if you need synchronous behavior.

Security Best Practices

1

Use IAM Roles

On EC2/ECS, use IAM roles instead of hardcoded credentials.
2

Restrict Permissions

Grant only necessary S3 permissions (PutObject, GetObject, DeleteObject).
3

Enable Encryption

Configure S3 bucket encryption (SSE-S3, SSE-KMS) for data at rest.
4

Use Private ACLs

For sensitive content, use private permission instead of public-read.
5

Enable Versioning

Enable S3 bucket versioning to protect against accidental deletions.
Configuration File Location: red5-web.xml is typically located at /usr/local/antmedia/webapps/YourApp/WEB-INF/red5-web.xml

Build docs developers (and LLMs) love