I’m trying to use CloudFront as a CDN for my video on demand website.
I’ve created a HTTP distribution (because I need to stream to iOS devices, so RTMP is unsuitable), and set the origin to be my S3 bucket where my video files are stored. I’ve also created a CloudFront key pair.
Using the AWS PHP SDK, I create a signed URL like this (in Laravel):
$cloudfront = AWS::get('CloudFront');
$streamHostUrl = 'http://REDACTED.cloudfront.net';
$resourceKey = 'videos/output/hls/REDACTED.m3u8';
$expires = '+10 minutes';
$signed_url = $cloudfront->getSignedUrl(array(
'url' => sprintf('%s/%s', $streamHostUrl, $resourceKey),
'expires' => $expires,
'private_key' => base_path('cloudfront.pem'),
'key_pair_id' => 'APKAIPX4UJ26KJ65PKIA',
));
And that creates a URL looking how I’d expect.
The path of the private key file is correct, and the specified object (REDACTED.m3u8) in my bucket has the permission of Everyone being able to View/Download (as does all the other objects in that folder). I then embed the URL in a web page:
<!DOCTYPE html>
<html>
<head>
<title>HTTP Live Streaming Example</title>
</head>
<body>
<video src="<?php echo $signed_url; ?>" height="300" width="400" controls>
</video>
</body>
</html>
However, this throws a 403 Forbidden error to the console.
What am I doing wrong? Why can’t a retrieve any objects via CloudFront?
I’ve disabled the requirement for signed URLs and when I access the object without query string parameters (i.e. http://REDACTED.cloudfront.net/videos/output/hls/REDACTED.m3u8) the video displays, so there’s a problem when I enable the need for signed URLs.