← back to Rentv Tour
batch-pitch.sh
40 lines
#!/bin/bash
cd /Users/macstudio3/Projects/rentv-tour
SAY=~/.claude/skills/clone-voice/scripts/say.sh
AV_LOOK=b2105c3cc1fd4464b11cd24c417b5751
for id in $(node pitch-set.mjs ids); do
echo "=== $id ==="
txt=$(node pitch-set.mjs vo $id)
bash $SAY "$txt" /tmp/pv-$id.wav >/dev/null 2>&1
ffmpeg -v error -y -i /tmp/pv-$id.wav -c:a aac -b:a 160k videos/pitch/assets/vo.m4a >/dev/null 2>&1
dur=$(ffprobe -v error -show_entries format=duration -of default=nk=1:nw=1 videos/pitch/assets/vo.m4a)
echo " VO ${dur}s"
node pitch-set.mjs emit $id $dur >/dev/null 2>&1
(cd videos/pitch && npx hyperframes render --output renders/$id-base.mp4 >/dev/null 2>&1)
echo " base rendered"
# 15s avatar intro
ffmpeg -v error -y -t 15 -i /tmp/pv-$id.wav -c:a libmp3lame -b:a 192k /tmp/pv15-$id.mp3 >/dev/null 2>&1
AID=$(heygen asset create --file /tmp/pv15-$id.mp3 2>/dev/null | python3 -c 'import sys,json;print(json.load(sys.stdin)["data"]["asset_id"])' 2>/dev/null)
VID=$(heygen video create -d "{\"type\":\"avatar\",\"avatar_id\":\"$AV_LOOK\",\"audio_asset_id\":\"$AID\",\"aspect_ratio\":\"1:1\",\"title\":\"$id intro\"}" 2>/dev/null | python3 -c 'import sys,json;print(json.load(sys.stdin)["data"]["video_id"])' 2>/dev/null)
echo " avatar VID=$VID"
for i in $(seq 1 24); do
S=$(heygen video get $VID 2>/dev/null | python3 -c 'import sys,json;print(json.load(sys.stdin)["data"].get("status",""))' 2>/dev/null)
if [ "$S" = "completed" ]; then
URL=$(heygen video get $VID 2>/dev/null | python3 -c 'import sys,json;print(json.load(sys.stdin)["data"].get("video_url",""))' 2>/dev/null)
curl -s -o /tmp/pav-$id.mp4 "$URL"; echo " avatar downloaded"; break
fi
[ "$S" = "failed" ] && { echo " avatar FAILED"; break; }
node -e 'setTimeout(()=>{},10000)' 2>/dev/null
done
# composite: circular PIP over first 15s, base audio (full VO)
if [ -f /tmp/pav-$id.mp4 ]; then
ffmpeg -v error -y -i videos/pitch/renders/$id-base.mp4 -i /tmp/pav-$id.mp4 -filter_complex \
"[1:v]scale=340:340,format=rgba,geq=r='r(X,Y)':g='g(X,Y)':b='b(X,Y)':a='if(gt((X-170)*(X-170)+(Y-170)*(Y-170),165*165),0,255)'[pip];[0:v][pip]overlay=W-w-56:H-h-56:enable='lte(t,15)':format=auto[v]" \
-map "[v]" -map 0:a -c:v libx264 -preset medium -crf 20 -c:a aac -b:a 192k -pix_fmt yuv420p videos/pitch/renders/$id.mp4 >/dev/null 2>&1
echo " FINAL $id.mp4 ($(ls -la videos/pitch/renders/$id.mp4|awk '{printf "%.1fMB",$5/1048576}'))"
else
cp videos/pitch/renders/$id-base.mp4 videos/pitch/renders/$id.mp4; echo " (no avatar — used base)"
fi
done
echo "PITCH BATCH DONE"