Skip to content

Automatically Generate a Low-Size TikTok Video From an Original Video

Creating engaging TikTok videos isn’t just about creativity; it’s about keeping up with fleeting trends. With over a billion active users on TikTok, every second counts. A slow-loading video can lose viewers’ attention in an instant, leading to lower engagement and higher data usage. 

This blog post shows you how to automatically generate low-size, high-quality, TikTok-ready videos using Cloudinary’s on-the-fly transformations and Next.js.

You can see the complete code in this GitHub repository.

If you don’t have a Next.js project already, run the following command to get it up and running quickly:

npx create-next-app@latest video-optimization-demo

cd video-optimization-demoCode language: CSS (css)

Next, install the Cloudinary Node.js SDK, which will allow you to interact with Cloudinary’s API directly from your app and give you access to all its transformation and optimization features.

<code>npm install cloudinary</code>Code language: HTML, XML (xml)

To connect your app to Cloudinary, you’ll need your Cloudinary API credentials. Go to your Cloudinary dashboard and grab your cloud name, API key, and API secret, as shown below.

Next, create a .env.local file in the root of your project to securely store these credentials:

NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME=your_cloud_name

NEXT_PUBLIC_CLOUDINARY_API_KEY=your_api_key

CLOUDINARY_API_SECRET=your_api_secret

Finally, create a lib folder in your project’s root and a cloudinary.ts file in it to initialize and configure Cloudinary using the credentials stored in your .env.local file.

// lib/cloudinary.ts

import { v2 as cloudinary } from 'cloudinary';

cloudinary.config({

  cloud_name: process.env.CLOUDINARY_CLOUD_NAME,

  api_key: process.env.CLOUDINARY_API_KEY,

  api_secret: process.env.CLOUDINARY_API_SECRET,

  secure: true,

});

export default cloudinary;Code language: JavaScript (javascript)

This setup above lets you easily interact with Cloudinary’s API throughout your app.

With the introduction of server actions in Next.js 13, you can handle video uploads and optimization directly on the server side, keeping the logic cleaner and more efficient. 

Let’s dive into how you can upload unoptimized videos to Cloudinary.

First, create a form that allows users to select and upload a video. You’ll then handle the form submission via a server action in Next.js to optimize the video.

Here’s the form, you can copy this code into your page.tsx file in the app folder:

// app/page.tsx

'use client';

import { useState } from 'react';

export default function Home() {

    const[loading, setLoading]= useState(false);

    const handleSubmit = async (event: React.FormEvent<HTMLFormElement>)=>{

        event.preventDefault();

        setLoading(true);

        // Get the file from the form

const formData =new FormData(event.currentTarget);

        try {

            // Upload the video to Cloudinary

} catch (error){

            console.error('Upload failed:', error);

} finally {

            setLoading(false);

}

};

    return (

        <div>

            <h1>Generate Optimzed TikTok Video with Cloudinary</h1>

            <form onSubmit={handleSubmit}>

                <input type="file" name="video" accept="video/*" required />

                <button type="submit" disabled={loading}>

                    {loading ? 'Uploading...' : 'Upload Video'}

                </button>

            </form>

        </div>

    );

}Code language: JavaScript (javascript)

Next, create an upload.ts file in the app folder to handle video uploads to Cloudinary. This server action will receive the video and upload it to Cloudinary.

In the upload.ts file, add the following code:

// app/upload.ts

'use server';

import cloudinary from '../lib/cloudinary';

export async function upload(formData: FormData) {

    const file = formData.get('video') as File;

    const buffer: Buffer = Buffer.from(await file.arrayBuffer());

    // Sanitize the public_id (file name) if needed

    const safePublicId = file.name.replace(/[^a-zA-Z0-9-_]/g,'_');

    const uploadResponse = await new Promise<{

        secure_url: string;

        public_id: string;

}>((resolve, reject)=>{

        cloudinary.uploader

            .upload_stream(

{

                    resource_type:'video',

                    public_id: safePublicId,

},

(error, result)=>{

if(error){

                        reject(error);

}elseif(result){

                        resolve(result);

}else{

                        reject(new Error('Upload result is undefined'));

}

}

)

            .end(buffer);

});

    console.log(uploadResponse.secure_url);

}Code language: JavaScript (javascript)

In the code above:

  • The video file is received from the form (formData) and converted to a buffer using file.arrayBuffer().
  • A safe public ID is generated for the file by sanitizing the file name to ensure it contains only valid characters.
  • The video is uploaded to Cloudinary using cloudinary.uploader.upload_stream(). The response includes the video URL (secure_url) and the video identifier (public_id), which will be used later for optimization.

You can now import the upload action from upload.ts file and modify the try/catch block in the page.tsx file to trigger this upload function when submitting the form:

// app/page.tsx

import { upload } from './upload';

try {

await upload(formData);

} catch (error){

    console.error('Upload failed', error);

} finally {

    setLoading(false);// Stop loading state

}Code language: JavaScript (javascript)

When the form is submitted, the video is sent to the upload function, which handles the Cloudinary upload. You can confirm the upload in your Cloudinary management console.

In the next step, you’ll learn how to optimize the video and make it available for download.

When optimizing videos for platforms like TikTok, you want to ensure that the final video maintains a balance between high quality and small file size. 

Cloudinary provides a range of transformation options that ensure your videos are optimized for performance without sacrificing quality. Here are some key parameters:

  1. quality: 'auto'. The quality parameter defines the level of compression applied to a video. When set to ‘auto’, Cloudinary automatically chooses the best quality setting based on the video content and the need to balance visual quality with file size.
  1. format: 'auto'. The format parameter defines the file format in which the video is delivered. By setting format: ‘auto’, Cloudinary can choose the best format based on the user’s browser and device. However, since TikTok requires MP4 format for uploads, you’ll explicitly specify format: ‘mp4’. This ensures that the video is delivered in a format that TikTok supports, while still benefiting from any other format-based optimizations Cloudinary performs behind the scenes.
  1. width and height. The width and height parameters allow you to specify the target resolution. TikTok videos typically perform well with a width of 1080px and height of 1920px. This ensures the video fits TikTok’s dimensions without being unnecessarily large, reducing file size while maintaining the vertical orientation that TikTok users expect.
  1. crop: 'fill'. The fill cropping mode resizes the video to the specified dimensions while using smart cropping to ensure the video retains its key elements. It automatically detects the most important regions (like faces or motion) and focuses on them during the crop.

You’ll implement these optimizations in the app/upload.ts file by improving the uploaded video and returning the optimized URL.

In the upload.ts file, update the function to include the following code:

// app/upload.ts

const optimizedVideoUrl = cloudinary.url(uploadResponse.public_id,{

    resource_type:'video',

    width: 1080,

    height:1920,

    crop:'fill',

    quality:'auto',

    format:'mp4',

});

return optimizedVideoUrl;Code language: JavaScript (javascript)

This function takes the uploaded video and applies the necessary transformations to make it TikTok-ready. The optimizedVideoUrl` returned from this function can be used to display and download the video on the client side.

Once the video is optimized, it’s time to display it and provide an option for users to download the video.

Create a state to store the optimized video URL in the page.tsx file and store the video URL to the state in the try block:

// app/page.tsx

const[optimizedVideoUrl, setOptimizedVideoUrl]= useState<string>('');

const[loading, setLoading]= useState(false);

const handleSubmit = async (event: React.FormEvent<HTMLFormElement>)=>{

    event.preventDefault();

    setLoading(true);

const formData =new FormData(event.currentTarget);

    try {

const videoUrl: string = await upload(formData);

        setOptimizedVideoUrl(videoUrl);

} catch (error){

        console.error('Upload failed', error);

} finally {

        setLoading(false);// Stop loading state

}

};Code language: JavaScript (javascript)

The code above handles the form submission, uploads the video, and stores the optimized video URL in the optimizedVideoUrl state.

Now, use the optimizedVideoUrl to display the video on the page.tsx file:

// app/page.tsx

{optimizedVideoUrl && (

    <div className="flex justify-center space-x-4 mt-10">

        <div>

            <h2 className="text-lg font-bold text-center mb-4">

                Optimized Video

            </h2>

            <video

                src={optimizedVideoUrl}

                controls

                className="w-full max-w-md border-4 rounded"

            />

        </div>

    </div>

)}Code language: JavaScript (javascript)

The code above conditionally renders the video only when the optimizedVideoUrl is available, providing a video player to preview the optimized TikTok video.

Finally, to allow users download the optimized video, ready for TikTok upload. Add the following function in your page.tsx file to handle download:

// app.page.tsx

const handleDownload = async ()=>{

    if (optimizedVideoUrl){

        // Fetch the video from the URL

const response = await fetch(optimizedVideoUrl,{

            method:'GET',

            mode:'cors',

});

        // Create a blob from the response

const blob = await response.blob();

        // Create a URL for the blob object

const blobUrl = window.URL.createObjectURL(blob);

        // Create a link element and trigger the download

const a = document.createElement('a');

        a.href = blobUrl;

        a.download =`optimized_video`;

        document.body.appendChild(a);

        a.click();

        // Clean up the URL object

        window.URL.revokeObjectURL(blobUrl);

        document.body.removeChild(a);

}

};Code language: JavaScript (javascript)

Then, create a button on the page.tsx file and attach the download function in the code above to an onClick event as shown below:

// app/page.tsx

<button

    onClick={handleDownload}

    className="bg-green-600 text-white p-2 rounded-md"

>

    Download Video

</button>Code language: HTML, XML (xml)

This allows users to view the optimized video and download it in MP4 format, ready for upload to TikTok.  

In the demo below, a 26.7 MB wide video is uploaded. After applying Cloudinary’s optimization techniques, the video size is reduced to 20 MB still with a high quality.

In this blog post, you learned how to upload an unoptimized video, apply smart cropping, and resize it for TikTok’s vertical format — all in a few steps. Learn more about Cloudinary’s suite of video optimization and transformation capabilities. Sign up for a free account today.

If you enjoyed this post and want to discuss it more, join the Cloudinary Community forum and its associated Discord.

Back to top

Featured Post