Created
August 29, 2025 15:07
-
-
Save eumel8/5478dbac2ad8fc192c707e4325a0b037 to your computer and use it in GitHub Desktop.
Google Cloud VEO Text-2-Video Generator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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