Signed URL for video transcodes
Private video transcodes need a signed URL. A signed URL carries an expiry time and a signature that FileSpin checks before serving the video.
You'll need these, besides the asset ID and the transcode name (such as 480p-video.mp4):
| Parameter | Type | Description |
|---|---|---|
API Key | string | Your API Key. This is available in your Authorization Settings page. Keep it on your server. |
EXPIRY | integer | When the URL stops working, in seconds since the Unix epoch. |
ACCESS_ID | string | Access Id that must be used to sign URLs. You can obtain your account's Access Id from the Authorization Settings page. |
warning
Sign URLs on your server. Never put the API key in browser or mobile app code.
How to sign a transcode URL
- Build the string to sign:
{ASSET_ID}/transcodes/{TRANSCODE}?expiry={EXPIRY}&accessId={ACCESS_ID}. For example,f99255d2bf8142b29561641491e9940c/transcodes/480p-video.mp4?expiry=1452894790&accessId=IZJTAMBQGAYDAMBQGAYDAMBQGAYDANKT. - Calculate the HMAC-SHA1 of the string to sign, using your API key as the key.
- Encode the result as URL-safe base64, keeping the
=padding: use-and_in place of+and/. Then URL-encode it. - Add it as the
signatureparameter:https://cdn.filespin.io/api/v1/assets/{string to sign}&signature={signature}.
Only expiry and accessId are signed. You can add delivery=download&dl_prefix=… to a signed MP4 URL to download it as a file.
Example signed video URL
With the example API key 0c3c6d026858460abc4de1dcb4de15ac:
https://cdn.filespin.io/api/v1/assets/f99255d2bf8142b29561641491e9940c/transcodes/480p-video.mp4?expiry=1452894790&accessId=IZJTAMBQGAYDAMBQGAYDAMBQGAYDANKT&signature=fPsKf_315aye5jTizI-bzHmNXGg%3D
Code examples
Each example reads the API key and Access Id from the FILESPIN_API_KEY and FILESPIN_ACCESS_ID environment variables, and prints a URL that's valid for one hour.
Python
import base64, hashlib, hmac, os, time
from urllib.parse import quote
API_KEY = os.environ["FILESPIN_API_KEY"]
ACCESS_ID = os.environ["FILESPIN_ACCESS_ID"]
asset_id = "f99255d2bf8142b29561641491e9940c"
transcode = "480p-video.mp4"
expiry = int(time.time()) + 3600 # valid for one hour
string_to_sign = f"{asset_id}/transcodes/{transcode}?expiry={expiry}&accessId={ACCESS_ID}"
digest = hmac.new(API_KEY.encode(), string_to_sign.encode(), hashlib.sha1).digest()
signature = quote(base64.urlsafe_b64encode(digest).decode(), safe="")
signed_url = f"https://cdn.filespin.io/api/v1/assets/{string_to_sign}&signature={signature}"
print(signed_url)
Node.js
const crypto = require("crypto");
const API_KEY = process.env.FILESPIN_API_KEY;
const ACCESS_ID = process.env.FILESPIN_ACCESS_ID;
const assetId = "f99255d2bf8142b29561641491e9940c";
const transcode = "480p-video.mp4";
const expiry = Math.floor(Date.now() / 1000) + 3600; // valid for one hour
const stringToSign = `${assetId}/transcodes/${transcode}?expiry=${expiry}&accessId=${ACCESS_ID}`;
// URL-safe base64 that keeps the "=" padding (digest("base64url") drops it, so don't use it)
const signature = encodeURIComponent(
crypto.createHmac("sha1", API_KEY).update(stringToSign).digest("base64")
.replace(/\+/g, "-").replace(/\//g, "_")
);
const signedUrl = `https://cdn.filespin.io/api/v1/assets/${stringToSign}&signature=${signature}`;
console.log(signedUrl);
Java
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class SignedVideoUrl {
public static void main(String[] args) throws Exception {
String apiKey = System.getenv("FILESPIN_API_KEY");
String accessId = System.getenv("FILESPIN_ACCESS_ID");
String assetId = "f99255d2bf8142b29561641491e9940c";
String transcode = "480p-video.mp4";
long expiry = System.currentTimeMillis() / 1000 + 3600; // valid for one hour
String stringToSign = assetId + "/transcodes/" + transcode + "?expiry=" + expiry + "&accessId=" + accessId;
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(new SecretKeySpec(apiKey.getBytes(StandardCharsets.UTF_8), "HmacSHA1"));
byte[] digest = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
String signature = URLEncoder.encode(Base64.getUrlEncoder().encodeToString(digest), StandardCharsets.UTF_8);
String signedUrl = "https://cdn.filespin.io/api/v1/assets/" + stringToSign + "&signature=" + signature;
System.out.println(signedUrl);
}
}
PHP
<?php
$api_key = getenv('FILESPIN_API_KEY');
$access_id = getenv('FILESPIN_ACCESS_ID');
$asset_id = 'f99255d2bf8142b29561641491e9940c';
$transcode = '480p-video.mp4';
$expiry = time() + 3600; // valid for one hour
$string_to_sign = "$asset_id/transcodes/$transcode?expiry=$expiry&accessId=$access_id";
$digest = hash_hmac('sha1', $string_to_sign, $api_key, true);
$signature = urlencode(strtr(base64_encode($digest), '+/', '-_'));
$signed_url = "https://cdn.filespin.io/api/v1/assets/$string_to_sign&signature=$signature";
echo $signed_url . "\n";