Upload videos directly
FastPix Direct Uploads provide a streamlined solution for uploading media (video and audio) directly to your platform from client applications. This guide will simplify the process and highlight how users can effectively utilize authenticated upload URLs for seamless content delivery.
Why to use FastPix direct uploads
- Authenticated access: Grant authenticated access for direct uploads from mobile and web applications, ensuring secure and controlled content management.
- Flexible upload options: Upload media directly from your server or use command-line tools, providing ultimate flexibility in how you manage your media.
- Storage efficiency: Eliminate the need to store original files on your local system, reducing storage costs and simplifying file management.
- Better user experience: Deliver exceptional experiences to your audience with efficient content delivery, reducing loading times and improving accessibility.
Use case scenarios
FastPix Direct Uploads can be utilized in multiple scenarios:
- Mobile app uploads: Users can upload videos directly from their mobile devices, enhancing user-generated content (UGC) capabilities.
- Web app uploads: Web applications can facilitate direct uploads, allowing users to share content easily.
- Server-side content uploads: Large platforms can upload media files in batches from their servers, streamlining content management.
- Command-line tool uploads: Developers can leverage command-line tools for quick and efficient uploads, perfect for automated workflows.
Uploading media to FastPix in 3 steps
Follow these steps to easily upload content directly to FastPix:
Step 1: Generate a unique upload URL
- Generate an access token: Create a new Access Token in FastPix dashboard. This token consists of a Token ID (username) and Token Secret (password) pair, which are necessary for authenticating with the FastPix Video API. See the guide.
- Make the API request: You can visit FastPix API reference and navigate to the Upload media from device endpoint. This lets you create a new direct upload with your desired media settings.
- Receive your upload URL: The API in its response will generate an authenticated URL specifically for your upload. This URL is unique and can be used directly in your client applications.
- Keep track of your upload ID: Along with the URL, you will receive a unique ID for this direct upload. Make sure to save this ID for tracking the upload progress later through the API.
Command line tool:
curl --request POST \
--url https://v1.fastpix.io/on-demand/uploads \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '
{
"corsOrigin": "*",
"pushMediaSettings": {
"accessPolicy": "public",
"metadata": {
"key1": "value1"
},
"maxResolution": "1080p",
"mp4Support": "capped_4k"
}
}
'
Javascript:
<script>
// This endpoint provides you with the signed URL necessary for uploading your video.
const url = 'https://v1.fastpix.io/on-demand/uploads';
// The FastPix Video API employs a token key pair consisting of a Token ID (username) and Token Secret (password) for authentication.
// Generate a new Access Token in the Access Token settings located within your FastPix Organization dashboard.
const username = '';
const password = '';
// Initialize the data object
const data = {
corsOrigin: '*',
newAssetSettings: {
accessPolicy: 'public',
metadata: {
key1: 'value1',
},
generateSubtitles: false,
normalizeAudio: true,
maxResolution: '1080p',
},
};
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: 'Basic ' + btoa(username + ':' + password),
},
body: JSON.stringify(data),
}
fetch(url, options)
.then(response => {
if (response.success) {
// You can fetch the signedUrl in the response
}
})
</script>
Step 2: Initiate the upload
With the upload URL in hand, you’re ready to upload your media content. In your client application (whether it’s a mobile or web app), use the provided URL to initiate a PUT request. Include the file you want to upload in the request body. The API accepts the media file from the device and uploads it to the FastPix platform.
Step 3: Track your upload
Once uploaded, the media undergoes processing and is assigned a unique ID for tracking. Retain this uploadId for any future operations related to this upload.
Check your FastPix dashboard to confirm successful uploads. You'll see new assets listed with the settings you specified during setup, along with the uploaded video. Alternatively, you can also use the Get Media by ID endpoint to check the status of the uploaded media asset and see if it has transitioned to a ready status for playback.
USING WEBHOOKS
To notify your application about the status of this API request check for the webhooks for Upload related events.
Resumable uploading of large files
When it comes to uploading files, especially large ones like videos, using the right method is crucial for a smooth and efficient experience. This guide explains how to implement resumable uploads effectively.
How resumable uploads work through chunking
Resumable uploads can be effectively handled through a technique called chunking. This method involves breaking down large files into smaller, more manageable pieces, or "chunks." Here's how chunking works:
- Divide the file: Large files are split into smaller, manageable chunks (e.g., 16 MB by default).
- Upload individually: Each chunk is uploaded separately. If a chunk fails, only that specific chunk needs to be re-uploaded.
- Resume capability: If the upload is interrupted, you can resume from the last successfully uploaded chunk instead of starting over.
This approach is important because:
- It reduces the risk: Uploading smaller chunks minimizes the risk of failure. If a chunk fails to upload due to network issues, only that specific chunk needs to be re-uploaded, not the entire file.
- Improves performance: Smaller chunks can be uploaded more quickly and efficiently, especially on slower connections, as they require less time to transfer.
- Easier management: Chunking allows for better tracking of upload progress, making it easier to implement features like pause and resume.
The FastPix Uploader SDK helps you efficiently upload large files from the browser by splitting them into chunks and also gives you the ability to pause and resume your uploads.
Installation
To install the SDK, you can use npm or any of your favourite node package manager 😉:
npm i @fastpix/uploader
Basic usage
To get started with the SDK, you will need a signed URL.
To make API requests, you'll need a valid Access Token and Secret Key. See the Basic Authentication Guide for details on retrieving these credentials.
Once you have your credentials, use the Upload media from device API to generate a signed URL for uploading media.
import { Uploader } from "@fastpix/uploader";
const fileUploader = Uploader.init({
endpoint: 'https://example.com/signed-url', // Replace with the signed URL.
file: mediaFile, // Provide the media file you want to upload.
chunkSize: 5120, // Specify the chunk size in kilobytes (KB). Minimum allowed chunk size is 5120KB (5MB).
// Additional optional parameters can be specified here as needed
})
Monitor the upload progress through lifecycle events
// fileUploader is the instance of the Uploader
// Track upload progress
fileUploader.on('progress', event => {
console.log("Upload Progress:", event.detail);
});
// Handle errors during the upload process
fileUploader.on('error', event => {
console.error("Upload Error:", event.detail.message);
});
// Trigger actions when the upload completes successfully
fileUploader.on('success', event => {
console.log("Upload Completed");
});
// Track the initiation of each chunk upload
fileUploader.on('attempt', event => {
console.log("Chunk Upload Attempt:", event.detail);
});
// Track failures of each chunk upload attempt
fileUploader.on('chunkAttemptFailure', event => {
console.log("Chunk Attempt Failure:", event.detail);
});
// Perform an action when a chunk is successfully uploaded
fileUploader.on('chunkSuccess', event => {
console.log("Chunk Successfully Uploaded:", event.detail);
});
// Triggers when the connection is back online
fileUploader.on('online', event => {
console.log("Connection Online");
});
// Triggers when the connection goes offline
fileUploader.on('offline', event => {
console.log("Connection Offline");
});
Managing video uploads
You can control the upload lifecycle with the following methods:
Pause an upload:
// fileUploader is the instance of the Uploader
fileUpload.pause()
Resume an upload:
// fileUploader is the instance of the Uploader
fileUpload.resume()
Abort an upload:
// fileUploader is the instance of the Uploader
fileUpload.abort()
Parameters to use
This SDK supports the following parameters:
- endpoint (mandatory): The URL endpoint where the file will be uploaded.
- file (mandatory): The file object that you want to upload (e.g., a video file).
- chunkSize (optional): chunkSize should be provided in kilobytes (KB). By default, the SDK splits files into chunks of 16 MB. You can customize this by specifying a chunkSize in kilobytes (minimum of 5 MB).
- maxFileSize (optional): This parameter restricts the maximum file size that users can upload. Setting this can help prevent users from attempting to upload excessively large files that may not be manageable.
- retryChunkAttempt (optional): Specifies the number of times to retry uploading a chunk in case of failure. The default value is 5.
- delayRetry (optional): The delay time (in milliseconds) before retrying a chunk upload after a failure. The default value is 1000ms.
import React, { useState, useRef } from "react";
import { Uploader } from "@fastpix/uploader";
function Uploads() {
const [progress, setProgress] = useState(0);
const [statusMessage, setStatusMessage] = useState({
status: "",
message: "",
});
const fileInputRef = useRef(null);
const fileUploadRef = useRef(null);
const handleUpload = (video, signedUrl) => {
try {
// Initialize the uploader with the signed URL and video file
const fileUpload = Uploader.init({
endpoint: signedUrl, // The signed URL to upload the file to
file: video, // The video file to upload
chunkSize: 5120, // The size of each chunk in KB
});
fileUploadRef.current = fileUpload;
// Listen to the 'progress' event to update progress percentage
fileUpload.on("progress", (event) => {
console.log(event);
setProgress(event.detail);
});
// Listen to the 'success' event to display a success message
fileUpload.on("success", () => {
setStatusMessage({
message: "Upload completed successfully!",
status: "success",
});
});
// Listen to the 'error' event to handle errors
fileUpload.on("error", (event) => {
setStatusMessage({ message: event.detail.message, status: "error" });
});
// Pause an upload
// fileUpload.pause()
// Resume an upload
// fileUpload.resume()
// Abort an upload
// fileUpload.abort()
} catch (error) {
setStatusMessage({ message: error?.message, status: "error" });
}
};
const handleUploadProcess = async (file) => {
if (!file) {
setStatusMessage({
message: "Please select a video to upload.",
status: "error",
});
return;
}
try {
// The endpoint URL for getting the signed upload URL
const url = "https://v1.fastpix.io/on-demand/uploads";
// Basic authentication credentials
const username = "";
const password = "";
// Data to send in the POST request to configure the upload
const data = {
corsOrigin: "*", // Specify allowed cross-origin requests
pushMediaSettings: {
accessPolicy: "public", // Set access policy to public
metadata: { key1: "value1" }, // Metadata associated with the video
generateSubtitles: false, // Disable automatic subtitle generation
normalizeAudio: true, // Enable audio normalization
maxResolution: "1080p", // Set the maximum video resolution
},
};
const headersRequest = {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Basic " + btoa(username + ":" + password),
},
body: JSON.stringify(data),
};
const getSignedUrl = await fetch(url, headersRequest);
const signedUrl = await getSignedUrl.json();
if (signedUrl.success) {
handleUpload(file, signedUrl.data.url);
} else {
setStatusMessage({ message: signedUrl.data.error, status: "error" });
}
} catch (error) {
console.error(error);
setStatusMessage({
message: "Failed to fetch signed URL.",
status: "error",
});
}
};
// Function to simulate a file upload button click
const handleButtonClick = () => {
fileInputRef.current.click();
};
// Handle file selection and initiate the upload process
const handleFileChange = (event) => {
const file = event.target.files[0];
if (file) {
handleUploadProcess(file);
}
};
return (
<div
style={{
textAlign: "center",
width: "100%",
border: "1px dashed #0f0f0f",
borderRadius: "8px",
}}
>
<h2 style={{ marginBottom: "20px" }}>Fastpix Resumable Uploads</h2>
{/* Button to select a file for upload */}
<div
style={{
marginTop: "20px",
display:
progress > 0 && statusMessage?.status !== "success"
? "none"
: "block",
}}
>
<button
onClick={handleButtonClick}
style={{
padding: "10px 20px",
cursor: "pointer",
backgroundColor: "#0f0f0f",
color: "#ffffff",
}}
>
Choose Video to Upload
</button>
<input
type="file"
ref={fileInputRef}
onChange={handleFileChange}
style={{ display: "none" }}
/>
</div>
<div style={{ padding: "20px" }}>
{/* Display the upload progress */}
<p style={{ display: "block", marginBottom: "10px" }}>
Progress: {`${Math.round(progress)}%`}
</p>
<div
style={{
backgroundColor: "#eee",
width: "100%",
height: "6px",
marginTop: "20px",
}}
>
<div
style={{
backgroundColor: "#0f0f0f",
transition: "width 0.20s",
width: `${progress}%`,
height: "6px",
marginTop: "20px",
borderRadius: "100px",
}}
></div>
</div>
{/* Display the status message */}
<p>{statusMessage.message}</p>
</div>
</div>
);
}
export default Uploads;
import { Uploader } from "@fastpix/uploader";
// Imagine there's an HTML page featuring an input field as follows: <input id="videoFile" type="file" />
const videoFile = document.getElementById('videoFile');
videoFile.onchange = async () => {
try {
// The endpoint URL for getting the signed upload URL
const url = 'https://v1.fastpix.io/on-demand/uploads';
// Basic authentication credentials
const username = '';
const password = '';
// Data to send in the POST request to configure the upload
const data = {
corsOrigin: "*", // Specify allowed cross-origin requests
pushMediaSettings: {
accessPolicy: "public", // Set access policy to public
metadata: { key1: "value1" }, // Metadata associated with the video
generateSubtitles: false, // Disable automatic subtitle generation
normalizeAudio: true, // Enable audio normalization
maxResolution: "1080p", // Set the maximum video resolution
},
};
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: 'Basic ' + btoa(username + ':' + password),
},
body: JSON.stringify(data),
};
const getSignedUrl = await fetch(url, headersRequest);
const signedUrl = await getSignedUrl.json();
if (signedUrl.success) {
handleUpload(videoFile.files[0], signedUrl.data.url)
} else {
console.error(signedUrl.data.error)
}
} catch (error) {
console.error(error)
}
}
const handleUpload = (video, signedUrl) => {
const fileUpload = Uploader.init({
endpoint: signedUrl, // The signed URL to upload the file to
file: video, // The video file to upload
chunkSize: 5120, // The size of each chunk in KB
// Additional optional parameters can be specified here as needed
});
// Event listener for tracking upload progress.
fileUpload.on('progress', event => {
setProgress(event.detail);
});
// Event listener for handling successful upload completion.
fileUpload.on('success', () => {
setStatusMessage({ message: "Upload completed successfully!", status: "success" });
});
// Event listener for handling upload errors.
fileUpload.on('error', event => {
setStatusMessage({ message: event.detail.message, status: "error" });
});
// Pause an upload
// fileUpload.pause()
// Resume an upload
// fileUpload.resume()
// Abort an upload
// fileUpload.abort()
}
Updated about 2 months ago