Login

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: '*',
    pushMediaSettings: {
        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 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:

  1. Divide the file: Large files are split into smaller, manageable chunks (e.g., 16 MB by default).
  2. Upload individually: Each chunk is uploaded separately. If a chunk fails, only that specific chunk needs to be re-uploaded.
  3. 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, a CDN, or your preferred package manager:


Using npm:

npm i @fastpix/uploader

Using CDN:

<script src="https://cdn.jsdelivr.net/npm/@fastpix/uploader@1.0.3/dist/uploads.js"></script> 

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";
const videoFile = document.getElementById("videoFile")

videoFile.onchange = async (event) => {
	const fileObject = event?.target?.files[0]
	if (fileObject) {
    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(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 => {
		console.log("progress:", event.detail);
	});
  
	// Event listener for handling successful upload completion.  
	fileUpload.on('success', () => {
		console.log("upload completed")
	});
  
	// Event listener for handling upload errors.  
	fileUpload.on('error', event => {
		console.log("upload error:", event?.detail?.message);
	});
	// Pause an upload  
	// fileUpload.pause()  
	// Resume an upload  
	// fileUpload.resume()  
	// Abort an upload  
	// fileUpload.abort()  
}
<!DOCTYPE html>

<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>File Upload with Progress Bar</title>

	<!-- Import FastPix Uploader library from CDN -->
	<script src="https://cdn.jsdelivr.net/npm/@fastpix/uploader@1.0.3/dist/uploads.js"></script>
</head>
<body>
	<style>
		.container {
			width: 100%;
			display: flex;
			flex-direction: column;
			align-items: center;
			justify-content: center;
			margin-top: 50px;
		}

		.progress-bar-container {
			width: 100%;
			background-color: #eee;
			border-radius: 20px;
			height: 10px;
			margin-top: 20px;
		}

		.progress-bar {
			height: 100%;
			width: 0;
			background-color: #0f0f0f;
			border-radius: 100px;
			transition: width 0.2s ease;
		}
	</style>

	<div class="container">
		<h1>FastPix Uploads</h1>

		<!-- File input to select video for upload -->
		<input id="videoFile" type="file" />

		<!-- Progress indicator text -->
		<p id="progressIndicator"></p>

		<!-- Visual representation of upload progress -->
		<div class="progress-bar-container">
			<div class="progress-bar" id="progressBar"></div>
		</div>
	</div>

	<script>
      const videoFile = document.getElementById("videoFile");
      const progressBar = document.getElementById("progressBar");
      const progressIndicator = document.getElementById("progressIndicator")
      
      // Initialize progress bar and indicator to 0 
      progressBar.style.width = '0%';
      progressIndicator.innerText = '0%'
      
      // Triggered when a file is selected 
      videoFile.onchange = async (event) => {
        const fileObject = event?.target?.files[0];
        if (fileObject) {
          try {
            
            // API details to get signed URL for upload 
            const url = 'https://v1.fastpix.io/on-demand/uploads';
            const username = '53328e44-b686-432c-9f8e-c8b24c027bc0';
            const password = '717cc20a-8145-42de-824b-21fac947cf22';
            
            // Request payload for upload configuration 
            const payload = {
              corsOrigin: "*",
              pushMediaSettings: {
                accessPolicy: "public",
                metadata: {
                  key1: "value1"
                },
                generateSubtitles: false,
                normalizeAudio: true,
                maxResolution: "1080p",
              },
            };
            const headersRequest = {
              method: 'POST',
              headers: {
                'Content-Type': 'application/json',
                Authorization: 'Basic ' + btoa(username + ':' + password),
              },
              body: JSON.stringify(payload),
            };
            const getSignedUrl = await fetch(url, headersRequest);
            const signedUrl = await getSignedUrl.json();

            // If signed URL is successfully received, proceed to upload 
            if (signedUrl.success) {
              handleUpload(fileObject, signedUrl.data.url);
            } else {
              console.error(signedUrl.data.error);
            }
          } catch (error) {
            console.error(error);
          }
        }
      };

      // Function to handle file upload using the signed URL 
      const handleUpload = (video, signedUrl) => {
        const fileUpload = Uploader.init({
          endpoint: signedUrl,
          file: video,
          chunkSize: 5120,
        });

        // Event listener for upload progress 
        fileUpload.on('progress', (event) => {
          const percentage = Math.round(event.detail);
          progressIndicator.innerText = `${percentage}%`;
          progressBar.style.width = `${percentage}%`;
          console.log("progress:", percentage + "%");
        });

        // Event listener for successful upload 
        fileUpload.on('success', () => {
          console.log("upload completed");
        });

        // Event listener for upload error 
        fileUpload.on('error', (event) => {
          console.log("upload error:", event?.detail?.message);
        });

        // Pause an upload  
        // fileUpload.pause()  
        // Resume an upload  
        // fileUpload.resume()  
        // Abort an upload  
        // fileUpload.abort()  
		};
	</script>
</body>
</html>