colab-enterprise/Veo-2-text-to-video.ipynb (794 lines of code) (raw):
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "RqoS4ZK8unQP"
},
"source": [
"### <font color='#4285f4'>Overview</font>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "v0pvJXXhvyN9"
},
"source": [
"- Demostrats how to use Veo 2 REST API for creating videos\n",
"- Uses Gemini to re-write your original text-to-video prompt and incorporates best pratices for generating genai-videos."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "5R9CS3wkuqhU"
},
"source": [
"### <font color='#4285f4'>License</font>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "a6hOzD4Eus8g"
},
"source": [
"```\n",
"# Copyright 2024 Google LLC\n",
"#\n",
"# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"# you may not use this file except in compliance with the License.\n",
"# You may obtain a copy of the License at\n",
"#\n",
"# https://www.apache.org/licenses/LICENSE-2.0\n",
"#\n",
"# Unless required by applicable law or agreed to in writing, software\n",
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"# See the License for the specific language governing permissions and\n",
"# limitations under the License.\n",
"```\n",
"\n",
"Author: Adam Paternostro"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "H9NU3667e5lW"
},
"outputs": [],
"source": [
"from PIL import Image\n",
"from IPython.display import HTML\n",
"from IPython.display import Audio\n",
"from functools import reduce\n",
"import IPython.display\n",
"import google.auth\n",
"import requests\n",
"import json\n",
"import uuid\n",
"import base64\n",
"import os\n",
"import cv2\n",
"import random\n",
"import time\n",
"import datetime\n",
"import base64\n",
"import random\n",
"import datetime"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "s5rcnCWFuvIv"
},
"source": [
"### <font color='#4285f4'>Initialize</font>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "sgsTMDOre5v3"
},
"outputs": [],
"source": [
"# Set these (run this cell to verify the output)\n",
"\n",
"bigquery_location = \"${bigquery_location}\"\n",
"region = \"${region}\"\n",
"location = \"${location}\"\n",
"storage_account = \"${chocolate_ai_bucket}\"\n",
"\n",
"#bigquery_location = \"us\"\n",
"#region = \"us-central1\"\n",
"#location = \"us-central1\"\n",
"#storage_account = \"your-bucket\"\n",
"\n",
"# Get the current date and time\n",
"now = datetime.datetime.now()\n",
"\n",
"# Format the date and time as desired\n",
"formatted_date = now.strftime(\"%Y-%m-%d-%H-%M\")\n",
"\n",
"# Get some values using gcloud\n",
"project_id = !(gcloud config get-value project)\n",
"user = !(gcloud auth list --filter=status:ACTIVE --format=\"value(account)\")\n",
"\n",
"if len(project_id) != 1:\n",
" raise RuntimeError(f\"project_id is not set: {project_id}\")\n",
"project_id = project_id[0]\n",
"\n",
"if len(user) != 1:\n",
" raise RuntimeError(f\"user is not set: {user}\")\n",
"user = user[0]\n",
"\n",
"print(f\"project_id = {project_id}\")\n",
"print(f\"user = {user}\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "U4vNgqicuyNo"
},
"source": [
"### <font color='#4285f4'>Pip installs</font>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "dkqshG57uzTw"
},
"outputs": [],
"source": [
"# To read/write to/from Kafka\n",
"import sys\n",
"\n",
"# https://pypi.org/project/moviepy/\n",
"# !{sys.executable} -m pip install moviepy"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "6SoxlH9Iuzl6"
},
"source": [
"### <font color='#4285f4'>Helper Methods</font>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "G9SZiisbu3DQ"
},
"source": [
"#### restAPIHelper\n",
"Calls the Google Cloud REST API using the current users credentials."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Z4kGxLXJjOwF"
},
"outputs": [],
"source": [
"def restAPIHelper(url: str, http_verb: str, request_body: str) -> str:\n",
" \"\"\"Calls the Google Cloud REST API passing in the current users credentials\"\"\"\n",
"\n",
" import requests\n",
" import google.auth\n",
" import json\n",
"\n",
" # Get an access token based upon the current user\n",
" creds, project = google.auth.default()\n",
" auth_req = google.auth.transport.requests.Request()\n",
" creds.refresh(auth_req)\n",
" access_token=creds.token\n",
"\n",
" headers = {\n",
" \"Content-Type\" : \"application/json\",\n",
" \"Authorization\" : \"Bearer \" + access_token\n",
" }\n",
"\n",
" if http_verb == \"GET\":\n",
" response = requests.get(url, headers=headers)\n",
" elif http_verb == \"POST\":\n",
" response = requests.post(url, json=request_body, headers=headers)\n",
" elif http_verb == \"PUT\":\n",
" response = requests.put(url, json=request_body, headers=headers)\n",
" elif http_verb == \"PATCH\":\n",
" response = requests.patch(url, json=request_body, headers=headers)\n",
" elif http_verb == \"DELETE\":\n",
" response = requests.delete(url, headers=headers)\n",
" else:\n",
" raise RuntimeError(f\"Unknown HTTP verb: {http_verb}\")\n",
"\n",
" if response.status_code == 200:\n",
" return json.loads(response.content)\n",
" #image_data = json.loads(response.content)[\"predictions\"][0][\"bytesBase64Encoded\"]\n",
" else:\n",
" error = f\"Error restAPIHelper -> ' Status: '{response.status_code}' Text: '{response.text}'\"\n",
" raise RuntimeError(error)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "U-YdwCiNvECT"
},
"source": [
"#### generateVideo\n",
"Generates the video and waits for it to complete. Saves the prompt with the video and returns the file name."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "02Hkjv9Xe58U"
},
"outputs": [],
"source": [
"def generateVideo(prompt, storage_account, output_gcs_path):\n",
" \"\"\"Calls text-to-video to create the video and waits for the output (which can be several minutes). Saves the prompt/parameters with the vidoe. Returns the outputted path.\"\"\"\n",
"\n",
" full_output_gcs_path = f\"gs://{storage_account}/{output_gcs_path}\"\n",
" model = \"veo-2.0-generate-001\"\n",
" url = f\"https://{location}-aiplatform.googleapis.com/v1beta1/projects/{project_id}/locations/{location}/publishers/google/models/{model}:predictLongRunning\"\n",
"\n",
" request_body = {\n",
" \"instances\": [\n",
" {\n",
" \"prompt\": prompt\n",
" }\n",
" ],\n",
" \"parameters\": {\n",
" \"storageUri\": full_output_gcs_path,\n",
" \"aspectRatio\":\"16:9\"\n",
" }\n",
" }\n",
"\n",
" rest_api_parameters = request_body.copy()\n",
"\n",
" print(f\"url: {url}\")\n",
" print(f\"request_body: {request_body}\")\n",
" json_result = restAPIHelper(url, \"POST\", request_body)\n",
" print(f\"json_result: {json_result}\")\n",
" operation_name = json_result[\"name\"] # odd this is name\n",
"\n",
" url = f\"https://{location}-aiplatform.googleapis.com/v1beta1/projects/{project_id}/locations/{location}/publishers/google/models/{model}:fetchPredictOperation\"\n",
"\n",
" request_body = {\n",
" \"operationName\": operation_name\n",
" }\n",
"\n",
" status = False\n",
" # {\n",
" # \"name\": \"projects/chocolate-ai-demo-xxxxxx/locations/us-central1/publishers/google/models/veo-2.0-generate-001/operations/6d737b7c-5824-4f44-bc58-2e8d8226d2c2\",\n",
" # \"done\": True,\n",
" # \"response\": {\n",
" # \"@type\": \"type.googleapis.com/cloud.ai.large_models.vision.GenerateVideoResponse\",\n",
" # \"raiMediaFilteredCount\": 0,\n",
" # \"videos\": [\n",
" # {\n",
" # \"gcsUri\": \"gs: //chocolate-ai-data-xxxxxx/text-to-video/text-to-video-2025-04-15-13-59/9874965778463625250/sample_0.mp4\",\n",
" # \"mimeType\": \"video/mp4\"\n",
" # }\n",
" # ]\n",
" # }\n",
" # }\n",
"\n",
" while status == False:\n",
" time.sleep(10)\n",
" print(f\"url: {url}\")\n",
" print(f\"request_body: {request_body}\")\n",
" json_result = restAPIHelper(url, \"POST\", request_body)\n",
" print(f\"json_result: {json_result}\")\n",
" if \"done\" in json_result:\n",
" status = bool(json_result[\"done\"]) # in the future might be a status of running\n",
" else:\n",
" print(\"Status 'done' JSON attribute not present. Assuming not done...\")\n",
"\n",
" # Get the filename of our video\n",
" filename = json_result[\"response\"][\"videos\"][0][\"gcsUri\"]\n",
"\n",
" # Save our prompt (this was we know what we used to generate the video)\n",
" json_filename = \"text-to-video-prompt.json\"\n",
" with open(json_filename, \"w\") as f:\n",
" f.write(json.dumps(rest_api_parameters))\n",
"\n",
" # get the random number directory from text-to-video\n",
" text_to_video_output_directory = filename.replace(full_output_gcs_path,\"\")\n",
" text_to_video_output_directory = text_to_video_output_directory.split(\"/\")[1]\n",
" text_to_video_output_directory\n",
"\n",
" # Write the prompt to the same path as our outputted video. Saving the prompt allow us to know how to regenerate it (you should also save the seed and any other settings)\n",
" copy_file_to_gcs(json_filename, storage_account, f\"{output_gcs_path}/{text_to_video_output_directory}/{json_filename}\")\n",
" delete_file(json_filename)\n",
"\n",
" return filename"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "EnVQkN2vvk0O"
},
"source": [
"#### Gemini"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "MOrah-bpvlhN"
},
"outputs": [],
"source": [
"def GeminiLLM(prompt, model = \"gemini-2.0-flash\", response_schema = None,\n",
" temperature = 1, topP = 1, topK = 32):\n",
"\n",
" # https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/inference#supported_models\n",
" # gemini-2.0-flash\n",
"\n",
" llm_response = None\n",
" if temperature < 0:\n",
" temperature = 0\n",
"\n",
" creds, project = google.auth.default()\n",
" auth_req = google.auth.transport.requests.Request() # required to acess access token\n",
" creds.refresh(auth_req)\n",
" access_token=creds.token\n",
"\n",
" headers = {\n",
" \"Content-Type\" : \"application/json\",\n",
" \"Authorization\" : \"Bearer \" + access_token\n",
" }\n",
"\n",
" # https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/inference\n",
" url = f\"https://{location}-aiplatform.googleapis.com/v1/projects/{project_id}/locations/{location}/publishers/google/models/{model}:generateContent\"\n",
"\n",
" generation_config = {\n",
" \"temperature\": temperature,\n",
" \"topP\": topP,\n",
" \"maxOutputTokens\": 8192,\n",
" \"candidateCount\": 1,\n",
" \"responseMimeType\": \"application/json\",\n",
" }\n",
"\n",
" # Add inthe response schema for when it is provided\n",
" if response_schema is not None:\n",
" generation_config[\"responseSchema\"] = response_schema\n",
"\n",
" if model == \"gemini-pro\" or model == \"gemini-1.0-pro\" or model == \"gemini-1.0-pro-vision-001\":\n",
" generation_config[\"topK\"] = topK\n",
"\n",
" payload = {\n",
" \"contents\": {\n",
" \"role\": \"user\",\n",
" \"parts\": {\n",
" \"text\": prompt\n",
" },\n",
" },\n",
" \"generation_config\": {\n",
" **generation_config\n",
" },\n",
" \"safety_settings\": {\n",
" \"category\": \"HARM_CATEGORY_SEXUALLY_EXPLICIT\",\n",
" \"threshold\": \"BLOCK_LOW_AND_ABOVE\"\n",
" }\n",
" }\n",
"\n",
" response = requests.post(url, json=payload, headers=headers)\n",
"\n",
" if response.status_code == 200:\n",
" try:\n",
" json_response = json.loads(response.content)\n",
" except Exception as error:\n",
" raise RuntimeError(f\"An error occurred parsing the JSON: {error}\")\n",
"\n",
" if \"candidates\" in json_response:\n",
" candidates = json_response[\"candidates\"]\n",
" if len(candidates) > 0:\n",
" candidate = candidates[0]\n",
" if \"content\" in candidate:\n",
" content = candidate[\"content\"]\n",
" if \"parts\" in content:\n",
" parts = content[\"parts\"]\n",
" if len(parts):\n",
" part = parts[0]\n",
" if \"text\" in part:\n",
" text = part[\"text\"]\n",
" llm_response = text\n",
" else:\n",
" raise RuntimeError(\"No text in part: {response.content}\")\n",
" else:\n",
" raise RuntimeError(\"No parts in content: {response.content}\")\n",
" else:\n",
" raise RuntimeError(\"No parts in content: {response.content}\")\n",
" else:\n",
" raise RuntimeError(\"No content in candidate: {response.content}\")\n",
" else:\n",
" raise RuntimeError(\"No candidates: {response.content}\")\n",
" else:\n",
" raise RuntimeError(\"No candidates: {response.content}\")\n",
"\n",
" # Remove some typically response characters (if asking for a JSON reply)\n",
" llm_response = llm_response.replace(\"```json\",\"\")\n",
" llm_response = llm_response.replace(\"```\",\"\")\n",
" llm_response = llm_response.replace(\"\\n\",\"\")\n",
"\n",
" return llm_response\n",
"\n",
" else:\n",
" raise RuntimeError(f\"Error with prompt:'{prompt}' Status:'{response.status_code}' Text:'{response.text}'\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "2m3dFlQNu9se"
},
"source": [
"#### GCS file helpers"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "m5dOgbfVoZRV"
},
"outputs": [],
"source": [
"# This was generated by GenAI\n",
"\n",
"def copy_file_to_gcs(local_file_path, bucket_name, destination_blob_name):\n",
" \"\"\"Copies a file from a local drive to a GCS bucket.\n",
"\n",
" Args:\n",
" local_file_path: The full path to the local file.\n",
" bucket_name: The name of the GCS bucket to upload to.\n",
" destination_blob_name: The desired name of the uploaded file in the bucket.\n",
"\n",
" Returns:\n",
" None\n",
" \"\"\"\n",
"\n",
" import os\n",
" from google.cloud import storage\n",
"\n",
" # Ensure the file exists locally\n",
" if not os.path.exists(local_file_path):\n",
" raise FileNotFoundError(f\"Local file '{local_file_path}' not found.\")\n",
"\n",
" # Create a storage client\n",
" storage_client = storage.Client()\n",
"\n",
" # Get a reference to the bucket\n",
" bucket = storage_client.bucket(bucket_name)\n",
"\n",
" # Create a blob object with the desired destination path\n",
" blob = bucket.blob(destination_blob_name)\n",
"\n",
" # Upload the file from the local filesystem\n",
" content_type = \"\"\n",
" if local_file_path.endswith(\".html\"):\n",
" content_type = \"text/html; charset=utf-8\"\n",
"\n",
" if local_file_path.endswith(\".json\"):\n",
" content_type = \"application/json; charset=utf-8\"\n",
"\n",
" if content_type == \"\":\n",
" blob.upload_from_filename(local_file_path)\n",
" else:\n",
" blob.upload_from_filename(local_file_path, content_type = content_type)\n",
"\n",
" print(f\"File '{local_file_path}' uploaded to GCS bucket '{bucket_name}' as '{destination_blob_name}. Content-Type: {content_type}'.\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "xAQiEhyVz69j"
},
"outputs": [],
"source": [
"def download_from_gcs(destination_file_name, gcs_storage_bucket, object_name):\n",
" # prompt: Write python code to download a blob from a gcs bucket. do not use the requests method\n",
"\n",
" from google.cloud import storage\n",
" storage_client = storage.Client()\n",
" bucket = storage_client.bucket(gcs_storage_bucket)\n",
"\n",
" # Construct a client side representation of a blob.\n",
" # Note `Bucket.blob` differs from `Bucket.get_blob` as it doesn't retrieve\n",
" # any content from Google Cloud Storage. As we don't need additional data,\n",
" # using `Bucket.blob` is preferred here.\n",
" blob = bucket.blob(object_name)\n",
" blob.download_to_filename(destination_file_name)\n",
"\n",
" print(\n",
" \"Downloaded storage object {} from bucket {} to local file {}.\".format(\n",
" object_name, gcs_storage_bucket, destination_file_name\n",
" )\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "kYXFK_wooaC1"
},
"outputs": [],
"source": [
"# prompt: python to delete a file even if it does not exist\n",
"\n",
"def delete_file(filename):\n",
" try:\n",
" os.remove(filename)\n",
" print(f\"File '{filename}' deleted successfully.\")\n",
" except FileNotFoundError:\n",
" print(f\"File '{filename}' not found.\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "DdDBoe3YwDm1"
},
"source": [
"### <font color='#4285f4'>Teach the LLM how to write text-to-video prompts</font>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "MliX_6DEwEMN"
},
"outputs": [],
"source": [
"# We need to tell the LLM how to write text-to-video prompts\n",
"\n",
"text_to_video_prompt_guide = \"\"\"\n",
"Text-to-Video Prompt Writing Help:\n",
"<text-to-video-prompt-guide>\n",
"Here are some our best practices for text-to-video prompts:\n",
"\n",
"Detailed prompts = better videos:\n",
" - More details you add, the more control you’ll have over the video.\n",
" - A prompt should look like this: \"Camera dollies to show a close up of a desperate man in a green trench coat is making a call on a rotary style wall-phone, green neon light, movie scene.\"\n",
" - Here is a break down of elements need to create a text-to-video prompt using the above prompt as an example:\n",
" - \"Camera dollies to show\" = \"Camera Motion\"\n",
" - \"A close up of\" = \"Composition\"\n",
" - \"A desperate man in a green trench coat\" = \"Subject\"\n",
" - \"Is making a call\" = \"Action\"\n",
" - \"On a roary style wall-phone\" = \"Scene\"\n",
" - \"Green Neon light\" = \"Ambiance\"\n",
" - \"Movie Scene\" = \"Style\"\n",
"\n",
"Use the right keywords for better control:\n",
" - Here is a list of some keywords that work well with text-to-video, use these in your prompts to get the desired camera motion or style.\n",
" - Subject: Who or what is the main focus of the shot. Example: \"happy woman in her 30s\".\n",
" - Scene: Where is the location of the shot. Example \"on a busy street, in space\".\n",
" - Action: What is the subject doing Examples: \"walking\", \"running\", \"turning head\".\n",
" - Camera Motion: What the camera is doing. Example: \"POV shot\", \"Aerial View\", \"Tracking Drone view\", \"Tracking Shot\".\n",
"\n",
"Example text-to-video prompt using the above keywords:\n",
" - Example text-to-video prompt: \"Tracking drone view of a man driving a red convertible car in Palm Springs, 1970s, warm sunlight, long shadows\"\n",
" - Example text-to-video prompt: \"A POV shot from a vintage car driving in the rain, Canada at night, cinematic\"\n",
"\n",
"Styles:\n",
" - Overall aesthetic. Consider using specific film style keywords. Examples: \"horror film\", \"film noir, \"animated styles\", \"3D cartoon style render\".\n",
" - Example text-to-video prompt: \"Over the shoulder of a young woman in a car, 1970s, film grain, horror film, cinematic he Film noir style, man and woman walk on the street, mystery, cinematic, black and white\"\n",
" - Example text-to-video prompt: \"A cute creatures with snow leopard-like fur is walking in winter forest, 3D cartoon style render. An architectural rendering of a white concrete apartment building with flowing organic shapes, seamlessly blending with lush greenery and futuristic elements.\"\n",
"\n",
"Composition:\n",
" - How the shot is framed. This is often relative to the subject e.g. wide shot, close-up, low angle\n",
" - Example text-to-video prompt: \"Extreme close-up of a an eye with city reflected in it. A wide shot of surfer walking on a beach with a surfboard, beautiful sunset, cinematic\"\n",
"\n",
"Ambiance & Emotions:\n",
" - How the color and light contribute to the scene (blue tones, night)\n",
" - Example text-to-video prompt: \"A close-up of a girl holding adorable golden retriever puppy in the park, sunlight Cinematic close-up shot of a sad woman riding a bus in the rain, cool blue tones, sad mood\"\n",
"\n",
"Cinematic effects:\n",
" - e.g. double exposure, projected, glitch camera effect.\n",
" - Example text-to-video prompt: \"A double exposure of silhouetted profile of a woman walking and lake, walking in a forest Close-up shot of a model with blue light with geometric shapes projected on her face\"\n",
" - Example text-to-video prompt: \"Silhouette of a man walking in collage of cityscapes Glitch camera effect, close up of woman’s face speaking, neon colors\"\n",
"</text-to-video-prompt-guide>\n",
"\"\"\""
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "yoQnskrhvQhS"
},
"source": [
"### <font color='#4285f4'>Text-to-Video Example</font>\n",
"- Provide a basic text-to-video prompt\n",
"- Use Gemini to rewrite the text-to-video prompt incorporating best pratices\n",
"- Provide Gemini with instructions for text-to-video\n",
"- Call Gemini\n",
"- Run the enhanced prompt"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "6PT3GN91wMhc"
},
"outputs": [],
"source": [
"# Write me the json in OpenAPI 3.0 schema object for the below object.\n",
"# Make all fields required.\n",
"# {\n",
"# \"text-to-video-prompt\" : \"text\"\n",
"# }\n",
"response_schema = {\n",
" \"type\": \"object\",\n",
" \"required\": [\n",
" \"text-to-video-prompt\"\n",
" ],\n",
" \"properties\": {\n",
" \"text-to-video-prompt\": {\n",
" \"type\": \"string\"\n",
" }\n",
" }\n",
"}\n",
"\n",
"# ---> Enter your original prompt here <---\n",
"original_prompt = \"a cat watching tv\"\n",
"\n",
"gemini_prompt = f\"\"\"Rewrite the following \"original prompt\" using the text-to-video instructions below.\n",
"You want the video to be creative and artistic..\n",
"\n",
"Original Prompt:\n",
"\"{original_prompt}\"\n",
"\n",
"Output Fields:\n",
"- \"text-to-video-prompt\":\n",
"\n",
"Instructions:\n",
" - Read the \"Text-to-Video Prompt Writing Help\" to learn more about how to create good text-to-video prompts.\n",
" - Make sure you include all the relevant best practices when creating the text-to-video prompt.\n",
" - Do not include \"text overlays\" in the text-to-video prompt.\n",
" - Do not include children in the text-to-video prompt.\n",
"\n",
"{text_to_video_prompt_guide}\n",
"\"\"\"\n",
"\n",
"print(gemini_prompt)\n",
"llm_result = GeminiLLM(gemini_prompt, response_schema=response_schema)\n",
"gemini_results_dict = json.loads(llm_result)\n",
"\n",
"print()\n",
"print(json.dumps(gemini_results_dict))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "NEmYsXaWe6C6"
},
"outputs": [],
"source": [
"# Text-to-Video Parameters\n",
"# prompt = \"A customer smiles while taking a bite of an exquisite dessert, eyes closed in pure enjoyment, soft focus background, warm lighting\" # hardcoded example\n",
"prompt = gemini_results_dict[\"text-to-video-prompt\"]\n",
"output_gcs_path = f\"text-to-video/text-to-video-{formatted_date}\"\n",
"\n",
"# Generate the video and wait for it to complete. The prompt / text-to-video parameters will be saved in the same storage location as the video.\n",
"filename = generateVideo(prompt, storage_account, output_gcs_path)\n",
"print(f\"filename: {filename}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "WCYyB4rMztm3"
},
"outputs": [],
"source": [
"# download the video and play it\n",
"download_from_gcs(\"text-to-video.mp4\", storage_account, filename.replace(f\"gs://{storage_account}/\",\"\"))\n",
"\n",
"video_mp4 = open(\"text-to-video.mp4\", 'rb').read()\n",
"video_url = \"data:video/mp4;base64,\" + base64.b64encode(video_mp4).decode()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Qq99CRwAzs5C"
},
"outputs": [],
"source": [
"# 16:9 aspect ratio\n",
"HTML(f\"\"\"\n",
"<p>Text-to-Video (no audio)</p>\n",
"<video width=600 height=337 controls>\n",
" <source src=\"{video_url}\" type=\"video/mp4\">\n",
"</video>\n",
"\"\"\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "lti0dSb_vUos"
},
"source": [
"### <font color='#4285f4'>Clean Up</font>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "mG4TC-CQvXou"
},
"outputs": [],
"source": [
"# Placeholder"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "FnWaNjILvUGT"
},
"source": [
"### <font color='#4285f4'>Reference Links</font>\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Ds3Z_NLIvad-"
},
"source": [
"- [Google.com](https://www.google.com)"
]
}
],
"metadata": {
"colab": {
"collapsed_sections": [
"RqoS4ZK8unQP",
"5R9CS3wkuqhU",
"s5rcnCWFuvIv"
],
"private_outputs": true,
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 0
}