Skip to content

Instantly share code, notes, and snippets.

@eumel8
Created August 29, 2025 15:07
Show Gist options
  • Select an option

  • Save eumel8/5478dbac2ad8fc192c707e4325a0b037 to your computer and use it in GitHub Desktop.

Select an option

Save eumel8/5478dbac2ad8fc192c707e4325a0b037 to your computer and use it in GitHub Desktop.
Google Cloud VEO Text-2-Video Generator
#!/bin/bash
# Was brauch man hier:
# * Google Cloud Account https://console.cloud.google.com/
# * Goofle Projekt mit aktivem Rechnungskonto
# * AKtoierte Vertex AI API https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/veo-video-generation?hl=de#rest-ttv
set -e
PROJECT_ID=""
LOCATION_ID="us-central1"
API_ENDPOINT="us-central1-aiplatform.googleapis.com"
MODEL_ID="veo-3.0-generate-001"
OUTPUT_DIR="./videos"
check_curl() {
if ! command -v curl &> /dev/null; then
echo "curl ist nicht installiert. Installiere curl..."
sudo apt install curl
fi
echo "curl gefunden."
}
check_jq() {
if ! command -v jq &> /dev/null; then
echo "jq ist nicht installiert. Installiere jq..."
sudo apt install jq
fi
echo "jq gefunden."
}
check_gcloud() {
if ! command -v gcloud &> /dev/null; then
echo "gcloud CLI ist nicht installiert. Installiere gcloud..."
if command -v snap &> /dev/null; then
sudo snap install google-cloud-cli --classic
else
curl https://sdk.cloud.google.com | bash
exec -l $SHELL
source ~/.bashrc
fi
fi
echo "gcloud CLI gefunden."
}
check_auth() {
if ! gcloud auth list --filter=status:ACTIVE --format="value(account)" | head -n 1 > /dev/null 2>&1; then
echo "Nicht bei Google Cloud eingeloggt. Starte Authentifizierung..."
gcloud auth login
gcloud auth application-default login
fi
echo "Google Cloud Authentifizierung erfolgreich."
}
set_project() {
if [ -z "$PROJECT_ID" ]; then
read -p "Geben Sie Ihre Google Cloud Project ID ein: " PROJECT_ID
if [ -z "$PROJECT_ID" ]; then
echo "Fehler: Project ID darf nicht leer sein."
exit 1
fi
gcloud config set project "$PROJECT_ID"
fi
}
get_prompt() {
read -p "Geben Sie Ihren Text-Prompt für die Video-Generierung ein: " VIDEO_PROMPT
if [ -z "$VIDEO_PROMPT" ]; then
echo "Fehler: Prompt darf nicht leer sein."
exit 1
fi
}
create_request_json() {
cat << EOF > request.json
{
"instances": [
{
"prompt": "$VIDEO_PROMPT"
}
],
"parameters": {
"aspectRatio": "16:9",
"sampleCount": 1,
"durationSeconds": "8",
"personGeneration": "allow_all",
"addWatermark": true,
"includeRaiReason": true,
"generateAudio": true,
"resolution": "720p"
}
}
EOF
}
submit_generation() {
echo "Sende Video-Generierungsanfrage..."
create_request_json
RESPONSE=$(curl -s \
-X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://${API_ENDPOINT}/v1/projects/${PROJECT_ID}/locations/${LOCATION_ID}/publishers/google/models/${MODEL_ID}:predictLongRunning" \
-d '@request.json')
OPERATION_NAME=$(echo "$RESPONSE" | jq -r '.name // empty')
OPERATION_ID=$(echo "$OPERATION_NAME" | sed 's/.*operations\///g')
if [ -z "$OPERATION_ID" ] || [ "$OPERATION_ID" = "null" ]; then
echo "Fehler: Konnte Operation ID nicht extrahieren."
echo "Response: $RESPONSE"
exit 1
fi
echo "Operation gestartet mit ID: $OPERATION_ID"
rm -f request.json
}
poll_status() {
echo "Warte auf Fertigstellung der Video-Generierung..."
while true; do
# Create status check request JSON
cat << EOF > status_request.json
{
"operationName": "${OPERATION_NAME}"
}
EOF
STATUS_RESPONSE=$(curl -s \
-X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
"https://${API_ENDPOINT}/v1/projects/${PROJECT_ID}/locations/${LOCATION_ID}/publishers/google/models/${MODEL_ID}:fetchPredictOperation" \
-d '@status_request.json')
# Debug: Zeige die aktuelle Response
#echo "DEBUG: Status Response:"
#echo $STATUS_RESPONSE
#echo "$STATUS_RESPONSE" | jq '.'
STATUS=$(echo "$STATUS_RESPONSE" | jq -r '.done // false')
METADATA=$(echo "$STATUS_RESPONSE" | jq -r '.metadata // empty')
#echo "DEBUG: Done status: $STATUS"
#echo "DEBUG: Metadata: $METADATA"
if [ "$STATUS" = "true" ]; then
ERROR=$(echo "$STATUS_RESPONSE" | jq -r '.error // empty')
if [ -n "$ERROR" ] && [ "$ERROR" != "null" ]; then
echo "Fehler bei der Video-Generierung:"
echo "$ERROR"
exit 1
fi
# Erweiterte Pfade für Video-Daten prüfen
VIDEO_BASE64=$(echo "$STATUS_RESPONSE" | jq -r '.response.predictions[0].bytesBase64Encoded // .response.videos[0].bytesBase64Encoded // empty')
if [ -z "$VIDEO_BASE64" ] || [ "$VIDEO_BASE64" = "null" ]; then
echo "Fehler: Video-Daten nicht in der Antwort gefunden."
echo "Verfügbare Response-Struktur:"
echo "$STATUS_RESPONSE" | jq 'keys'
echo "Response: $STATUS_RESPONSE"
exit 1
fi
echo "Video erfolgreich generiert!"
break
fi
echo "Status: In Bearbeitung... (warte 30 Sekunden)"
sleep 30
done
}
download_video() {
mkdir -p "$OUTPUT_DIR"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
OUTPUT_FILE="$OUTPUT_DIR/veo_video_$TIMESTAMP.mp4"
echo "Speichere Video als: $OUTPUT_FILE"
echo "$VIDEO_BASE64" | base64 -d > "$OUTPUT_FILE"
echo "Video erfolgreich gespeichert: $OUTPUT_FILE"
}
cleanup() {
rm -f request.json fetch.json status_request.json
}
main() {
echo "=== Google Cloud VEO Text-2-Video Generator ==="
trap cleanup EXIT
check_curl
check_jq
check_gcloud
check_auth
set_project
get_prompt
submit_generation
poll_status
download_video
echo "=== Fertig! ==="
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment