HOW TO: Offload videos (but not images) from the WordPress Media Library to AWS S3

February 10, 2021

The Memberpress plugin has an awesome add-on in their Pro and Plus versions that allow developers to easily connect to an S3 bucket and display videos hosted their based on membership permissions (Memberpress AWS).

This allows you to keep costs low and storage usage on the WordPress server conservative. The one big drawback is that you can't upload the videos through wp-admin out-of-the-box.

Instead, you need to upload the videos through the AWS console itself or with CLI.

The folks at Delicious Brains have a great free plugin that allows you to offload all files uploaded through WordPress's Media Library to S3 automatically called WP Offload Media Lite for Amazon S3, DigitalOcean Spaces, and Google Cloud Storage.

With this plugin, uploaded files are added to your web server like normal, then they're piped to the S3 bucket before being removed from local.

This is almost a perfect solution for our Membepress use-case, however there is one catch.

In most cases, the S3 bucket that hosts video for Memberpress will be configured as "private" - meaning that the files cannot be publicly accessed without the proper authentication keys being passed in the request. This is perfect for videos, as you only want members to be able to access them.

It's not so perfect for all the other types of files you upload (ie. .png, .jpg, etc.). For example, anytime you upload an image for a public facing page - it will return a 403.

Ultimately we only want the WP Offload Media Lite plugin to send videos to S3 and leave everything else local. Thankfully, it's as easy as adding a snippet to your theme's functions.php or into a small plugin.

Here's the code:

# Support for Media Offload to S3 Lite to only offload video to S3
function s3pl_as3cf_pre_upload_attachment( $abort, $post_id, $metadata ) {
	$file      = get_post_meta( $post_id, '_wp_attached_file', true );
	$extension = is_string( $file ) ? pathinfo( $file, PATHINFO_EXTENSION ) : false;
	if ( is_string( $extension ) && !in_array( $extension, array( 'mp4', 'avi' ) ) ) {
		$abort = true; // abort the upload
	}
	return $abort;
}
add_filter( 'as3cf_pre_upload_attachment', 's3pl_as3cf_pre_upload_attachment', 10, 3 );

This will only upload files with the extension specified in the $extension array, which is 'mp4', 'avi' in this example.