diff --git a/config/config.go b/config/config.go index 027d76751..3451e2860 100644 --- a/config/config.go +++ b/config/config.go @@ -79,13 +79,14 @@ type files struct { //s3 is for configuring the s3 integration type s3 struct { - Enabled bool `yaml:"enabled"` - Endpoint string `yaml:"endpoint"` - AccessKey string `yaml:"accessKey"` - Secret string `yaml:"secret"` - Bucket string `yaml:"bucket"` - Region string `yaml:"region"` - ACL string `yaml:"acl"` + Enabled bool `yaml:"enabled"` + Endpoint string `yaml:"endpoint"` + ServingEndpoint string `yaml:"servingEndpoint"` + AccessKey string `yaml:"accessKey"` + Secret string `yaml:"secret"` + Bucket string `yaml:"bucket"` + Region string `yaml:"region"` + ACL string `yaml:"acl"` } func (c *config) load(filePath string) error { diff --git a/core/storageproviders/s3Storage.go b/core/storageproviders/s3Storage.go index e6f884def..77d61a7a5 100644 --- a/core/storageproviders/s3Storage.go +++ b/core/storageproviders/s3Storage.go @@ -2,6 +2,7 @@ package storageproviders import ( "bufio" + "fmt" "os" "strings" @@ -21,12 +22,13 @@ type S3Storage struct { sess *session.Session host string - s3Endpoint string - s3Region string - s3Bucket string - s3AccessKey string - s3Secret string - s3ACL string + s3Endpoint string + s3ServingEndpoint string + s3Region string + s3Bucket string + s3AccessKey string + s3Secret string + s3ACL string } //Setup sets up the s3 storage for saving the video to s3 @@ -34,6 +36,7 @@ func (s *S3Storage) Setup() error { log.Trace("Setting up S3 for external storage of video...") s.s3Endpoint = config.Config.S3.Endpoint + s.s3ServingEndpoint = config.Config.S3.ServingEndpoint s.s3Region = config.Config.S3.Region s.s3Bucket = config.Config.S3.Bucket s.s3AccessKey = config.Config.S3.AccessKey @@ -90,6 +93,8 @@ func (s *S3Storage) GenerateRemotePlaylist(playlist string, variant models.Varia fullRemotePath := variant.GetSegmentForFilename(line) if fullRemotePath == nil { line = "" + } else if s.s3ServingEndpoint != "" { + line = fmt.Sprintf("%s/%s/%s", s.s3ServingEndpoint, config.Config.GetPrivateHLSSavePath(), fullRemotePath.RelativeUploadPath) } else { line = fullRemotePath.RemoteID } diff --git a/doc/S3.md b/doc/S3.md index 8e95de9fe..b660e8aa1 100644 --- a/doc/S3.md +++ b/doc/S3.md @@ -110,6 +110,10 @@ You should expire old segments on your S3 bucket. [Here are some instructions o * Ugh. CORS. [You will need to enable CORS on your bucket](https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html#how-do-i-enable-cors) so the web player can access the video. +### CDN + +AWS (and other S3 compatible providers) offer a feature to change the HTTP host to support CDNs. You can configure Owncast to serve media files from this host by setting the `s3.servingEndpoint` config to your CDNed host. + ## [Wasabi cloud storage](https://wasabi.com/content-delivery/) diff --git a/doc/config-example-full.yaml b/doc/config-example-full.yaml index 425087c49..da83c764d 100644 --- a/doc/config-example-full.yaml +++ b/doc/config-example-full.yaml @@ -70,6 +70,7 @@ files: s3: enabled: false endpoint: https://s3.us-west-2.amazonaws.com + servingEndpoint: https://yourcdn.example accessKey: ABC12342069 secret: lolomgqwtf49583949 region: us-west-2