Update
This commit is contained in:
87
bash/convert_webm_to_prores4444.sh
Executable file
87
bash/convert_webm_to_prores4444.sh
Executable file
@@ -0,0 +1,87 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script to convert all WebM files with alpha to ProRes 4444 MOV files
|
||||
# Overwrites existing MOV files by default
|
||||
|
||||
# Check if directory parameter is provided
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "Usage: sh convert_webm_to_mov.sh <absolute_path_to_directory>"
|
||||
echo "Example: sh convert_webm_to_mov.sh /Users/charlesteh/Desktop/mag-group-1/"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get the target directory from parameter
|
||||
target_dir="$1"
|
||||
|
||||
# Check if directory exists
|
||||
if [ ! -d "$target_dir" ]; then
|
||||
echo "Error: Directory '$target_dir' does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Converting all WebM files in '$target_dir' to ProRes 4444 MOV..."
|
||||
|
||||
# Check if ffmpeg is installed
|
||||
if ! command -v ffmpeg &> /dev/null; then
|
||||
echo "Error: ffmpeg is not installed or not in PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Change to target directory
|
||||
cd "$target_dir" || {
|
||||
echo "Error: Cannot access directory '$target_dir'"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Count total WebM files
|
||||
webm_count=$(ls *.webm 2>/dev/null | wc -l)
|
||||
|
||||
if [ $webm_count -eq 0 ]; then
|
||||
echo "No WebM files found in current directory"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Found $webm_count WebM file(s) to convert"
|
||||
|
||||
# Counter for progress
|
||||
count=0
|
||||
|
||||
# Loop through all WebM files in current directory
|
||||
for webm_file in *.webm; do
|
||||
# Check if file actually exists (in case glob doesn't match)
|
||||
if [ ! -f "$webm_file" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Increment counter
|
||||
count=$((count + 1))
|
||||
|
||||
# Get filename without extension
|
||||
base_name=$(basename "$webm_file" .webm)
|
||||
|
||||
# Output MOV filename
|
||||
mov_file="${base_name}.mov"
|
||||
|
||||
echo "[$count/$webm_count] Converting: $webm_file -> $mov_file"
|
||||
|
||||
# Convert with ffmpeg
|
||||
# -y: overwrite output files without asking
|
||||
# -vcodec libvpx-vp9: Force libvpx decoder (native VP9 decoder doesn't handle alpha)
|
||||
# -i: input file
|
||||
# -c:v prores_ks: ProRes encoder (much better compression than qtrle)
|
||||
# -profile:v 4444: ProRes 4444 profile (supports alpha)
|
||||
# -pix_fmt yuva444p10le: Pixel format with alpha channel support
|
||||
# -c:a aac: convert audio to AAC (MOV compatible, since Opus isn't supported in MOV)
|
||||
ffmpeg -y -vcodec libvpx-vp9 -i "$webm_file" -c:v prores_ks -profile:v 4444 -pix_fmt yuva444p10le -c:a aac "$mov_file"
|
||||
|
||||
# Check if conversion was successful
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✓ Successfully converted: $mov_file"
|
||||
else
|
||||
echo "✗ Failed to convert: $webm_file"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
done
|
||||
|
||||
echo "Conversion complete! Processed $count file(s)."
|
||||
62
bash/test.sh
Executable file
62
bash/test.sh
Executable file
@@ -0,0 +1,62 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Debug script to test HEVC alpha conversion step by step
|
||||
# Usage: ./test_hevc.sh input.webm
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "Usage: $0 input.webm"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
INPUT="$1"
|
||||
BASE=$(basename "$INPUT" .webm)
|
||||
|
||||
echo "=== Testing HEVC Alpha Conversion ==="
|
||||
echo "Input: $INPUT"
|
||||
echo ""
|
||||
|
||||
# Test 1: Basic HEVC (your original command format)
|
||||
echo "Test 1: Basic HEVC with alpha..."
|
||||
ffmpeg -y -c:v libvpx-vp9 -i "$INPUT" -c:v hevc_videotoolbox -q:v 60 -allow_sw 1 -alpha_quality 0.7 -vtag hvc1 -movflags +faststart "${BASE}_test1.mp4"
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✓ Test 1 successful"
|
||||
ls -lh "${BASE}_test1.mp4"
|
||||
else
|
||||
echo "✗ Test 1 failed"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Test 2: Simplified approach (no audio)
|
||||
echo "Test 2: HEVC without audio..."
|
||||
ffmpeg -y -c:v libvpx-vp9 -i "$INPUT" -c:v hevc_videotoolbox -q:v 60 -allow_sw 1 -alpha_quality 0.7 -vtag hvc1 -an "${BASE}_test2.mp4"
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✓ Test 2 successful"
|
||||
ls -lh "${BASE}_test2.mp4"
|
||||
else
|
||||
echo "✗ Test 2 failed"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Test 3: MOV container instead of MP4
|
||||
echo "Test 3: HEVC with MOV container..."
|
||||
ffmpeg -y -c:v libvpx-vp9 -i "$INPUT" -c:v hevc_videotoolbox -q:v 60 -allow_sw 1 -alpha_quality 0.7 -vtag hvc1 "${BASE}_test3.mov"
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✓ Test 3 successful"
|
||||
ls -lh "${BASE}_test3.mov"
|
||||
else
|
||||
echo "✗ Test 3 failed"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Test 4: Check if any files actually have alpha
|
||||
echo "=== Checking results with ffprobe ==="
|
||||
for file in "${BASE}_test"*.{mp4,mov}; do
|
||||
if [ -f "$file" ]; then
|
||||
echo "--- $file ---"
|
||||
ffprobe -v quiet -select_streams v:0 -show_entries stream=codec_name,pix_fmt -of csv=p=0 "$file"
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "=== Manual Test ==="
|
||||
echo "Try opening the test files in Safari/QuickTime to check for transparency"
|
||||
165
bash/test_prores_to_hevc.sh
Executable file
165
bash/test_prores_to_hevc.sh
Executable file
@@ -0,0 +1,165 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Fixed script to convert ProRes 4444 alpha to HEVC alpha
|
||||
# Usage: ./test_prores_to_hevc.sh input.mov
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "Usage: $0 input_prores4444.mov"
|
||||
echo "Example: ./test_prores_to_hevc.sh animation.mov"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
prores_file="$1"
|
||||
|
||||
# Check if input file exists
|
||||
if [ ! -f "$prores_file" ]; then
|
||||
echo "Error: File '$prores_file' not found."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Generate output filename
|
||||
base_name=$(basename "$prores_file" .mov)
|
||||
hevc_output="${base_name}_hevc.mov"
|
||||
|
||||
echo "=== Testing ProRes 4444 to HEVC Alpha Conversion ==="
|
||||
echo "Input ProRes: $prores_file"
|
||||
echo "Output HEVC: $hevc_output"
|
||||
echo ""
|
||||
|
||||
# Check input file properties
|
||||
echo "=== Input File Analysis ==="
|
||||
echo "ProRes file properties:"
|
||||
ffprobe -v quiet -select_streams v:0 -show_entries stream=codec_name,pix_fmt,width,height,bit_rate -of csv=p=0 "$prores_file"
|
||||
echo ""
|
||||
|
||||
# Check if input has alpha channel (HEVC embeds alpha natively)
|
||||
has_alpha=$(ffprobe -v quiet -select_streams v:0 -show_entries stream=pix_fmt -of csv=p=0 "$prores_file" | grep -E "(yuva|rgba|argb|bgra|abgr)")
|
||||
if [ -z "$has_alpha" ]; then
|
||||
echo "Note: Input shows standard pixel format (HEVC will embed alpha natively if present)"
|
||||
fi
|
||||
|
||||
# Show input file size
|
||||
input_size=$(stat -f%z "$prores_file" 2>/dev/null || stat -c%s "$prores_file" 2>/dev/null)
|
||||
echo "Input file size: $(awk "BEGIN {printf \"%.1f\", $input_size/1024/1024}")MB"
|
||||
echo ""
|
||||
|
||||
# Test if VideoToolbox supports HEVC on this system
|
||||
echo "=== Testing VideoToolbox HEVC Support ==="
|
||||
vt_test=$(ffmpeg -f lavfi -i "color=red:size=100x100:duration=1" -c:v hevc_videotoolbox -f null - 2>&1)
|
||||
if echo "$vt_test" | grep -q "not supported\|failed\|error"; then
|
||||
echo "VideoToolbox doesn't support HEVC on this system, falling back to software encoder"
|
||||
use_software=true
|
||||
else
|
||||
echo "VideoToolbox HEVC support detected"
|
||||
use_software=false
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Convert ProRes 4444 to HEVC Alpha with improved settings
|
||||
echo "=== Converting ProRes 4444 to HEVC Alpha ==="
|
||||
|
||||
if [ "$use_software" = true ]; then
|
||||
# Software encoder fallback matching Apple's settings
|
||||
echo "Using software HEVC encoder (libx265)..."
|
||||
cmd="ffmpeg -y -i \"$prores_file\" -map 0:a -map 0:v -c:a aac -b:a 129k -c:v libx265 -b:v 4885k -preset medium -colorspace bt709 -color_primaries bt709 -color_trc bt709 -movflags +faststart \"$hevc_output\""
|
||||
echo "Command: $cmd"
|
||||
echo ""
|
||||
|
||||
ffmpeg -y -i "$prores_file" \
|
||||
-map 0:a -map 0:v \
|
||||
-c:a aac -b:a 129k \
|
||||
-c:v libx265 \
|
||||
-b:v 4885k \
|
||||
-preset medium \
|
||||
-colorspace bt709 \
|
||||
-color_primaries bt709 \
|
||||
-color_trc bt709 \
|
||||
-movflags +faststart \
|
||||
"$hevc_output"
|
||||
else
|
||||
# VideoToolbox matching Apple's exact Encode Media output
|
||||
echo "Using VideoToolbox HEVC encoder (matching Apple's exact Encode Media)..."
|
||||
cmd="ffmpeg -y -i \"$prores_file\" -map 0:a -map 0:v -c:a aac -b:a 129k -c:v hevc_videotoolbox -b:v 4885k -colorspace bt709 -color_primaries bt709 -color_trc bt709 -vtag hvc1 -movflags +faststart \"$hevc_output\""
|
||||
echo "Command: $cmd"
|
||||
echo ""
|
||||
|
||||
ffmpeg -y -i "$prores_file" \
|
||||
-c:v hevc_videotoolbox \
|
||||
-pix_fmt bgra \
|
||||
-alpha_quality 1 \
|
||||
-tag:v hvc1 \
|
||||
"$hevc_output"
|
||||
fi
|
||||
|
||||
if [ $? -eq 0 ] && [ -f "$hevc_output" ]; then
|
||||
echo ""
|
||||
echo "✓ SUCCESS: HEVC conversion complete!"
|
||||
ls -lh "$hevc_output"
|
||||
|
||||
# Verify the output file isn't corrupted
|
||||
echo ""
|
||||
echo "=== Verifying Output File Integrity ==="
|
||||
verify_result=$(ffprobe -v error -select_streams v:0 -count_frames -show_entries stream=nb_frames -of csv=p=0 "$hevc_output" 2>&1)
|
||||
if echo "$verify_result" | grep -q "error\|corrupt\|invalid"; then
|
||||
echo "✗ WARNING: Output file may be corrupted"
|
||||
echo "Verification result: $verify_result"
|
||||
else
|
||||
echo "✓ Output file integrity verified"
|
||||
echo "Frame count: $verify_result"
|
||||
fi
|
||||
|
||||
# Show file size comparison
|
||||
output_size=$(stat -f%z "$hevc_output" 2>/dev/null || stat -c%s "$hevc_output" 2>/dev/null)
|
||||
if [ ! -z "$input_size" ] && [ ! -z "$output_size" ]; then
|
||||
ratio=$(awk "BEGIN {printf \"%.1f\", $output_size/$input_size}")
|
||||
compression=$(awk "BEGIN {printf \"%.1f\", $input_size/$output_size}")
|
||||
echo ""
|
||||
echo "=== File Size Comparison ==="
|
||||
echo "ProRes 4444: $(awk "BEGIN {printf \"%.1f\", $input_size/1024/1024}")MB"
|
||||
echo "HEVC Alpha: $(awk "BEGIN {printf \"%.1f\", $output_size/1024/1024}")MB"
|
||||
echo "Size ratio: ${ratio}x (${compression}x compression)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Output File Analysis ==="
|
||||
echo "HEVC file properties:"
|
||||
ffprobe -v quiet -select_streams v:0 -show_entries stream=codec_name,pix_fmt,width,height,bit_rate -of csv=p=0 "$hevc_output"
|
||||
|
||||
# HEVC embeds alpha natively - visual verification required
|
||||
echo "✓ HEVC file created (alpha embedded natively - verify visually)"
|
||||
|
||||
echo ""
|
||||
echo "✓ TEST COMPLETE: $hevc_output created successfully!"
|
||||
echo "✓ Open the file in Safari or QuickTime to verify alpha transparency works!"
|
||||
|
||||
else
|
||||
echo ""
|
||||
echo "✗ FAILED: HEVC conversion failed"
|
||||
|
||||
# Try alternative approach if VideoToolbox failed
|
||||
if [ "$use_software" = false ]; then
|
||||
echo ""
|
||||
echo "Trying software encoder as fallback..."
|
||||
|
||||
ffmpeg -y -i "$prores_file" \
|
||||
-map 0:a -map 0:v \
|
||||
-c:a aac -b:a 129k \
|
||||
-c:v libx265 \
|
||||
-b:v 4885k \
|
||||
-preset medium \
|
||||
-colorspace bt709 \
|
||||
-color_primaries bt709 \
|
||||
-color_trc bt709 \
|
||||
-movflags +faststart \
|
||||
"${base_name}_hevc_sw.mov"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✓ SUCCESS with software encoder: ${base_name}_hevc_sw.mov"
|
||||
else
|
||||
echo "✗ Both hardware and software encoders failed"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
280
bash/webm_metadata.sh
Executable file
280
bash/webm_metadata.sh
Executable file
@@ -0,0 +1,280 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script to process .webm files and generate metadata using OpenAI API
|
||||
# Requires: dotenv-cli, jq
|
||||
# Usage: ./webm_metadata.sh [directory_path]
|
||||
|
||||
set -e # Exit on any error
|
||||
|
||||
# Get the directory where the script is located
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Get target directory (default to current directory)
|
||||
TARGET_DIR="${1:-.}"
|
||||
TARGET_DIR="$(cd "$TARGET_DIR" && pwd)" # Convert to absolute path
|
||||
|
||||
# Check dependencies
|
||||
command -v dotenv >/dev/null 2>&1 || { echo "Error: dotenv-cli is required. Install with: npm install -g dotenv-cli" >&2; exit 1; }
|
||||
command -v jq >/dev/null 2>&1 || { echo "Error: jq is required. Install with: apt-get install jq or brew install jq" >&2; exit 1; }
|
||||
|
||||
# Check if .env exists in script directory
|
||||
ENV_FILE="$SCRIPT_DIR/.env"
|
||||
if [ ! -f "$ENV_FILE" ]; then
|
||||
echo "Error: .env file not found at $ENV_FILE"
|
||||
echo "Please create one with OPENAI_API_KEY=your_key"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Script directory: $SCRIPT_DIR"
|
||||
echo "Target directory: $TARGET_DIR"
|
||||
echo "Looking for .env at: $ENV_FILE"
|
||||
echo ""
|
||||
|
||||
# Configuration
|
||||
CSV_FILE="$TARGET_DIR/webm_metadata.csv"
|
||||
DELAY_SECONDS=1
|
||||
|
||||
# Function to check if filename already processed
|
||||
is_processed() {
|
||||
local filename="$1"
|
||||
grep -q "^\"$filename\"," "$CSV_FILE" 2>/dev/null
|
||||
}
|
||||
|
||||
# Function to escape CSV field
|
||||
escape_csv() {
|
||||
local field="$1"
|
||||
# Escape double quotes and wrap in quotes
|
||||
echo "\"$(echo "$field" | sed 's/"/\"\"/g')\""
|
||||
}
|
||||
|
||||
# Function to make API call and extract metadata
|
||||
process_file() {
|
||||
local filename="$1"
|
||||
echo "Processing: $filename"
|
||||
|
||||
# Create the system prompt text
|
||||
local system_prompt="You are an AI assistant that receives a meme filename. Based on the filename, your task is to generate detailed metadata describing the meme in a structured format.
|
||||
|
||||
The metadata should include these fields:
|
||||
- **type**: either \`video\` or \`image\` depending on the file extension.
|
||||
- **sub_type**: a classification such as \`background\` or \`overlay\` (choose \`overlay\` if it seems like an edit or reaction video/image).
|
||||
- **name**: a concise, title-cased name derived from the filename (remove file extension and normalize, without the Meme word if exist).
|
||||
- **description**: a short paragraph describing the meme content and context inferred from the name, and reaction
|
||||
- **keywords**: a comma-separated list of relevant keywords extracted from the filename or meme context.
|
||||
- **media_1_mime_type**: the MIME type derived from the file extension (e.g., \`video/webm\`, \`image/png\`).
|
||||
|
||||
Return the output as a JSON object containing these fields. Use null for any unknown or missing values.
|
||||
|
||||
---
|
||||
|
||||
#### Example input:
|
||||
\`7th element oiiaa cat.webm\`
|
||||
|
||||
#### Example output:
|
||||
\`\`\`json
|
||||
{
|
||||
\"type\": \"video\",
|
||||
\"sub_type\": \"overlay\",
|
||||
\"name\": \"7th Element Oiiaa Cat\",
|
||||
\"description\": \"a cat edited to mimic or react to Vitas' bizarre vocals from the viral \\\"7th Element\\\" performance.\",
|
||||
\"keywords\": \"cat, oiiaa, 7th element, vitas, webm, funny\",
|
||||
\"media_1_mime_type\": \"video/webm\"
|
||||
}
|
||||
\`\`\`"
|
||||
|
||||
local assistant_example="\`\`\`json
|
||||
{
|
||||
\"type\": \"video\",
|
||||
\"sub_type\": \"overlay\",
|
||||
\"name\": \"Angry Cat\",
|
||||
\"description\": \"A video meme featuring an angry-looking cat, typically used to express frustration, annoyance, or irritation in a humorous way.\",
|
||||
\"keywords\": \"angry, cat, reaction, meme, webm, annoyed, frustration\",
|
||||
\"media_1_mime_type\": \"video/webm\"
|
||||
}
|
||||
\`\`\`"
|
||||
|
||||
# Use jq to properly construct the JSON payload
|
||||
local json_payload=$(jq -n \
|
||||
--arg system_prompt "$system_prompt" \
|
||||
--arg filename "$filename" \
|
||||
--arg assistant_example "$assistant_example" \
|
||||
'{
|
||||
"model": "gpt-4.1-nano",
|
||||
"input": [
|
||||
{
|
||||
"role": "system",
|
||||
"content": [
|
||||
{
|
||||
"type": "input_text",
|
||||
"text": $system_prompt
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{
|
||||
"type": "input_text",
|
||||
"text": $filename
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": [
|
||||
{
|
||||
"type": "output_text",
|
||||
"text": $assistant_example
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"text": {
|
||||
"format": {
|
||||
"type": "json_object"
|
||||
}
|
||||
},
|
||||
"reasoning": {},
|
||||
"tools": [],
|
||||
"temperature": 1,
|
||||
"max_output_tokens": 2048,
|
||||
"top_p": 1,
|
||||
"store": true
|
||||
}')
|
||||
|
||||
# Make the API call
|
||||
local response=$(curl -s "https://api.openai.com/v1/responses" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer $OPENAI_API_KEY" \
|
||||
-d "$json_payload")
|
||||
|
||||
# Check for API errors
|
||||
if echo "$response" | jq -e '.error' >/dev/null 2>&1; then
|
||||
echo "API Error for $filename:"
|
||||
echo "$response" | jq '.error'
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Extract the response text from the correct path
|
||||
local response_text=$(echo "$response" | jq -r '.output[0].content[0].text // empty')
|
||||
|
||||
if [ -z "$response_text" ]; then
|
||||
echo "Error: Empty response for $filename"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# With JSON mode enabled, response should always be direct JSON
|
||||
local json_content="$response_text"
|
||||
|
||||
# Validate that it's valid JSON before parsing
|
||||
if ! echo "$json_content" | jq . >/dev/null 2>&1; then
|
||||
echo "Error: Invalid JSON response for $filename"
|
||||
echo "Content: $json_content"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Parse individual fields
|
||||
local type=$(echo "$json_content" | jq -r '.type // "unknown"')
|
||||
local sub_type=$(echo "$json_content" | jq -r '.sub_type // "unknown"')
|
||||
local name=$(echo "$json_content" | jq -r '.name // "unknown"')
|
||||
local description=$(echo "$json_content" | jq -r '.description // "unknown"')
|
||||
local keywords=$(echo "$json_content" | jq -r '.keywords // "unknown"')
|
||||
local media_1_mime_type=$(echo "$json_content" | jq -r '.media_1_mime_type // "unknown"')
|
||||
|
||||
# Write to CSV
|
||||
local csv_line="$(escape_csv "$filename"),$(escape_csv "$type"),$(escape_csv "$sub_type"),$(escape_csv "$name"),$(escape_csv "$description"),$(escape_csv "$keywords"),$(escape_csv "$media_1_mime_type")"
|
||||
echo "$csv_line" >> "$CSV_FILE"
|
||||
|
||||
echo "✓ Successfully processed: $filename"
|
||||
}
|
||||
|
||||
# Export functions so they're available in the dotenv subshell
|
||||
export -f is_processed
|
||||
export -f escape_csv
|
||||
export -f process_file
|
||||
export CSV_FILE
|
||||
export DELAY_SECONDS
|
||||
export TARGET_DIR
|
||||
|
||||
# Change to script directory so dotenv can find the .env file
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
# Use dotenv to run the main processing logic
|
||||
dotenv -- bash -c '
|
||||
# Check if OPENAI_API_KEY is loaded
|
||||
if [ -z "$OPENAI_API_KEY" ]; then
|
||||
echo "Error: OPENAI_API_KEY not found in environment variables"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✓ OpenAI API key loaded successfully"
|
||||
echo "CSV file will be: $CSV_FILE"
|
||||
echo "Delay between requests: ${DELAY_SECONDS}s"
|
||||
echo ""
|
||||
|
||||
# Create CSV with headers if it doesn'\''t exist
|
||||
if [ ! -f "$CSV_FILE" ]; then
|
||||
echo "filename,type,sub_type,name,description,keywords,media_1_mime_type" > "$CSV_FILE"
|
||||
echo "Created $CSV_FILE with headers"
|
||||
fi
|
||||
|
||||
echo "Starting processing of .webm files..."
|
||||
|
||||
# Count total files and processed files
|
||||
total_files=$(ls -1 "$TARGET_DIR"/*.webm 2>/dev/null | wc -l)
|
||||
processed_count=0
|
||||
skipped_count=0
|
||||
error_count=0
|
||||
|
||||
if [ "$total_files" -eq 0 ]; then
|
||||
echo "No .webm files found in $TARGET_DIR"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Found $total_files .webm files"
|
||||
|
||||
# Process each .webm file
|
||||
for webm_file in "$TARGET_DIR"/*.webm; do
|
||||
if [ ! -f "$webm_file" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Get just the filename (not full path) for processing
|
||||
filename=$(basename "$webm_file")
|
||||
|
||||
# Check if already processed
|
||||
if is_processed "$filename"; then
|
||||
echo "⏭️ Skipping (already processed): $filename"
|
||||
((skipped_count++))
|
||||
continue
|
||||
fi
|
||||
|
||||
# Process the file
|
||||
if process_file "$filename"; then
|
||||
((processed_count++))
|
||||
else
|
||||
echo "❌ Failed to process: $filename"
|
||||
((error_count++))
|
||||
fi
|
||||
|
||||
# Progress update
|
||||
total_done=$((processed_count + skipped_count + error_count))
|
||||
echo "Progress: $total_done/$total_files (Processed: $processed_count, Skipped: $skipped_count, Errors: $error_count)"
|
||||
echo ""
|
||||
|
||||
# Rate limiting delay (skip on last file)
|
||||
if [ "$total_done" -lt "$total_files" ]; then
|
||||
echo "Waiting ${DELAY_SECONDS}s before next request..."
|
||||
sleep "$DELAY_SECONDS"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "===================="
|
||||
echo "Processing complete!"
|
||||
echo "Total files: $total_files"
|
||||
echo "Newly processed: $processed_count"
|
||||
echo "Already processed (skipped): $skipped_count"
|
||||
echo "Errors: $error_count"
|
||||
echo "CSV file: $CSV_FILE"
|
||||
echo "===================="
|
||||
'
|
||||
Reference in New Issue
Block a user