AI Newsletter Digest improvements: fixed QP soft line break decoding, URL extraction, and content cleaning
This commit is contained in:
80
skills/openclaw-self-healing/scripts/newsletter-to-audio.sh
Normal file
80
skills/openclaw-self-healing/scripts/newsletter-to-audio.sh
Normal file
@@ -0,0 +1,80 @@
|
||||
#!/bin/bash
|
||||
# newsletter-to-audio.sh
|
||||
# 뉴스레터 텍스트 → 오디오 브리핑 변환
|
||||
# 사용법: ./newsletter-to-audio.sh "뉴스레터 내용" [output.mp3]
|
||||
|
||||
set -e
|
||||
|
||||
TEXT="$1"
|
||||
OUTPUT="${2:-~/Downloads/briefing-$(date +%Y%m%d-%H%M).mp3}"
|
||||
|
||||
if [ -z "$TEXT" ]; then
|
||||
echo "사용법: $0 \"뉴스레터 내용\" [output.mp3]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# OpenAI TTS API 사용
|
||||
if [ -z "$OPENAI_API_KEY" ]; then
|
||||
echo "❌ OPENAI_API_KEY 환경변수 필요"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🎙️ 오디오 생성 중..."
|
||||
|
||||
# 4096자 제한 → 청킹 필요
|
||||
CHAR_LIMIT=4000
|
||||
TEXT_LENGTH=${#TEXT}
|
||||
|
||||
if [ $TEXT_LENGTH -le $CHAR_LIMIT ]; then
|
||||
# 단일 요청
|
||||
curl -s https://api.openai.com/v1/audio/speech \
|
||||
-H "Authorization: Bearer $OPENAI_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"model\": \"tts-1\",
|
||||
\"input\": $(echo "$TEXT" | jq -Rs .),
|
||||
\"voice\": \"nova\",
|
||||
\"speed\": 1.1
|
||||
}" \
|
||||
--output "$OUTPUT"
|
||||
|
||||
echo "✅ 생성 완료: $OUTPUT"
|
||||
else
|
||||
# 청킹 모드
|
||||
echo "📦 텍스트 길이 $TEXT_LENGTH자 → 청킹 모드"
|
||||
|
||||
TEMP_DIR=$(mktemp -d)
|
||||
CHUNK_NUM=0
|
||||
|
||||
# 문장 단위로 분할
|
||||
echo "$TEXT" | fold -s -w $CHAR_LIMIT | while read -r CHUNK; do
|
||||
CHUNK_NUM=$((CHUNK_NUM + 1))
|
||||
CHUNK_FILE="$TEMP_DIR/chunk_$(printf '%03d' $CHUNK_NUM).mp3"
|
||||
|
||||
echo " 청크 $CHUNK_NUM 생성 중..."
|
||||
curl -s https://api.openai.com/v1/audio/speech \
|
||||
-H "Authorization: Bearer $OPENAI_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"model\": \"tts-1\",
|
||||
\"input\": $(echo "$CHUNK" | jq -Rs .),
|
||||
\"voice\": \"nova\",
|
||||
\"speed\": 1.1
|
||||
}" \
|
||||
--output "$CHUNK_FILE"
|
||||
done
|
||||
|
||||
# ffmpeg로 병합
|
||||
echo "🔗 청크 병합 중..."
|
||||
ffmpeg -y -f concat -safe 0 \
|
||||
-i <(for f in "$TEMP_DIR"/chunk_*.mp3; do echo "file '$f'"; done) \
|
||||
-c copy "$OUTPUT" 2>/dev/null
|
||||
|
||||
rm -rf "$TEMP_DIR"
|
||||
echo "✅ 생성 완료: $OUTPUT"
|
||||
fi
|
||||
|
||||
# 파일 정보
|
||||
DURATION=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$OUTPUT" 2>/dev/null | cut -d. -f1)
|
||||
SIZE=$(du -h "$OUTPUT" | cut -f1)
|
||||
echo "📊 길이: ${DURATION}초 / 크기: $SIZE"
|
||||
Reference in New Issue
Block a user