{"id":36453,"date":"2025-01-24T07:00:00","date_gmt":"2025-01-24T15:00:00","guid":{"rendered":"https:\/\/cloudinary.com\/blog\/?p=36453"},"modified":"2025-01-29T13:52:56","modified_gmt":"2025-01-29T21:52:56","slug":"ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery","title":{"rendered":"AI Video Workflow With PHP and Cloudinary \u2013 From Upload to Delivery"},"content":{"rendered":"\n<p>Just like with images, Cloudinary offers powerful tools for optimizing and automating video workflows. From handling client-side video uploads and integrating AI moderation for content safety asynchronously to delivering seamless video streaming, Cloudinary\u2019s flexibility shines.<\/p>\n\n\n\n<p>In this blog post, we\u2019ll walk through a video workflow example using Cloudinary\u2019s PHP SDK, demonstrated with a product catalog app. While the demo focuses on a product catalog, the techniques and workflows apply to any application that manages videos. Here\u2019s the video workflow we\u2019ll explore:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img width=\"1024\" height=\"135\" data-public-id=\"Web_Assets\/blog\/Video-3\/Video-3.png\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_1024,h_135,c_scale\/f_auto,q_auto\/v1737448769\/Web_Assets\/blog\/Video-3\/Video-3.png?_i=AA\" alt=\"\" class=\"wp-post-36453 wp-image-36584\" loading=\"lazy\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1737448769\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1737448769\/Web_Assets\/blog\/Video-3\/Video-3.png?_i=AA 1529w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1737448769\/Web_Assets\/blog\/Video-3\/Video-3.png?_i=AA 300w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1737448769\/Web_Assets\/blog\/Video-3\/Video-3.png?_i=AA 768w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1737448769\/Web_Assets\/blog\/Video-3\/Video-3.png?_i=AA 1024w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>As you read, think about which aspects of this video workflow might best suit your own PHP app as we explore how it integrates seamlessly into the PHP Product Catalog demo app.<\/p>\n\n\n<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p>If you\u2019re just getting started with video workflows, be sure to check out the <a href=\"https:\/\/cloudinary.com\/blog\/ai-image-workflows-php\">previous post<\/a> in this series, where we explored how Cloudinary handles image uploads, AI-driven transformations, and delivery.<\/p>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\"><strong>E-commerce Demo Overview<\/strong><\/h2>\n\n\n\n<p>The PHP Product Catalog app showcases a simulated product catalog with products stored in a database. Each product includes a name, metadata (SKU, price, and category), an auto-generated description, an image, and a video. For details on the video upload-to-delivery workflow, check out the previous blog in this series.<\/p>\n\n\n\n<p>With this app, you can:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Add new products with images.<\/li>\n\n\n\n<li>View all products or individual product details.<\/li>\n\n\n\n<li>Edit product metadata and media.<\/li>\n<\/ul>\n\n\n\n<p>See the app&#8217;s image features in action:<\/p>\n\n\n<cld-video-player\n      cloud-name='cloudinary'\n      public-id='training\/php_product_catalog_video'\n      js-config='{\"playbackRates\":[0.5,1,1.5,2]}'\n      style='max-width: 700px;'\n      class='c-video-player'\n      poster-timestamp='149'\n      core-version='2.12.3'\n      player-version='1.7.0'\n      >\n      <video\n        id='_video-player69dc423cd7c06'\n        data-cld-big-play-button='init'\n        data-cld-source-types='[\"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\"><strong>Get Started<\/strong><\/h2>\n\n\n\n<p>To follow along with this blog, make sure you:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><a href=\"https:\/\/cloudinary.com\/users\/register_free\">Sign up for a Cloudinary account and try it for free!<\/a><\/li>\n\n\n\n<li>Find the full code for this app on <a href=\"https:\/\/github.com\/cloudinary-devs\/php-product-catalog\">GitHub<\/a> and follow the README for setup and installation instructions.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Client-Side Video Uploads<\/strong><\/h2>\n\n\n\n<p>The first step in managing video workflows is uploading files to Cloudinary. The <a href=\"https:\/\/cloudinary.com\/documentation\/upload_widget\">Upload widget <\/a> provides an intuitive interface for direct uploads, removing the need for backend dependencies.<\/p>\n\n\n\n<p>Here\u2019s how the Upload widget is configured in the demo app:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ Configure the upload widget for videos<\/span>\n    <span class=\"hljs-keyword\">const<\/span> videoWidget = cloudinary.createUploadWidget({\n        <span class=\"hljs-attr\">cloudName<\/span>: <span class=\"hljs-string\">'&lt;?php echo $_ENV&#91;'<\/span>CLOUDINARY_CLOUD_NAME<span class=\"hljs-string\">']; ?&gt;'<\/span>, <span class=\"hljs-comment\">\/\/ Replace with your Cloudinary cloud name<\/span>\n        <span class=\"hljs-attr\">uploadPreset<\/span>: <span class=\"hljs-string\">'php_demo_preset'<\/span>, <span class=\"hljs-comment\">\/\/ Replace with your upload preset<\/span>\n        <span class=\"hljs-attr\">sources<\/span>: &#91;<span class=\"hljs-string\">'local'<\/span>, <span class=\"hljs-string\">'url'<\/span>], <span class=\"hljs-comment\">\/\/ Allow uploads from local files and URLs<\/span>\n        <span class=\"hljs-attr\">resourceType<\/span>: <span class=\"hljs-string\">'video'<\/span>, <span class=\"hljs-comment\">\/\/ Specify resource type as video<\/span>\n        <span class=\"hljs-attr\">maxFileSize<\/span>: <span class=\"hljs-number\">50000000<\/span>, <span class=\"hljs-comment\">\/\/ Set a max file size (optional)<\/span>\n        <span class=\"hljs-attr\">folder<\/span>: <span class=\"hljs-string\">'products\/videos'<\/span>, <span class=\"hljs-comment\">\/\/ Optional folder path<\/span>\n    }, (error, result) =&gt; {\n        <span class=\"hljs-keyword\">if<\/span> (!error &amp;&amp; result &amp;&amp; result.event === <span class=\"hljs-string\">\"success\"<\/span>) {\n            <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">'Video uploaded successfully:'<\/span>, result.info.secure_url);\n            <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">'video_url'<\/span>).value = result.info.secure_url;\n            <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">'video_id'<\/span>).value = result.info.public_id;\n            <span class=\"hljs-comment\">\/\/ Display the new video alongside the current one<\/span>\n            <span class=\"hljs-keyword\">const<\/span> videoSection = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">\"video_section\"<\/span>);\n            videoSection.innerHTML = <span class=\"hljs-string\">`\n                &lt;label&gt;Video:&lt;\/label&gt;\n                &lt;div&gt;\n                    &lt;video controls style=\"max-width: 200px; height: auto; margin-bottom: 15px;\"&gt;\n                        &lt;source src=\"<span class=\"hljs-subst\">${result.info.secure_url}<\/span>\" type=\"video\/mp4\"&gt;\n                        Your browser does not support the video tag.\n                    &lt;\/video&gt;\n                &lt;\/div&gt;\n            `<\/span>;\n        }\n    });\n\n    <span class=\"hljs-comment\">\/\/ Open the video upload widget<\/span>\n    <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">'upload_video_button'<\/span>).addEventListener(<span class=\"hljs-string\">'click'<\/span>, () =&gt; {\n        videoWidget.open();\n    });\n&lt;<span class=\"hljs-regexp\">\/script&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><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<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p>You need to specify your <code>cloudName<\/code> and an unsigned <code>uploadPreset<\/code> to instantiate an Upload Widget.<\/p>\n<ul>\n<li>Find your <code>cloudName<\/code> on your Cloudinary dashboard.<\/li>\n<li>In the Product Catalog demo app, you run the script to create the <code>php_demo_preset<\/code> when clicking the first time setup button on the main page of the app. For more information about this upload preset and how to create it, see <a href=\"https:\/\/cloudinary.com\/blog\/ai-image-workflows-php\">AI Image Workflows with PHP and Cloudinary<\/a>\n<\/li>\n<\/ul>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\"><strong>Apply AI Moderation<\/strong> Asynchronously<\/h2>\n\n\n\n<p>AI moderation ensures content safety, especially for user-generated videos. With Cloudinary add-ons like <a href=\"https:\/\/cloudinary.com\/documentation\/aws_rekognition_video_moderation_addon#banner\">Amazon Rekognition Video Moderation<\/a>, you can have videos automatically reviewed asynchronously.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Backend Implementation<\/h3>\n\n\n\n<p>In our demo app, when you add or edit a product, the app sends the uploaded video for automatic moderation using the <a href=\"https:\/\/cloudinary.com\/documentation\/image_upload_api_reference#explicit\">explicit<\/a> method of the Upload API. The review process occurs in the background, allowing users to continue using the app without interruptions. A placeholder message informs users that the video is under review. The app marks the video\u2019s moderation status as \u201cpending\u201d and updates the database with the results once moderation is complete.<\/p>\n\n\n\n<p>Here&#8217;s the code: <\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-meta\">&lt;?php<\/span>\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/..\/vendor\/autoload.php'<\/span>;\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/..\/includes\/database.php'<\/span>;\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/..\/includes\/functions.php'<\/span>;\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/..\/config\/cloudinary_config.php'<\/span>;\n\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Dotenv<\/span>\\<span class=\"hljs-title\">Dotenv<\/span>;\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Cloudinary<\/span>\\<span class=\"hljs-title\">Configuration<\/span>\\<span class=\"hljs-title\">Configuration<\/span>;\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Cloudinary<\/span>\\<span class=\"hljs-title\">Cloudinary<\/span>;\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Cloudinary<\/span>\\<span class=\"hljs-title\">Api<\/span>\\<span class=\"hljs-title\">Admin<\/span>\\<span class=\"hljs-title\">AdminApi<\/span>;\n\n$dotenv = Dotenv::createImmutable(dirname(<span class=\"hljs-keyword\">__DIR__<\/span>));\n$dotenv-&gt;load();\n\n<span class=\"hljs-comment\">\/\/ Initialize Configuration<\/span>\n$config = <span class=\"hljs-keyword\">new<\/span> Configuration($_ENV&#91;<span class=\"hljs-string\">'CLOUDINARY_URL'<\/span>]);\n\n$api = <span class=\"hljs-keyword\">new<\/span> AdminAPI($config);\n\n    <span class=\"hljs-comment\">\/\/ Handle Video Moderation and Metadata<\/span>\n    <span class=\"hljs-keyword\">if<\/span> (!<span class=\"hljs-keyword\">empty<\/span>($_POST&#91;<span class=\"hljs-string\">'video_url'<\/span>])) {\n        $product_video_url = $_POST&#91;<span class=\"hljs-string\">'video_url'<\/span>];\n        <span class=\"hljs-comment\">\/\/ Hold the video public ID temporarily until moderation status is confirmed.<\/span>\n        $video_public_id_temp = $_POST&#91;<span class=\"hljs-string\">'video_id'<\/span>];\n        <span class=\"hljs-comment\">\/\/ Set metadata and mark the video for moderation.<\/span>\n        $cloudinary_result = $cld-&gt;uploadApi()-&gt;explicit($video_public_id_temp, &#91;<span class=\"hljs-string\">'type'<\/span> =&gt; <span class=\"hljs-string\">'upload'<\/span>, <span class=\"hljs-string\">'resource_type'<\/span> =&gt; <span class=\"hljs-string\">'video'<\/span>, <span class=\"hljs-string\">'moderation'<\/span> =&gt; <span class=\"hljs-string\">'aws_rek_video'<\/span>, <span class=\"hljs-string\">\"metadata\"<\/span> =&gt; $metadata]);\n        <span class=\"hljs-comment\">\/\/ Set initial values, pending moderation<\/span>\n        $product_video_url = <span class=\"hljs-keyword\">null<\/span>; \n        $video_public_id = <span class=\"hljs-string\">\"pending\"<\/span>;\n        $video_moderation_status=<span class=\"hljs-string\">\"pending\"<\/span>;     \n    } <span class=\"hljs-keyword\">else<\/span> {\n        <span class=\"hljs-comment\">\/\/ Set values in case there's no video.<\/span>\n        $product_video_url=<span class=\"hljs-string\">\"invalid\"<\/span>;\n        $video_public_id = <span class=\"hljs-string\">\"invalid\"<\/span>;\n        $video_moderation_status=<span class=\"hljs-keyword\">null<\/span>;\n        $video_public_id_temp=<span class=\"hljs-keyword\">null<\/span>;\n    }\n    <span class=\"hljs-comment\">\/\/ Save the values in the database.<\/span>\n    $product_id = saveProduct($pdo, $name, $product_image_url, $product_video_url, $image_public_id,  $video_public_id, $video_moderation_status, $image_caption, $video_public_id_temp);\n    header(<span class=\"hljs-string\">\"Location: products.php\"<\/span>);\n    <span class=\"hljs-keyword\">exit<\/span>;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><strong>Explanation:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>In this example, we use the <a href=\"https:\/\/cloudinary.com\/documentation\/image_upload_api_reference#explicit\">explicit<\/a> method of the Upload API to moderate videos that are already uploaded.\n<ul class=\"wp-block-list\">\n<li><code>use Cloudinary\\Api\\Upload\\UploadApi;<\/code> imports the library. <\/li>\n\n\n\n<li><code>$api = new AdminAPI($config);<\/code> creates an instance for using those methods.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Set the moderation parameter to <code>aws_rek_video<\/code> for video content moderation. (To use <code>aws_rek_video<\/code>, you need to sign up for the Rekognition AI Video Moderation <a href=\"https:\/\/console.cloudinary.com\/settings\/addons\">add-on<\/a> as described in the app\u2019s <a href=\"https:\/\/github.com\/cloudinary-devs\/php-product-catalog\/blob\/main\/readme.md\">Readme<\/a> file.)&nbsp;<\/li>\n\n\n\n<li>The Cloudinary PHP SDK automatically chunks large videos for easier uploading.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Handle Moderation <\/h2>\n\n\n\n<p>Webhooks enable the page to automatically render the video or display the rejected message once it has been processed. If you choose not to implement the webhook, you&#8217;ll need to refresh the page to render the video when the moderation process is complete.<\/p>\n\n\n<div class='c-callout  c-callout--inline-title c-callout--tip'><strong class='c-callout__title'>Tip:<\/strong> <p>Find the code for handling moderation on page refresh in the <code>products.php<\/code> and <code>product.php<\/code> files of the <a href=\"https:\/\/github.com\/cloudinary-devs\/php-product-catalog\">GitHub<\/a> repo.<\/p>\n<\/div>\n\n\n<h3 class=\"wp-block-heading\">Use Optional Webhooks<\/h3>\n\n\n\n<p>To receive a webhook notification whenever Cloudinary finishes moderating a video asset:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Go to the<a href=\"https:\/\/console.cloudinary.com\/settings\/webhooks\"> <strong>Webhook Notifications<\/strong><\/a> page of the Cloudinary Console Settings.<\/li>\n\n\n\n<li>Add the URL of your webhook endpoint with the suffix <code>webhooks\/video_upload_webhook.php<\/code> .<\/li>\n\n\n\n<li>Select <strong>Moderation<\/strong> in the <strong>Notification Type<\/strong> drop-down to listen for moderation notifications.<\/li>\n<\/ol>\n\n\n<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p>To test your app locally, you can use a tool like <a href=\"https:\/\/ngrok.com\/\">Ngrok<\/a> to create up a secure tunnel connecting the internet to your locally running app. Alternatively, deploy the app using a service like <a href=\"https:\/\/vercel.com\/\">Vercel<\/a>.<\/p>\n<\/div>\n\n\n<p>Once set up, Cloudinary sends a <code>POST<\/code> request to the specified URL with the moderation results.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Code Example: Handling Webhook Notifications for Video Moderation<\/strong><\/h3>\n\n\n\n<p>Let\u2019s walk through handling webhook notifications for video moderation using PHP.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-meta\">&lt;?php<\/span>\n<span class=\"hljs-comment\">\/\/ Set headers to prevent caching<\/span>\nheader(<span class=\"hljs-string\">'Content-Type: text\/event-stream'<\/span>);\nheader(<span class=\"hljs-string\">'Cache-Control: no-cache'<\/span>);\nheader(<span class=\"hljs-string\">'Connection: keep-alive'<\/span>);\n\n<span class=\"hljs-comment\">\/\/ Start output buffering<\/span>\nob_start();\n\n<span class=\"hljs-comment\">\/\/ Include necessary files<\/span>\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/..\/vendor\/autoload.php'<\/span>;\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/..\/includes\/database.php'<\/span>;\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/..\/config\/cloudinary_config.php'<\/span>;\n\n<span class=\"hljs-comment\">\/\/ Ensure you're receiving a POST request<\/span>\n<span class=\"hljs-keyword\">if<\/span> ($_SERVER&#91;<span class=\"hljs-string\">'REQUEST_METHOD'<\/span>] === <span class=\"hljs-string\">'POST'<\/span>) {\n   <span class=\"hljs-comment\">\/\/ Get the raw POST data from Cloudinary<\/span>\n   $payload = json_decode(file_get_contents(<span class=\"hljs-string\">'php:\/\/input'<\/span>), <span class=\"hljs-keyword\">true<\/span>);\n\n   <span class=\"hljs-comment\">\/\/ Ensure you received necessary Cloudinary data<\/span>\n   <span class=\"hljs-keyword\">if<\/span> (<span class=\"hljs-keyword\">isset<\/span>($payload&#91;<span class=\"hljs-string\">'public_id'<\/span>], $payload&#91;<span class=\"hljs-string\">'secure_url'<\/span>])) {\n      \n       <span class=\"hljs-comment\">\/\/ Get Cloudinary data from the webhook notification<\/span>\n       $video_moderation_status = $payload&#91;<span class=\"hljs-string\">'moderation_status'<\/span>];\n      \n       <span class=\"hljs-keyword\">if<\/span> ($video_moderation_status === <span class=\"hljs-string\">'approved'<\/span>){\n           $video_public_id = $payload&#91;<span class=\"hljs-string\">'public_id'<\/span>];\n           $product_video_url = $payload&#91;<span class=\"hljs-string\">'secure_url'<\/span>];\n           $rejection_reason = <span class=\"hljs-keyword\">null<\/span>;\n       } <span class=\"hljs-keyword\">else<\/span> {\n           $video_public_id = <span class=\"hljs-keyword\">null<\/span>;\n           $product_video_url = <span class=\"hljs-keyword\">null<\/span>;\n           $rejection_reason = $payload&#91;<span class=\"hljs-string\">'moderation_response'<\/span>]&#91;<span class=\"hljs-string\">'moderation_labels'<\/span>]&#91;<span class=\"hljs-number\">0<\/span>]&#91;<span class=\"hljs-string\">'moderation_label'<\/span>]&#91;<span class=\"hljs-string\">'name'<\/span>];\n       }\n\n       <span class=\"hljs-keyword\">try<\/span> {\n           <span class=\"hljs-comment\">\/\/ Find the record to update based on video_public_id_temp<\/span>\n           $sql = <span class=\"hljs-string\">\"SELECT id FROM products WHERE video_public_id_temp = ?\"<\/span>;\n           $stmt = $pdo-&gt;prepare($sql);\n           $stmt-&gt;execute(&#91;$payload&#91;<span class=\"hljs-string\">'public_id'<\/span>]]);\n           $product = $stmt-&gt;fetch(PDO::FETCH_ASSOC);\n      \n           <span class=\"hljs-keyword\">if<\/span> ($product) {\n               <span class=\"hljs-comment\">\/\/ Get the product ID of the matching record<\/span>\n               $product_id = $product&#91;<span class=\"hljs-string\">'id'<\/span>];\n      \n               <span class=\"hljs-comment\">\/\/ Update the database with video information<\/span>\n               $sql = <span class=\"hljs-string\">\"UPDATE products\n                       SET product_video_url = ?, video_public_id = ?, video_moderation_status = ?, rejection_reason = ?\n                       WHERE id = ?\"<\/span>;\n               $stmt = $pdo-&gt;prepare($sql);\n               $stmt-&gt;execute(&#91;$product_video_url, $video_public_id, $video_moderation_status, $rejection_reason, $product_id]);\n              \n               <span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"Product with ID $product_id successfully updated.\"<\/span>;\n               file_put_contents(<span class=\"hljs-string\">'upload_status.json'<\/span>, json_encode(&#91;<span class=\"hljs-string\">'status'<\/span> =&gt; <span class=\"hljs-string\">'completed'<\/span>]));\n               http_response_code(<span class=\"hljs-number\">200<\/span>);\n           } <span class=\"hljs-keyword\">else<\/span> {\n               <span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"No matching record found for video_public_id_temp = $video_public_id.\"<\/span>;\n           }\n       } <span class=\"hljs-keyword\">catch<\/span> (PDOException $e) {\n           <span class=\"hljs-comment\">\/\/ Handle database errors<\/span>\n           error_log(<span class=\"hljs-string\">\"Database error: \"<\/span> . $e-&gt;getMessage());\n           <span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"An error occurred while updating the product.\"<\/span>;\n       }            \n   }\n}\n\n<span class=\"hljs-comment\">\/\/ Clean output buffer and end the script<\/span>\nob_end_flush();\n<span class=\"hljs-meta\">?&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><strong>Explanation:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The code parses and checks the <strong>POST request<\/strong> payload to confirm that it contains the necessary video information (like <code>public_id<\/code> and <code>secure_url<\/code>).<\/li>\n\n\n\n<li>The code checks <code>moderation_status<\/code> to determine if the video is approved or rejected.<\/li>\n\n\n\n<li>In case of <strong>approval<\/strong>, the code updates the database with the video\u2019s public URL and ID.<\/li>\n\n\n\n<li>In case of <strong>rejection<\/strong>, the code records the rejection reason and updates the database accordingly.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Delivering Video With Cloudinary\u2019s Video Player<\/strong><\/h2>\n\n\n\n<p>The Cloudinary Video Player ensures fast and reliable video streaming, leveraging adaptive bitrate streaming to seamlessly adjust to varying network speeds. In addition, it\u2019s highly customizable, allowing you to align the player\u2019s design with your app\u2019s style while delivering a smooth playback experience.<\/p>\n\n\n\n<p>Finally, with the Video Player, you can optimize delivery for any screen size or internet connection, providing viewers with the best experience wherever they are.<\/p>\n\n\n\n<p>Here\u2019s the code to embed the Video Player:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"hljs-comment\">&lt;!-- Display product video if available --&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"product-image\"<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">b<\/span>&gt;<\/span>Video<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">b<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n            <span class=\"php\"><span class=\"hljs-meta\">&lt;?php<\/span> <span class=\"hljs-keyword\">if<\/span> ($product&#91;<span class=\"hljs-string\">'video_public_id'<\/span>] &amp;&amp; $product&#91;<span class=\"hljs-string\">'video_public_id'<\/span>]!=<span class=\"hljs-string\">'pending'<\/span> &amp;&amp; $product&#91;<span class=\"hljs-string\">'video_public_id'<\/span>]!=<span class=\"hljs-string\">'invalid'<\/span> &amp;&amp; $product&#91;<span class=\"hljs-string\">'video_moderation_status'<\/span>]!=<span class=\"hljs-string\">'rejected'<\/span>): <span class=\"hljs-meta\">?&gt;<\/span><\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n                 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">video<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"doc-player-&lt;?php echo $product&#91;'id']; ?&gt;\"<\/span> <span class=\"hljs-attr\">controls<\/span> <span class=\"hljs-attr\">muted<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"cld-video-player cld-fluid\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">video<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script<\/span>&gt;<\/span><span class=\"handlebars\"><span class=\"xml\">\n               \/\/ Render the video using Cloudinary's Video Player.\n               \/\/ Initialize the Cloudinary video player with a unique ID\n               const player_<span class=\"php\"><span class=\"hljs-meta\">&lt;?php<\/span> <span class=\"hljs-keyword\">echo<\/span> $product&#91;<span class=\"hljs-string\">'id'<\/span>]; <span class=\"hljs-meta\">?&gt;<\/span><\/span> = cloudinary.videoPlayer('doc-player-<span class=\"php\"><span class=\"hljs-meta\">&lt;?php<\/span> <span class=\"hljs-keyword\">echo<\/span> $product&#91;<span class=\"hljs-string\">'id'<\/span>]; <span class=\"hljs-meta\">?&gt;<\/span><\/span>', { cloudName: '<span class=\"php\"><span class=\"hljs-meta\">&lt;?php<\/span> <span class=\"hljs-keyword\">echo<\/span> $_ENV&#91;<span class=\"hljs-string\">'CLOUDINARY_CLOUD_NAME'<\/span>]; <span class=\"hljs-meta\">?&gt;<\/span><\/span>' });\n               player_<span class=\"php\"><span class=\"hljs-meta\">&lt;?php<\/span> <span class=\"hljs-keyword\">echo<\/span> $product&#91;<span class=\"hljs-string\">'id'<\/span>]; <span class=\"hljs-meta\">?&gt;<\/span><\/span>.source('<span class=\"php\"><span class=\"hljs-meta\">&lt;?php<\/span> <span class=\"hljs-keyword\">echo<\/span> $product&#91;<span class=\"hljs-string\">'video_public_id'<\/span>]; <span class=\"hljs-meta\">?&gt;<\/span><\/span>');\n            <\/span><\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/span>\n            <span class=\"php\"><span class=\"hljs-meta\">&lt;?php<\/span> <span class=\"hljs-keyword\">elseif<\/span> (<span class=\"hljs-keyword\">isset<\/span>($message)): <span class=\"hljs-meta\">?&gt;<\/span><\/span>\n                 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n                     <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span> <span class=\"hljs-attr\">style<\/span>=<span class=\"hljs-string\">\"color:&lt;?php echo $color; ?&gt;;\"<\/span>&gt;<\/span><span class=\"php\"><span class=\"hljs-meta\">&lt;?php<\/span> <span class=\"hljs-keyword\">echo<\/span> htmlspecialchars($message); <span class=\"hljs-meta\">?&gt;<\/span><\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n                 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n            <span class=\"php\"><span class=\"hljs-meta\">&lt;?php<\/span> <span class=\"hljs-keyword\">endif<\/span>; <span class=\"hljs-meta\">?&gt;<\/span><\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"edit_product.php?id=&lt;?php echo $product&#91;'id']; ?&gt;\"<\/span>&gt;<\/span>Edit<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"product.php?id=&lt;?php echo $product&#91;'id']; ?&gt;\"<\/span>&gt;<\/span>Preview Listing<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><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><strong>Explanation:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Rejected videos<\/strong> displays a message explaining the reason for rejection.<\/li>\n\n\n\n<li><strong>Pending videos<\/strong> prompts the user to wait until the moderation process is complete.<\/li>\n\n\n\n<li><strong>Approved videos<\/strong> renders the video using the Cloudinary Video Player, initialized using the public ID of the video.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Seamless Video Workflows With Cloudinary<\/strong><\/h2>\n\n\n\n<p>From uploading videos on the client side and applying AI moderation asynchronously to delivering optimized video streams, Cloudinary\u2019s workflow capabilities ensure that video content is handled efficiently and in compliance with safety standards. This post demonstrates how easy it is to integrate Cloudinary into your PHP app for managing video content, keeping your application responsive while maintaining high-quality user experiences and implementing flexible AI video workflows with PHP.<\/p>\n\n\n\n<p>For a deeper dive into managing images with Cloudinary, don\u2019t forget to revisit the previous post in this series. With Cloudinary\u2019s powerful tools at your disposal, the possibilities for enhancing media workflows in your app are endless. <a href=\"https:\/\/cloudinary.com\/users\/register_free\">Sign up for a free Cloudinary account <\/a> today and start optimizing your media management workflows.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Just like with images, Cloudinary offers powerful tools for optimizing and automating video workflows. From handling client-side video uploads and integrating AI moderation for content safety asynchronously to delivering seamless video streaming, Cloudinary\u2019s flexibility shines. In this blog post, we\u2019ll walk through a video workflow example using Cloudinary\u2019s PHP SDK, demonstrated with a product catalog [&hellip;]<\/p>\n","protected":false},"author":52,"featured_media":36638,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[336,229,310],"class_list":["post-36453","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-ai","tag-php","tag-video-player"],"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>AI Video Workflows with PHP and Cloudinary - Upload to Delivery<\/title>\n<meta name=\"description\" content=\"Discover AI video workflows with PHP &amp; Cloudinary. Deliver optimized video content with Video Player, client-side uploads, &amp; AI moderation.\" \/>\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\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"AI Video Workflow With PHP and Cloudinary \u2013 From Upload to Delivery\" \/>\n<meta property=\"og:description\" content=\"Discover AI video workflows with PHP &amp; Cloudinary. Deliver optimized video content with Video Player, client-side uploads, &amp; AI moderation.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2025-01-24T15:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-01-29T21:52:56+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1737158616\/AI_Video_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery\/AI_Video_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery-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=\"sharonyelenik\" \/>\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\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery\"},\"author\":{\"name\":\"sharonyelenik\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/dc4e70df8d22a9cfdad676a82fa92a73\"},\"headline\":\"AI Video Workflow With PHP and Cloudinary \u2013 From Upload to Delivery\",\"datePublished\":\"2025-01-24T15:00:00+00:00\",\"dateModified\":\"2025-01-29T21:52:56+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery\"},\"wordCount\":928,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1737158616\/AI_Video_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery\/AI_Video_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery.jpg?_i=AA\",\"keywords\":[\"AI\",\"PHP\",\"Video Player\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery\",\"url\":\"https:\/\/cloudinary.com\/blog\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery\",\"name\":\"AI Video Workflows with PHP and Cloudinary - Upload to Delivery\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1737158616\/AI_Video_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery\/AI_Video_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery.jpg?_i=AA\",\"datePublished\":\"2025-01-24T15:00:00+00:00\",\"dateModified\":\"2025-01-29T21:52:56+00:00\",\"description\":\"Discover AI video workflows with PHP & Cloudinary. Deliver optimized video content with Video Player, client-side uploads, & AI moderation.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1737158616\/AI_Video_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery\/AI_Video_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1737158616\/AI_Video_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery\/AI_Video_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery.jpg?_i=AA\",\"width\":2000,\"height\":1100},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"AI Video Workflow With PHP and Cloudinary \u2013 From Upload to Delivery\"}]},{\"@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\/dc4e70df8d22a9cfdad676a82fa92a73\",\"name\":\"sharonyelenik\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/6565cdd768a04e9b6ea3932764886209dd9de8baeeef1504eaad8fe776677f92?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/6565cdd768a04e9b6ea3932764886209dd9de8baeeef1504eaad8fe776677f92?s=96&d=mm&r=g\",\"caption\":\"sharonyelenik\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"AI Video Workflows with PHP and Cloudinary - Upload to Delivery","description":"Discover AI video workflows with PHP & Cloudinary. Deliver optimized video content with Video Player, client-side uploads, & AI moderation.","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\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery","og_locale":"en_US","og_type":"article","og_title":"AI Video Workflow With PHP and Cloudinary \u2013 From Upload to Delivery","og_description":"Discover AI video workflows with PHP & Cloudinary. Deliver optimized video content with Video Player, client-side uploads, & AI moderation.","og_url":"https:\/\/cloudinary.com\/blog\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery","og_site_name":"Cloudinary Blog","article_published_time":"2025-01-24T15:00:00+00:00","article_modified_time":"2025-01-29T21:52:56+00:00","og_image":[{"width":2000,"height":1100,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1737158616\/AI_Video_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery\/AI_Video_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery-jpg?_i=AA","type":"image\/jpeg"}],"author":"sharonyelenik","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery"},"author":{"name":"sharonyelenik","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/dc4e70df8d22a9cfdad676a82fa92a73"},"headline":"AI Video Workflow With PHP and Cloudinary \u2013 From Upload to Delivery","datePublished":"2025-01-24T15:00:00+00:00","dateModified":"2025-01-29T21:52:56+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery"},"wordCount":928,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1737158616\/AI_Video_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery\/AI_Video_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery.jpg?_i=AA","keywords":["AI","PHP","Video Player"],"inLanguage":"en-US","copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery","url":"https:\/\/cloudinary.com\/blog\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery","name":"AI Video Workflows with PHP and Cloudinary - Upload to Delivery","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1737158616\/AI_Video_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery\/AI_Video_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery.jpg?_i=AA","datePublished":"2025-01-24T15:00:00+00:00","dateModified":"2025-01-29T21:52:56+00:00","description":"Discover AI video workflows with PHP & Cloudinary. Deliver optimized video content with Video Player, client-side uploads, & AI moderation.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1737158616\/AI_Video_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery\/AI_Video_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1737158616\/AI_Video_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery\/AI_Video_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery.jpg?_i=AA","width":2000,"height":1100},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"AI Video Workflow With PHP and Cloudinary \u2013 From Upload to Delivery"}]},{"@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\/dc4e70df8d22a9cfdad676a82fa92a73","name":"sharonyelenik","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/6565cdd768a04e9b6ea3932764886209dd9de8baeeef1504eaad8fe776677f92?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/6565cdd768a04e9b6ea3932764886209dd9de8baeeef1504eaad8fe776677f92?s=96&d=mm&r=g","caption":"sharonyelenik"}}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1737158616\/AI_Video_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery\/AI_Video_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/36453","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\/52"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=36453"}],"version-history":[{"count":33,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/36453\/revisions"}],"predecessor-version":[{"id":36660,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/36453\/revisions\/36660"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/36638"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=36453"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=36453"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=36453"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}