SiamCafe.net Blog
Technology

Voice Cloning Automation Script

voice cloning automation script
Voice Cloning Automation Script | SiamCafe Blog
2025-10-21· อ. บอม — SiamCafe.net· 10,221 คำ

Voice Cloning คืออะไร

Voice Cloning เป็นเทคโนโลยี AI ที่ใช้ Deep Learning สร้างเสียงเลียนแบบเสียงของคนจริง โดยวิเคราะห์ลักษณะเฉพาะของเสียง (Speaker Embedding) เช่น โทนเสียง จังหวะการพูด น้ำเสียง ความถี่ แล้วสร้างเสียงใหม่จากข้อความที่กำหนด (Text-to-Speech) ให้ฟังเหมือนคนต้นแบบ

ปัจจุบัน Voice Cloning ใช้กันแพร่หลายใน Audiobook Production, Video Dubbing, Virtual Assistant, Content Creation, Accessibility สำหรับผู้พิการทางเสียง และ Personalized TTS เทคโนโลยีพัฒนาเร็วมากจนสามารถ Clone เสียงได้จากตัวอย่างเพียง 3-10 วินาที

ติดตั้งและเตรียมสภาพแวดล้อม

# === ติดตั้ง Voice Cloning Environment ===

# สร้าง Virtual Environment
python -m venv voice-clone-env
source voice-clone-env/bin/activate  # Linux/Mac
# voice-clone-env\Scripts\activate   # Windows

# ติดตั้ง Coqui TTS (XTTS v2)
pip install TTS torch torchaudio

# ติดตั้ง Dependencies เพิ่มเติม
pip install soundfile librosa scipy numpy pydub
pip install fastapi uvicorn python-multipart  # สำหรับ API

# ตรวจสอบ GPU
python -c "import torch; print(f'CUDA: {torch.cuda.is_available()}')"
python -c "import torch; print(f'GPU: {torch.cuda.get_device_name(0)}')" 

# ดาวน์โหลด Model
python -c "from TTS.api import TTS; tts = TTS('tts_models/multilingual/multi-dataset/xtts_v2')"
# Model จะถูกดาวน์โหลดอัตโนมัติ (~1.8GB)

# โครงสร้าง Project
voice-cloner/
├── main.py              # Main Script
├── api.py               # FastAPI Server
├── preprocess.py        # Audio Preprocessing
├── clone.py             # Voice Cloning Engine
├── batch_process.py     # Batch Processing
├── samples/             # Voice Samples
│   └── speaker.wav
├── output/              # Generated Audio
├── config.yaml          # Configuration
└── requirements.txt

Voice Cloning Script

# clone.py — Voice Cloning Engine
import os
import torch
import numpy as np
import soundfile as sf
from TTS.api import TTS
from pydub import AudioSegment
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

class VoiceCloner:
    """Voice Cloning Engine ด้วย XTTS v2"""

    def __init__(self, model_name="tts_models/multilingual/multi-dataset/xtts_v2",
                 device=None):
        self.device = device or ("cuda" if torch.cuda.is_available() else "cpu")
        logger.info(f"Loading model on {self.device}...")
        self.tts = TTS(model_name).to(self.device)
        logger.info("Model loaded successfully")

    def preprocess_audio(self, audio_path, output_path=None,
                         target_sr=22050, max_duration=30):
        """เตรียมไฟล์เสียงสำหรับ Voice Cloning"""
        audio = AudioSegment.from_file(audio_path)

        # Convert to mono
        if audio.channels > 1:
            audio = audio.set_channels(1)

        # Set sample rate
        audio = audio.set_frame_rate(target_sr)

        # Normalize volume
        target_dbfs = -20
        change_in_dbfs = target_dbfs - audio.dBFS
        audio = audio.apply_gain(change_in_dbfs)

        # Trim silence
        from pydub.silence import detect_leading_silence
        start_trim = detect_leading_silence(audio, silence_threshold=-40)
        end_trim = detect_leading_silence(audio.reverse(), silence_threshold=-40)
        audio = audio[start_trim:len(audio) - end_trim]

        # Limit duration
        if len(audio) > max_duration * 1000:
            audio = audio[:max_duration * 1000]

        out_path = output_path or audio_path.replace(".wav", "_processed.wav")
        audio.export(out_path, format="wav")
        logger.info(f"Preprocessed: {out_path} ({len(audio)/1000:.1f}s)")
        return out_path

    def clone_voice(self, text, speaker_wav, output_path,
                    language="th", speed=1.0):
        """Clone เสียงและสร้าง Audio จากข้อความ"""
        logger.info(f"Generating speech: '{text[:50]}...'")

        self.tts.tts_to_file(
            text=text,
            speaker_wav=speaker_wav,
            language=language,
            file_path=output_path,
            speed=speed,
        )

        # ตรวจสอบไฟล์ Output
        if os.path.exists(output_path):
            audio = AudioSegment.from_file(output_path)
            duration = len(audio) / 1000
            logger.info(f"Generated: {output_path} ({duration:.1f}s)")
            return {"path": output_path, "duration": duration}
        else:
            raise FileNotFoundError(f"Failed to generate: {output_path}")

    def batch_clone(self, texts, speaker_wav, output_dir,
                    language="th", prefix="output"):
        """Clone เสียงหลายข้อความพร้อมกัน"""
        os.makedirs(output_dir, exist_ok=True)
        results = []

        for i, text in enumerate(texts):
            output_path = os.path.join(output_dir, f"{prefix}_{i:04d}.wav")
            try:
                result = self.clone_voice(text, speaker_wav, output_path,
                                          language=language)
                results.append(result)
            except Exception as e:
                logger.error(f"Error on text {i}: {e}")
                results.append({"path": None, "error": str(e)})

        success = sum(1 for r in results if r.get("path"))
        logger.info(f"Batch complete: {success}/{len(texts)} succeeded")
        return results

    def concatenate_audio(self, audio_files, output_path, gap_ms=500):
        """รวมไฟล์เสียงหลายไฟล์เข้าด้วยกัน"""
        combined = AudioSegment.empty()
        gap = AudioSegment.silent(duration=gap_ms)

        for f in audio_files:
            if f and os.path.exists(f):
                audio = AudioSegment.from_file(f)
                combined += audio + gap

        combined.export(output_path, format="wav")
        logger.info(f"Concatenated {len(audio_files)} files -> {output_path}")
        return output_path

# ตัวอย่างการใช้งาน
if __name__ == "__main__":
    cloner = VoiceCloner()

    # Preprocess Speaker Sample
    processed = cloner.preprocess_audio("samples/speaker.wav")

    # Clone เสียงเดียว
    result = cloner.clone_voice(
        text="สวัสดีครับ นี่คือเสียงที่สร้างจาก AI Voice Cloning",
        speaker_wav=processed,
        output_path="output/test_output.wav",
        language="th",
    )
    print(f"Generated: {result}")

    # Batch Clone
    texts = [
        "ยินดีต้อนรับสู่ระบบ Voice Cloning อัตโนมัติ",
        "ระบบนี้ใช้เทคโนโลยี XTTS v2 ในการสร้างเสียง",
        "สามารถ Clone เสียงได้จากตัวอย่างเพียงไม่กี่วินาที",
    ]
    results = cloner.batch_clone(texts, processed, "output/batch/")

API Server สำหรับ Voice Cloning

# api.py — FastAPI Server สำหรับ Voice Cloning
from fastapi import FastAPI, UploadFile, File, Form
from fastapi.responses import FileResponse
import tempfile
import os
import uuid
from clone import VoiceCloner

app = FastAPI(title="Voice Cloning API")
cloner = VoiceCloner()

@app.post("/clone")
async def clone_voice(
    text: str = Form(...),
    language: str = Form(default="th"),
    speaker: UploadFile = File(...),
):
    """Clone เสียงจากไฟล์ตัวอย่างและข้อความ"""
    # Save uploaded file
    tmp_speaker = os.path.join(tempfile.gettempdir(), f"speaker_{uuid.uuid4()}.wav")
    with open(tmp_speaker, "wb") as f:
        content = await speaker.read()
        f.write(content)

    # Preprocess
    processed = cloner.preprocess_audio(tmp_speaker)

    # Generate
    output_path = os.path.join(tempfile.gettempdir(), f"output_{uuid.uuid4()}.wav")
    result = cloner.clone_voice(text, processed, output_path, language=language)

    # Cleanup
    os.remove(tmp_speaker)
    if os.path.exists(processed):
        os.remove(processed)

    return FileResponse(
        output_path,
        media_type="audio/wav",
        filename="cloned_voice.wav",
    )

@app.post("/batch")
async def batch_clone(
    texts: str = Form(...),  # JSON array of texts
    language: str = Form(default="th"),
    speaker: UploadFile = File(...),
):
    """Batch Clone หลายข้อความ"""
    import json

    text_list = json.loads(texts)

    tmp_speaker = os.path.join(tempfile.gettempdir(), f"speaker_{uuid.uuid4()}.wav")
    with open(tmp_speaker, "wb") as f:
        f.write(await speaker.read())

    processed = cloner.preprocess_audio(tmp_speaker)
    output_dir = os.path.join(tempfile.gettempdir(), f"batch_{uuid.uuid4()}")
    results = cloner.batch_clone(text_list, processed, output_dir, language)

    # Concatenate all outputs
    audio_files = [r["path"] for r in results if r.get("path")]
    final_output = os.path.join(tempfile.gettempdir(), f"final_{uuid.uuid4()}.wav")
    cloner.concatenate_audio(audio_files, final_output)

    return FileResponse(final_output, media_type="audio/wav")

@app.get("/health")
async def health():
    return {"status": "ok", "device": cloner.device}

# รัน: uvicorn api:app --host 0.0.0.0 --port 8000
# ทดสอบ:
# curl -X POST http://localhost:8000/clone \
#   -F "text=สวัสดีครับ" \
#   -F "language=th" \
#   -F "speaker=@samples/speaker.wav" \
#   -o output.wav

Automation Pipeline

# batch_process.py — Automation Pipeline สำหรับ Voice Cloning
import os
import csv
import yaml
import time
import logging
from clone import VoiceCloner

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(message)s",
)
logger = logging.getLogger(__name__)

def process_csv(csv_path, speaker_wav, output_dir, language="th"):
    """
    อ่านข้อความจาก CSV แล้ว Clone เสียงอัตโนมัติ
    CSV Format: id, text, filename
    """
    cloner = VoiceCloner()
    os.makedirs(output_dir, exist_ok=True)

    # Preprocess speaker
    processed = cloner.preprocess_audio(speaker_wav)

    results = []
    with open(csv_path, "r", encoding="utf-8") as f:
        reader = csv.DictReader(f)
        rows = list(reader)

    logger.info(f"Processing {len(rows)} items...")
    start_time = time.time()

    for i, row in enumerate(rows):
        text = row["text"]
        filename = row.get("filename", f"output_{i:04d}.wav")
        output_path = os.path.join(output_dir, filename)

        try:
            result = cloner.clone_voice(text, processed, output_path,
                                        language=language)
            results.append({"id": row.get("id", i), "status": "ok",
                            **result})
            logger.info(f"[{i+1}/{len(rows)}] OK: {filename}")
        except Exception as e:
            results.append({"id": row.get("id", i), "status": "error",
                            "error": str(e)})
            logger.error(f"[{i+1}/{len(rows)}] FAIL: {filename} - {e}")

    elapsed = time.time() - start_time
    success = sum(1 for r in results if r["status"] == "ok")
    logger.info(f"Done: {success}/{len(rows)} in {elapsed:.1f}s")

    # Save report
    report_path = os.path.join(output_dir, "report.csv")
    with open(report_path, "w", encoding="utf-8", newline="") as f:
        writer = csv.DictWriter(f, fieldnames=["id", "status", "path",
                                                "duration", "error"])
        writer.writeheader()
        writer.writerows(results)

    return results

if __name__ == "__main__":
    process_csv(
        csv_path="texts.csv",
        speaker_wav="samples/speaker.wav",
        output_dir="output/batch/",
        language="th",
    )

Best Practices และข้อควรระวัง

Voice Cloning คืออะไร

Voice Cloning ใช้ AI สร้างเสียงเลียนแบบเสียงคนจริง วิเคราะห์ลักษณะเฉพาะของเสียงแล้วสร้างเสียงใหม่จากข้อความ ใช้ใน Text-to-Speech, Audiobook, Dubbing, Virtual Assistant เทคโนโลยีใหม่ Clone ได้จากตัวอย่างเพียง 3-10 วินาที

ต้องใช้ข้อมูลเสียงเท่าไรสำหรับ Voice Cloning

Zero-shot Cloning (XTTS, Bark) ใช้ 3-10 วินาที Few-shot ใช้ 1-5 นาที Fine-tuning ใช้ 30 นาทีถึง 2 ชั่วโมง ยิ่งมีข้อมูลมากเสียงยิ่งเหมือน แต่เทคโนโลยีใหม่ Clone ได้ดีแม้ข้อมูลน้อย คุณภาพเสียงสำคัญกว่าปริมาณ

Voice Cloning ถูกกฎหมายหรือไม่

ถูกกฎหมายถ้าใช้เสียงตัวเองหรือได้รับอนุญาต Clone เสียงคนอื่นโดยไม่ได้อนุญาตอาจผิดกฎหมายลิขสิทธิ์และสิทธิส่วนบุคคล ห้ามสร้าง Deepfake หลอกลวง ควรระบุว่าเป็นเสียง AI เสมอ หลายประเทศกำลังออกกฎหมายควบคุม

เครื่องมือ Voice Cloning ที่ดีมีอะไรบ้าง

Open-source: Coqui TTS (XTTS v2), Tortoise TTS, Bark, OpenVoice, Fish Speech Commercial: ElevenLabs, Play.ht, Resemble AI, Murf แนะนำเริ่มจาก Coqui XTTS v2 เพราะ Open-source คุณภาพดี รองรับหลายภาษารวมถึงไทย

สรุป

Voice Cloning ด้วย AI เป็นเทคโนโลยีที่ทรงพลังและใช้งานง่ายขึ้นเรื่อยๆ ด้วย XTTS v2 สามารถ Clone เสียงจากตัวอย่างเพียงไม่กี่วินาที สร้าง Automation Pipeline ด้วย Python สำหรับ Batch Processing และเปิดเป็น API Service ด้วย FastAPI สิ่งสำคัญคือใช้อย่างมีจริยธรรม ได้รับอนุญาตจากเจ้าของเสียง ระบุว่าเป็นเสียง AI และเพิ่ม Watermark เพื่อป้องกันการนำไปใช้ในทางที่ผิด

📖 บทความที่เกี่ยวข้อง

Voice Cloning Team Productivityอ่านบทความ → Voice Cloning Data Pipeline ETLอ่านบทความ → Great Expectations Automation Scriptอ่านบทความ → Voice Cloning Production Setup Guideอ่านบทความ → Voice Cloning SaaS Architectureอ่านบทความ →

📚 ดูบทความทั้งหมด →