{"id":36485,"date":"2025-01-03T07:00:00","date_gmt":"2025-01-03T15:00:00","guid":{"rendered":"https:\/\/cloudinary.com\/blog\/?p=36485"},"modified":"2024-12-20T18:47:59","modified_gmt":"2024-12-21T02:47:59","slug":"low-size-tiktok-video","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/low-size-tiktok-video","title":{"rendered":"Automatically Generate a Low-Size TikTok Video From an Original Video"},"content":{"rendered":"\n<p>Creating engaging <a target=\"_blank\" href=\"https:\/\/www.tiktok.com\/\" rel=\"noreferrer noopener\">TikTok<\/a> videos isn\u2019t just about creativity; it\u2019s about keeping up with fleeting trends. With <a target=\"_blank\" href=\"https:\/\/backlinko.com\/tiktok-users#:~:text=According%20to%20the%20parent%20company,active%20users%20in%20September%202021.&amp;text=Out%20of%203.96%20billion%20monthly,are%20monthly%20active%20TikTok%20users.\" rel=\"noreferrer noopener\">over a billion active users<\/a> on TikTok, every second counts. A slow-loading video can lose viewers&#8217; attention in an instant, leading to lower engagement and higher data usage.&nbsp;<\/p>\n\n\n\n<p>This blog post shows you how to automatically generate low-size, high-quality, TikTok-ready videos using Cloudinary\u2019s <a target=\"_blank\" href=\"https:\/\/cloudinary.com\/documentation\/image_transformations\" rel=\"noreferrer noopener\">on-the-fly transformations<\/a> and Next.js.<\/p>\n\n\n\n<p>You can see the complete code in this <a target=\"_blank\" href=\"https:\/\/github.com\/olawanlejoel\/cloudinary-video-optimization\" rel=\"noreferrer noopener\">GitHub repository<\/a>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img width=\"1024\" height=\"543\" data-public-id=\"Web_Assets\/blog\/blog-Automatically-Generate-a-Low-Size-TikTok-Video-From-an-Original-Video-1_364862427b\/blog-Automatically-Generate-a-Low-Size-TikTok-Video-From-an-Original-Video-1_364862427b.png\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_1024,h_543,c_scale\/f_auto,q_auto\/v1734749116\/Web_Assets\/blog\/blog-Automatically-Generate-a-Low-Size-TikTok-Video-From-an-Original-Video-1_364862427b\/blog-Automatically-Generate-a-Low-Size-TikTok-Video-From-an-Original-Video-1_364862427b.png?_i=AA\" alt=\"\" class=\"wp-post-36485 wp-image-36486\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1734749116\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1734749116\/Web_Assets\/blog\/blog-Automatically-Generate-a-Low-Size-TikTok-Video-From-an-Original-Video-1_364862427b\/blog-Automatically-Generate-a-Low-Size-TikTok-Video-From-an-Original-Video-1_364862427b.png?_i=AA 1600w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1734749116\/Web_Assets\/blog\/blog-Automatically-Generate-a-Low-Size-TikTok-Video-From-an-Original-Video-1_364862427b\/blog-Automatically-Generate-a-Low-Size-TikTok-Video-From-an-Original-Video-1_364862427b.png?_i=AA 300w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1734749116\/Web_Assets\/blog\/blog-Automatically-Generate-a-Low-Size-TikTok-Video-From-an-Original-Video-1_364862427b\/blog-Automatically-Generate-a-Low-Size-TikTok-Video-From-an-Original-Video-1_364862427b.png?_i=AA 768w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1734749116\/Web_Assets\/blog\/blog-Automatically-Generate-a-Low-Size-TikTok-Video-From-an-Original-Video-1_364862427b\/blog-Automatically-Generate-a-Low-Size-TikTok-Video-From-an-Original-Video-1_364862427b.png?_i=AA 1024w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1734749116\/Web_Assets\/blog\/blog-Automatically-Generate-a-Low-Size-TikTok-Video-From-an-Original-Video-1_364862427b\/blog-Automatically-Generate-a-Low-Size-TikTok-Video-From-an-Original-Video-1_364862427b.png?_i=AA 1536w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Setting Up Cloudinary and Next.js<\/h2>\n\n\n\n<p>If you don\u2019t have a Next.js project already, run the following command to get it up and running quickly:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-wrap-lines\"><span class=\"hljs-selector-tag\">npx<\/span> <span class=\"hljs-selector-tag\">create-next-app<\/span><span class=\"hljs-keyword\">@latest<\/span> video-optimization-demo\n\ncd video-optimization-demo<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Next, install the <a target=\"_blank\" href=\"https:\/\/www.npmjs.com\/package\/cloudinary\" rel=\"noreferrer noopener\">Cloudinary Node.js SDK<\/a>, which will allow you to interact with Cloudinary\u2019s API directly from your app and give you access to all its transformation and optimization features.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">code<\/span>&gt;<\/span>npm install cloudinary<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">code<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>To connect your app to Cloudinary, you\u2019ll need your Cloudinary API credentials. Go to your <a target=\"_blank\" href=\"https:\/\/cloudinary.com\/\" rel=\"noreferrer noopener\">Cloudinary dashboard<\/a> and grab your <strong>cloud name<\/strong>, <strong>API key<\/strong>, and <strong>API secret<\/strong>, as shown below.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img width=\"1024\" height=\"445\" data-public-id=\"Web_Assets\/blog\/blog-Automatically-Generate-a-Low-Size-TikTok-Video-From-an-Original-Video-2_36487e56f5\/blog-Automatically-Generate-a-Low-Size-TikTok-Video-From-an-Original-Video-2_36487e56f5.png\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_1024,h_445,c_scale\/f_auto,q_auto\/v1734749112\/Web_Assets\/blog\/blog-Automatically-Generate-a-Low-Size-TikTok-Video-From-an-Original-Video-2_36487e56f5\/blog-Automatically-Generate-a-Low-Size-TikTok-Video-From-an-Original-Video-2_36487e56f5.png?_i=AA\" alt=\"\" class=\"wp-post-36485 wp-image-36487\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1734749112\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1734749112\/Web_Assets\/blog\/blog-Automatically-Generate-a-Low-Size-TikTok-Video-From-an-Original-Video-2_36487e56f5\/blog-Automatically-Generate-a-Low-Size-TikTok-Video-From-an-Original-Video-2_36487e56f5.png?_i=AA 1600w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1734749112\/Web_Assets\/blog\/blog-Automatically-Generate-a-Low-Size-TikTok-Video-From-an-Original-Video-2_36487e56f5\/blog-Automatically-Generate-a-Low-Size-TikTok-Video-From-an-Original-Video-2_36487e56f5.png?_i=AA 300w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1734749112\/Web_Assets\/blog\/blog-Automatically-Generate-a-Low-Size-TikTok-Video-From-an-Original-Video-2_36487e56f5\/blog-Automatically-Generate-a-Low-Size-TikTok-Video-From-an-Original-Video-2_36487e56f5.png?_i=AA 768w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1734749112\/Web_Assets\/blog\/blog-Automatically-Generate-a-Low-Size-TikTok-Video-From-an-Original-Video-2_36487e56f5\/blog-Automatically-Generate-a-Low-Size-TikTok-Video-From-an-Original-Video-2_36487e56f5.png?_i=AA 1024w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1734749112\/Web_Assets\/blog\/blog-Automatically-Generate-a-Low-Size-TikTok-Video-From-an-Original-Video-2_36487e56f5\/blog-Automatically-Generate-a-Low-Size-TikTok-Video-From-an-Original-Video-2_36487e56f5.png?_i=AA 1536w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Next, create a <code>.env.local<\/code> file in the root of your project to securely store these credentials:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs shcb-wrap-lines\">NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME=your_cloud_name\n\nNEXT_PUBLIC_CLOUDINARY_API_KEY=your_api_key\n\nCLOUDINARY_API_SECRET=your_api_secret<\/code><\/span><\/pre>\n\n\n<p>Finally, create a lib folder in your project&#8217;s root and a <code>cloudinary.ts<\/code> file in it to initialize and configure Cloudinary using the credentials stored in your <code>.env.local<\/code> file.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ lib\/cloudinary.ts<\/span>\n\n<span class=\"hljs-keyword\">import<\/span> { v2 <span class=\"hljs-keyword\">as<\/span> cloudinary } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'cloudinary'<\/span>;\n\ncloudinary.config({\n\n\u00a0 <span class=\"hljs-attr\">cloud_name<\/span>: process.env.CLOUDINARY_CLOUD_NAME,\n\n\u00a0 <span class=\"hljs-attr\">api_key<\/span>: process.env.CLOUDINARY_API_KEY,\n\n\u00a0 <span class=\"hljs-attr\">api_secret<\/span>: process.env.CLOUDINARY_API_SECRET,\n\n\u00a0 <span class=\"hljs-attr\">secure<\/span>: <span class=\"hljs-literal\">true<\/span>,\n\n});\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> cloudinary;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This setup above lets you easily interact with Cloudinary\u2019s API throughout your app.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Uploading Video to Cloudinary With Next.js<\/h2>\n\n\n\n<p>With the introduction of <a target=\"_blank\" href=\"https:\/\/nextjs.org\/docs\/app\/building-your-application\/data-fetching\/server-actions-and-mutations\" rel=\"noreferrer noopener\">server actions<\/a> in Next.js 13, you can handle video uploads and optimization directly on the server side, keeping the logic cleaner and more efficient.&nbsp;<\/p>\n\n\n\n<p>Let\u2019s dive into how you can upload unoptimized videos to Cloudinary.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Step 1: Create the Video Upload Form<\/strong><\/h3>\n\n\n\n<p>First, create a form that allows users to select and upload a video. You\u2019ll then handle the form submission via a server action in Next.js to optimize the video.<\/p>\n\n\n\n<p>Here\u2019s the form, you can copy this code into your <code>page.tsx<\/code> file in the app folder:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ app\/page.tsx<\/span>\n\n<span class=\"hljs-string\">'use client'<\/span>;\n\n<span class=\"hljs-keyword\">import<\/span> { useState } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react'<\/span>;\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">Home<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n\n\u00a0 \u00a0 <span class=\"hljs-keyword\">const<\/span>&#91;loading, setLoading]= useState(<span class=\"hljs-literal\">false<\/span>);\n\n\u00a0 \u00a0 <span class=\"hljs-keyword\">const<\/span> handleSubmit = <span class=\"hljs-keyword\">async<\/span> (event: React.FormEvent&lt;HTMLFormElement&gt;)=&gt;{\n\n\u00a0 \u00a0 \u00a0 \u00a0 event.preventDefault();\n\n\u00a0 \u00a0 \u00a0 \u00a0 setLoading(<span class=\"hljs-literal\">true<\/span>);\n\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-comment\">\/\/ Get the file from the form<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> formData =<span class=\"hljs-keyword\">new<\/span> FormData(event.currentTarget);\n\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-keyword\">try<\/span> {\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-comment\">\/\/ Upload the video to Cloudinary<\/span>\n\n} <span class=\"hljs-keyword\">catch<\/span> (error){\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-built_in\">console<\/span>.error(<span class=\"hljs-string\">'Upload failed:'<\/span>, error);\n\n} <span class=\"hljs-keyword\">finally<\/span> {\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 setLoading(<span class=\"hljs-literal\">false<\/span>);\n\n}\n\n};\n\n\u00a0 \u00a0 <span class=\"hljs-keyword\">return<\/span> (\n\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span>&gt;<\/span>Generate Optimzed TikTok Video with Cloudinary<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">form<\/span> <span class=\"hljs-attr\">onSubmit<\/span>=<span class=\"hljs-string\">{handleSubmit}<\/span>&gt;<\/span>\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"file\"<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"video\"<\/span> <span class=\"hljs-attr\">accept<\/span>=<span class=\"hljs-string\">\"video\/*\"<\/span> <span class=\"hljs-attr\">required<\/span> \/&gt;<\/span>\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"submit\"<\/span> <span class=\"hljs-attr\">disabled<\/span>=<span class=\"hljs-string\">{loading}<\/span>&gt;<\/span>\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 {loading ? 'Uploading...' : 'Upload Video'}\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">form<\/span>&gt;<\/span>\n\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n\n\u00a0 \u00a0 );\n\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\"><strong>Step 2: Handle Video Upload With Server Action<\/strong><\/h3>\n\n\n\n<p>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.<\/p>\n\n\n\n<p>In the <code>upload.ts<\/code> file, add the following code:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ app\/upload.ts<\/span>\n\n<span class=\"hljs-string\">'use server'<\/span>;\n\n<span class=\"hljs-keyword\">import<\/span> cloudinary <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'..\/lib\/cloudinary'<\/span>;\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">upload<\/span>(<span class=\"hljs-params\">formData: FormData<\/span>) <\/span>{\n\n\u00a0 \u00a0 <span class=\"hljs-keyword\">const<\/span> file = formData.get(<span class=\"hljs-string\">'video'<\/span>) <span class=\"hljs-keyword\">as<\/span> File;\n\n\u00a0 \u00a0 <span class=\"hljs-keyword\">const<\/span> buffer: Buffer = Buffer.from(<span class=\"hljs-keyword\">await<\/span> file.arrayBuffer());\n\n\u00a0 \u00a0 <span class=\"hljs-comment\">\/\/ Sanitize the public_id (file name) if needed<\/span>\n\n\u00a0 \u00a0 <span class=\"hljs-keyword\">const<\/span> safePublicId = file.name.replace(<span class=\"hljs-regexp\">\/&#91;^a-zA-Z0-9-_]\/g<\/span>,<span class=\"hljs-string\">'_'<\/span>);\n\n\u00a0 \u00a0 <span class=\"hljs-keyword\">const<\/span> uploadResponse = <span class=\"hljs-keyword\">await<\/span> <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Promise<\/span>&lt;{\n\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">secure_url<\/span>: string;\n\n\u00a0 \u00a0 \u00a0 \u00a0 public_id: string;\n\n}&gt;<span class=\"hljs-function\">(<span class=\"hljs-params\">(resolve, reject<\/span>)=&gt;<\/span>{\n\n\u00a0 \u00a0 \u00a0 \u00a0 cloudinary.uploader\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 .upload_stream(\n\n{\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">resource_type<\/span>:<span class=\"hljs-string\">'video'<\/span>,\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">public_id<\/span>: safePublicId,\n\n},\n\n(error, result)=&gt;{\n\n<span class=\"hljs-keyword\">if<\/span>(error){\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 reject(error);\n\n}elseif(result){\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 resolve(result);\n\n}<span class=\"hljs-keyword\">else<\/span>{\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 reject(<span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Error<\/span>(<span class=\"hljs-string\">'Upload result is undefined'<\/span>));\n\n}\n\n}\n\n)\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 .end(buffer);\n\n});\n\n\u00a0 \u00a0 <span class=\"hljs-built_in\">console<\/span>.log(uploadResponse.secure_url);\n\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In the code above:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The video file is received from the form (<code>formData<\/code>) and converted to a buffer using <code>file.arrayBuffer()<\/code>.<\/li>\n\n\n\n<li>A safe public ID is generated for the file by sanitizing the file name to ensure it contains only valid characters.<\/li>\n\n\n\n<li>The video is uploaded to Cloudinary using <code>cloudinary.uploader.upload_stream()<\/code>. The response includes the video URL (<code>secure_url<\/code>) and the video identifier (<code>public_id<\/code>), which will be used later for optimization.<\/li>\n<\/ul>\n\n\n\n<p>You can now import the upload action from <code>upload.ts<\/code> file and modify the try\/catch block in the <code>page.tsx<\/code> file to trigger this upload function when submitting the form:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ app\/page.tsx<\/span>\n\n<span class=\"hljs-keyword\">import<\/span> { upload } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'.\/upload'<\/span>;\n\n<span class=\"hljs-keyword\">try<\/span> {\n\n<span class=\"hljs-keyword\">await<\/span> upload(formData);\n\n} <span class=\"hljs-keyword\">catch<\/span> (error){\n\n\u00a0 \u00a0 <span class=\"hljs-built_in\">console<\/span>.error(<span class=\"hljs-string\">'Upload failed'<\/span>, error);\n\n} <span class=\"hljs-keyword\">finally<\/span> {\n\n\u00a0 \u00a0 setLoading(<span class=\"hljs-literal\">false<\/span>);<span class=\"hljs-comment\">\/\/ Stop loading state<\/span>\n\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>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 <a target=\"_blank\" href=\"https:\/\/console.cloudinary.com\/console\" rel=\"noreferrer noopener\">Cloudinary management console<\/a>.<\/p>\n\n\n\n<p>In the next step, you\u2019ll learn how to optimize the video and make it available for download.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Handling Video Optimization With Cloudinary<\/h2>\n\n\n\n<p>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.&nbsp;<\/p>\n\n\n\n<p>Cloudinary provides a range of <a target=\"_blank\" href=\"https:\/\/cloudinary.com\/blog\/8-image-transformations-developers-can-make-on-the-fly-learning-by-example\" rel=\"noreferrer noopener\">transformation options<\/a> that ensure your videos are optimized for performance without sacrificing quality. Here are some key parameters:<\/p>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li><strong><code>quality: 'auto'<\/code><\/strong>. The quality parameter defines the level of compression applied to a video. When set to &#8216;auto&#8217;, Cloudinary automatically chooses the <a href=\"https:\/\/cloudinary.com\/documentation\/video_optimization#automatic_quality_q_auto\" target=\"_blank\" rel=\"noreferrer noopener\">best quality setting<\/a> based on the video content and the need to balance visual quality with file size.<\/li>\n<\/ol>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong><code>format: 'auto'<\/code><\/strong>. The format parameter defines the file format in which the video is delivered. By setting format: &#8216;auto&#8217;, Cloudinary can choose the best format based on the user&#8217;s browser and device. However, since TikTok requires MP4 format for uploads, you\u2019ll explicitly specify format: &#8216;mp4&#8217;. 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.<\/li>\n<\/ol>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>width<\/strong><strong> and <\/strong><strong>height<\/strong>. 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 <a href=\"https:\/\/www.videostudiopro.com\/en\/tips\/tiktok\/dimensions\" target=\"_blank\" rel=\"noreferrer noopener\">TikTok\u2019s dimensions<\/a> without being unnecessarily large, reducing file size while maintaining the vertical orientation that TikTok users expect.<\/li>\n<\/ol>\n\n\n\n<ol start=\"4\" class=\"wp-block-list\">\n<li><strong><code>crop: 'fill'<\/code><\/strong>. 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.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Implementing Video Optimization in the Server Action<\/strong><\/h2>\n\n\n\n<p>You\u2019ll implement these optimizations in the <code>app\/upload.ts<\/code> file by improving the uploaded video and returning the optimized URL.<\/p>\n\n\n\n<p>In the <code>upload.ts<\/code> file, update the function to include the following code:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ app\/upload.ts<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> optimizedVideoUrl = cloudinary.url(uploadResponse.public_id,{\n\n\u00a0 \u00a0 <span class=\"hljs-attr\">resource_type<\/span>:<span class=\"hljs-string\">'video'<\/span>,\n\n\u00a0 \u00a0 <span class=\"hljs-attr\">width<\/span>: <span class=\"hljs-number\">1080<\/span>,\n\n\u00a0 \u00a0 <span class=\"hljs-attr\">height<\/span>:<span class=\"hljs-number\">1920<\/span>,\n\n\u00a0 \u00a0 <span class=\"hljs-attr\">crop<\/span>:<span class=\"hljs-string\">'fill'<\/span>,\n\n\u00a0 \u00a0 <span class=\"hljs-attr\">quality<\/span>:<span class=\"hljs-string\">'auto'<\/span>,\n\n\u00a0 \u00a0 <span class=\"hljs-attr\">format<\/span>:<span class=\"hljs-string\">'mp4'<\/span>,\n\n});\n\n<span class=\"hljs-keyword\">return<\/span> optimizedVideoUrl;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This function takes the uploaded video and applies the necessary transformations to make it TikTok-ready. The <code>optimizedVideoUrl<\/code>` returned from this function can be used to display and download the video on the client side.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Displaying and Downloading the Optimized Video<\/strong><\/h2>\n\n\n\n<p>Once the video is optimized, it\u2019s time to display it and provide an option for users to download the video.<\/p>\n\n\n\n<p>Create a state to store the optimized video URL in the <code>page.tsx<\/code> file and store the video URL to the state in the try block:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ app\/page.tsx<\/span>\n\n<span class=\"hljs-keyword\">const<\/span>&#91;optimizedVideoUrl, setOptimizedVideoUrl]= useState&lt;string&gt;(<span class=\"hljs-string\">''<\/span>);\n\n<span class=\"hljs-keyword\">const<\/span>&#91;loading, setLoading]= useState(<span class=\"hljs-literal\">false<\/span>);\n\n<span class=\"hljs-keyword\">const<\/span> handleSubmit = <span class=\"hljs-keyword\">async<\/span> (event: React.FormEvent&lt;HTMLFormElement&gt;)=&gt;{\n\n\u00a0 \u00a0 event.preventDefault();\n\n\u00a0 \u00a0 setLoading(<span class=\"hljs-literal\">true<\/span>);\n\n<span class=\"hljs-keyword\">const<\/span> formData =<span class=\"hljs-keyword\">new<\/span> FormData(event.currentTarget);\n\n\u00a0 \u00a0 <span class=\"hljs-keyword\">try<\/span> {\n\n<span class=\"hljs-keyword\">const<\/span> videoUrl: string = <span class=\"hljs-keyword\">await<\/span> upload(formData);\n\n\u00a0 \u00a0 \u00a0 \u00a0 setOptimizedVideoUrl(videoUrl);\n\n} <span class=\"hljs-keyword\">catch<\/span> (error){\n\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-built_in\">console<\/span>.error(<span class=\"hljs-string\">'Upload failed'<\/span>, error);\n\n} <span class=\"hljs-keyword\">finally<\/span> {\n\n\u00a0 \u00a0 \u00a0 \u00a0 setLoading(<span class=\"hljs-literal\">false<\/span>);<span class=\"hljs-comment\">\/\/ Stop loading state<\/span>\n\n}\n\n};<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The code above handles the form submission, uploads the video, and stores the optimized video URL in the optimizedVideoUrl state.<\/p>\n\n\n\n<p>Now, use the <code>optimizedVideoUrl<\/code> to display the video on the <code>page.tsx<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ app\/page.tsx<\/span>\n\n{optimizedVideoUrl &amp;&amp; (\n\n\u00a0 \u00a0 <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"flex justify-center space-x-4 mt-10\"<\/span>&gt;<\/span>\n\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h2<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"text-lg font-bold text-center mb-4\"<\/span>&gt;<\/span>\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 Optimized Video\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h2<\/span>&gt;<\/span>\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">video<\/span>\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{optimizedVideoUrl}<\/span>\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">controls<\/span>\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"w-full max-w-md border-4 rounded\"<\/span>\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \/&gt;<\/span>\n\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\n\u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n\n)}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The code above conditionally renders the video only when the <code>optimizedVideoUrl<\/code> is available, providing a video player to preview the optimized TikTok video.<\/p>\n\n\n\n<p>Finally, to allow users download the optimized video, ready for TikTok upload. Add the following function in your page.tsx file to handle download:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ app.page.tsx<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> handleDownload = <span class=\"hljs-keyword\">async<\/span> ()=&gt;{\n\n\u00a0 \u00a0 <span class=\"hljs-keyword\">if<\/span> (optimizedVideoUrl){\n\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-comment\">\/\/ Fetch the video from the URL<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> response = <span class=\"hljs-keyword\">await<\/span> fetch(optimizedVideoUrl,{\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">method<\/span>:<span class=\"hljs-string\">'GET'<\/span>,\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">mode<\/span>:<span class=\"hljs-string\">'cors'<\/span>,\n\n});\n\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-comment\">\/\/ Create a blob from the response<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> blob = <span class=\"hljs-keyword\">await<\/span> response.blob();\n\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-comment\">\/\/ Create a URL for the blob object<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> blobUrl = <span class=\"hljs-built_in\">window<\/span>.URL.createObjectURL(blob);\n\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-comment\">\/\/ Create a link element and trigger the download<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> a = <span class=\"hljs-built_in\">document<\/span>.createElement(<span class=\"hljs-string\">'a'<\/span>);\n\n\u00a0 \u00a0 \u00a0 \u00a0 a.href = blobUrl;\n\n\u00a0 \u00a0 \u00a0 \u00a0 a.download =<span class=\"hljs-string\">`optimized_video`<\/span>;\n\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-built_in\">document<\/span>.body.appendChild(a);\n\n\u00a0 \u00a0 \u00a0 \u00a0 a.click();\n\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-comment\">\/\/ Clean up the URL object<\/span>\n\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-built_in\">window<\/span>.URL.revokeObjectURL(blobUrl);\n\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-built_in\">document<\/span>.body.removeChild(a);\n\n}\n\n};<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Then, create a button on the <code>page.tsx<\/code> file and attach the download function in the code above to an <code>onClick<\/code> event as shown below:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\">\/\/ app\/page.tsx\n\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span>\n\n\u00a0 \u00a0 <span class=\"hljs-attr\">onClick<\/span>=<span class=\"hljs-string\">{handleDownload}<\/span>\n\n\u00a0 \u00a0 <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"bg-green-600 text-white p-2 rounded-md\"<\/span>\n\n&gt;<\/span>\n\n\u00a0 \u00a0 Download Video\n\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This allows users to view the optimized video and download it in MP4 format, ready for upload to TikTok. &nbsp;<\/p>\n\n\n\n<p>In the demo below, a 26.7 MB wide video is uploaded. After applying Cloudinary\u2019s optimization techniques, the video size is reduced to 20 MB still with a high quality.<\/p>\n\n\n<cld-video-player\n      cloud-name='cloudinary-marketing'\n      public-id='v1734748697\/Video_Optimization_Cloudinary-Next.js'\n      js-config='{\"playbackRates\":[0.5,1,1.5,2]}'\n      style='max-width: ;'\n      class='c-video-player'\n      \n      core-version='2.12.3'\n      player-version='1.7.0'\n      >\n      <video\n        id='_video-player69e2f36559802'\n        data-cld-big-play-button='init'\n        data-cld-source-types='[\"hls\",\"webm\\\/vp9\",\"mp4\\\/h265\",\"mp4\"]'\n        controls\n        muted\n        class='cld-video-player cld-fluid wp-block-cloudinary-video-player  cld-video-player-skin-dark'\n      ><\/video>\n    <\/cld-video-player>\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>In this blog post, you learned how to upload an unoptimized video, apply smart cropping, and resize it for TikTok\u2019s vertical format \u2014 all in a few steps. Learn more about Cloudinary\u2019s suite of video optimization and transformation capabilities. <a target=\"_blank\" href=\"https:\/\/cloudinary.com\/users\/register_free\" rel=\"noreferrer noopener\">Sign up for a free account today<\/a>.<\/p>\n\n\n\n<p>If you enjoyed this post and want to discuss it more, join the <a target=\"_blank\" href=\"https:\/\/community.cloudinary.com\/\" rel=\"noreferrer noopener\">Cloudinary Community forum<\/a> and its associated <a target=\"_blank\" href=\"https:\/\/discord.com\/invite\/cloudinary\" rel=\"noreferrer noopener\">Discord<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Resources<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/cloudinary.com\/documentation\/video_manipulation_and_delivery\" target=\"_blank\" rel=\"noreferrer noopener\">Cloudinary Video Documentation<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/cloudinary.com\/documentation\/programmable_media_overview\" target=\"_blank\" rel=\"noreferrer noopener\">Cloudinary Overall Media Documentation<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/cloudinary.com\/documentation\/video_optimization\" target=\"_blank\" rel=\"noreferrer noopener\">Cloudinary Video Optimization<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/cloudinary.com\/documentation\/video_manipulation_and_delivery\" target=\"_blank\" rel=\"noreferrer noopener\">Video transformations<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/nextjs.org\/docs\" target=\"_blank\" rel=\"noreferrer noopener\">Next.js Documentation<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Creating engaging TikTok videos isn\u2019t just about creativity; it\u2019s about keeping up with fleeting trends. With over a billion active users on TikTok, every second counts. A slow-loading video can lose viewers&#8217; attention in an instant, leading to lower engagement and higher data usage.&nbsp; This blog post shows you how to automatically generate low-size, high-quality, [&hellip;]<\/p>\n","protected":false},"author":87,"featured_media":36488,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[212,227,303],"class_list":["post-36485","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-next-js","tag-performance-optimization","tag-video"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Automatically Generate a Low-Size TikTok Video From an Original Video<\/title>\n<meta name=\"description\" content=\"Creating engaging TikTok videos isn\u2019t just about creativity; it\u2019s about keeping up with fleeting trends. With over a billion active users on TikTok, every\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cloudinary.com\/blog\/low-size-tiktok-video\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Automatically Generate a Low-Size TikTok Video From an Original Video\" \/>\n<meta property=\"og:description\" content=\"Creating engaging TikTok videos isn\u2019t just about creativity; it\u2019s about keeping up with fleeting trends. With over a billion active users on TikTok, every\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/low-size-tiktok-video\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2025-01-03T15:00:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1734749176\/Web_Assets\/blog\/Automatically_generate_low-size_Tiktok_video_from_original_video\/Automatically_generate_low-size_Tiktok_video_from_original_video.jpg?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"2000\" \/>\n\t<meta property=\"og:image:height\" content=\"1100\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"melindapham\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/low-size-tiktok-video#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/low-size-tiktok-video\"},\"author\":{\"name\":\"melindapham\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9\"},\"headline\":\"Automatically Generate a Low-Size TikTok Video From an Original Video\",\"datePublished\":\"2025-01-03T15:00:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/low-size-tiktok-video\"},\"wordCount\":1120,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/low-size-tiktok-video#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1734749176\/Web_Assets\/blog\/Automatically_generate_low-size_Tiktok_video_from_original_video\/Automatically_generate_low-size_Tiktok_video_from_original_video.jpg?_i=AA\",\"keywords\":[\"Next.js\",\"Performance Optimization\",\"Video\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/low-size-tiktok-video\",\"url\":\"https:\/\/cloudinary.com\/blog\/low-size-tiktok-video\",\"name\":\"Automatically Generate a Low-Size TikTok Video From an Original Video\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/low-size-tiktok-video#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/low-size-tiktok-video#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1734749176\/Web_Assets\/blog\/Automatically_generate_low-size_Tiktok_video_from_original_video\/Automatically_generate_low-size_Tiktok_video_from_original_video.jpg?_i=AA\",\"datePublished\":\"2025-01-03T15:00:00+00:00\",\"description\":\"Creating engaging TikTok videos isn\u2019t just about creativity; it\u2019s about keeping up with fleeting trends. With over a billion active users on TikTok, every\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/low-size-tiktok-video#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/low-size-tiktok-video\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/low-size-tiktok-video#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1734749176\/Web_Assets\/blog\/Automatically_generate_low-size_Tiktok_video_from_original_video\/Automatically_generate_low-size_Tiktok_video_from_original_video.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1734749176\/Web_Assets\/blog\/Automatically_generate_low-size_Tiktok_video_from_original_video\/Automatically_generate_low-size_Tiktok_video_from_original_video.jpg?_i=AA\",\"width\":2000,\"height\":1100},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/low-size-tiktok-video#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Automatically Generate a Low-Size TikTok Video From an Original Video\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"name\":\"Cloudinary Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cloudinary.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\",\"name\":\"Cloudinary Blog\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"width\":312,\"height\":60,\"caption\":\"Cloudinary Blog\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9\",\"name\":\"melindapham\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g\",\"caption\":\"melindapham\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Automatically Generate a Low-Size TikTok Video From an Original Video","description":"Creating engaging TikTok videos isn\u2019t just about creativity; it\u2019s about keeping up with fleeting trends. With over a billion active users on TikTok, every","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/cloudinary.com\/blog\/low-size-tiktok-video","og_locale":"en_US","og_type":"article","og_title":"Automatically Generate a Low-Size TikTok Video From an Original Video","og_description":"Creating engaging TikTok videos isn\u2019t just about creativity; it\u2019s about keeping up with fleeting trends. With over a billion active users on TikTok, every","og_url":"https:\/\/cloudinary.com\/blog\/low-size-tiktok-video","og_site_name":"Cloudinary Blog","article_published_time":"2025-01-03T15:00:00+00:00","og_image":[{"width":2000,"height":1100,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1734749176\/Web_Assets\/blog\/Automatically_generate_low-size_Tiktok_video_from_original_video\/Automatically_generate_low-size_Tiktok_video_from_original_video.jpg?_i=AA","type":"image\/jpeg"}],"author":"melindapham","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/low-size-tiktok-video#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/low-size-tiktok-video"},"author":{"name":"melindapham","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9"},"headline":"Automatically Generate a Low-Size TikTok Video From an Original Video","datePublished":"2025-01-03T15:00:00+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/low-size-tiktok-video"},"wordCount":1120,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/low-size-tiktok-video#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1734749176\/Web_Assets\/blog\/Automatically_generate_low-size_Tiktok_video_from_original_video\/Automatically_generate_low-size_Tiktok_video_from_original_video.jpg?_i=AA","keywords":["Next.js","Performance Optimization","Video"],"inLanguage":"en-US","copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/low-size-tiktok-video","url":"https:\/\/cloudinary.com\/blog\/low-size-tiktok-video","name":"Automatically Generate a Low-Size TikTok Video From an Original Video","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/low-size-tiktok-video#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/low-size-tiktok-video#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1734749176\/Web_Assets\/blog\/Automatically_generate_low-size_Tiktok_video_from_original_video\/Automatically_generate_low-size_Tiktok_video_from_original_video.jpg?_i=AA","datePublished":"2025-01-03T15:00:00+00:00","description":"Creating engaging TikTok videos isn\u2019t just about creativity; it\u2019s about keeping up with fleeting trends. With over a billion active users on TikTok, every","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/low-size-tiktok-video#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/low-size-tiktok-video"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/low-size-tiktok-video#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1734749176\/Web_Assets\/blog\/Automatically_generate_low-size_Tiktok_video_from_original_video\/Automatically_generate_low-size_Tiktok_video_from_original_video.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1734749176\/Web_Assets\/blog\/Automatically_generate_low-size_Tiktok_video_from_original_video\/Automatically_generate_low-size_Tiktok_video_from_original_video.jpg?_i=AA","width":2000,"height":1100},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/low-size-tiktok-video#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Automatically Generate a Low-Size TikTok Video From an Original Video"}]},{"@type":"WebSite","@id":"https:\/\/cloudinary.com\/blog\/#website","url":"https:\/\/cloudinary.com\/blog\/","name":"Cloudinary Blog","description":"","publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cloudinary.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/cloudinary.com\/blog\/#organization","name":"Cloudinary Blog","url":"https:\/\/cloudinary.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","width":312,"height":60,"caption":"Cloudinary Blog"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9","name":"melindapham","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g","caption":"melindapham"}}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1734749176\/Web_Assets\/blog\/Automatically_generate_low-size_Tiktok_video_from_original_video\/Automatically_generate_low-size_Tiktok_video_from_original_video.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/36485","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/users\/87"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=36485"}],"version-history":[{"count":1,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/36485\/revisions"}],"predecessor-version":[{"id":36489,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/36485\/revisions\/36489"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/36488"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=36485"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=36485"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=36485"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}