#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
拼接双语音频：中文音频 + 静音 + 英文TTS
用法: python combine_bilingual_audio.py <adid>
"""

import os
import sys
import sqlite3
import subprocess
import tempfile


def get_file_duration(file_path):
    """
    获取音频文件时长（毫秒）
    """
    cmd = ["ffprobe", "-v", "quiet", "-show_entries", "format=duration", "-of", "default=noprint_wrappers=1:nokey=1", file_path]
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode == 0:
        return int(float(result.stdout.strip()) * 1000)
    return 0


def get_subtitles(adid, db_path):
    """
    从数据库获取字幕信息
    """
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()
    
    cursor.execute("""
        SELECT idx, start, end, cn, en FROM srts 
        WHERE adid = ? 
        ORDER BY idx
    """, (adid,))
    
    subtitles = []
    for row in cursor.fetchall():
        idx, start, end, cn, en = row
        # 解析时间格式
        start_ms = int(start)
        end_ms = int(end)
        subtitles.append((idx, start_ms, end_ms, cn, en))
    
    conn.close()
    return subtitles


def get_adname(adid, db_path):
    """
    从数据库获取adname
    """
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()
    
    cursor.execute("SELECT DISTINCT adname FROM srts WHERE adid = ? LIMIT 1", (adid,))
    result = cursor.fetchone()
    conn.close()
    
    if result:
        return result[0]
    return f"adid_{adid}"


def generate_silence(duration_ms, output_path):
    """
    生成指定长度的静音音频
    """
    duration_sec = duration_ms / 1000
    cmd = [
        "ffmpeg", "-y",
        "-f", "lavfi",
        "-i", "anullsrc=channel_layout=stereo:sample_rate=44100",
        "-t", str(duration_sec),
        "-acodec", "libmp3lame",
        output_path
    ]
    subprocess.run(cmd, capture_output=True)


def combine_bilingual_audio(adid):
    """
    拼接双语音频
    """
    # 配置
    db_path = r'\\ll\D\xtrssvjj\db\dpd.db'
    
    # 获取adname
    adname = get_adname(adid, db_path)
    print(f"adname: {adname}")
    
    # 目录路径
    cn_audio_dir = f"{adname}_cn_audio"
    en_tts_dir = os.path.join(r'\\ll\D\xtrssvjj', 'tts', adname)
    
    # 检查目录是否存在
    if not os.path.exists(cn_audio_dir):
        print(f"错误：中文音频目录不存在: {cn_audio_dir}")
        return False
    
    if not os.path.exists(en_tts_dir):
        print(f"错误：英文TTS目录不存在: {en_tts_dir}")
        return False
    
    # 获取字幕
    subtitles = get_subtitles(adid, db_path)
    print(f"找到 {len(subtitles)} 句字幕")
    
    if not subtitles:
        print("错误：未找到字幕信息")
        return False
    
    # 音频文件路径
    audio_file = os.path.join(r'\\ll\D\xtrssvjj', f"{adname}.mp3")
    
    # 获取音频文件总长度
    audio_duration = get_file_duration(audio_file)
    print(f"音频总长度: {audio_duration} 毫秒")
    
    # 计算每句的startpos、endpos、addstart、addend
    enhanced_subtitles = []
    for i, (idx, start, end, cn, en) in enumerate(subtitles):
        prevend = subtitles[i-1][2] if i > 0 else 0
        startgap = start - prevend if i > 0 else 0
        
        if i < len(subtitles)-1:
            nextstart = subtitles[i+1][1]
            endgap = nextstart - end
        else:
            # 最后一句的nextstart为音频文件的实际总长度
            nextstart = audio_duration
            endgap = nextstart - end if audio_duration > end else 0
        
        # 计算startpos和endpos
        # 第一句的startpos固定为0
        if i == 0:
            startpos = 0
        else:
            startpos = (prevend + start) // 2
        
        # 最后一句的endpos为视频的最后位置(总长度-1)
        if i == len(subtitles)-1:
            endpos = audio_duration - 1
        else:
            endpos = (end + nextstart) // 2
        
        # 计算addstart值：第一句addstart=0，后面的用400-(start-startpos)
        if i == 0:
            addstart = 0
        else:
            addstart = 400 - (start - startpos)
            if addstart <= 0:
                addstart = ''
        
        # 计算addend值：最后一句addend=0，其他用400-(endpos-end)
        if i == len(subtitles)-1:
            addend = 0
        else:
            addend = 400 - (endpos - end)
            if addend <= 0:
                addend = ''
        
        enhanced_subtitles.append((idx, start, end, startpos, endpos, addstart, addend, cn, en))
    
    # 创建临时目录
    with tempfile.TemporaryDirectory() as temp_dir:
        # 生成拼接文件列表
        filelist_path = os.path.join(temp_dir, "filelist.txt")
        
        with open(filelist_path, 'w', encoding='utf-8') as f:
            for i, (idx, start, end, startpos, endpos, addstart, addend, cn, en) in enumerate(enhanced_subtitles):
                # 1. 中文音频
                cn_audio_file = os.path.join(cn_audio_dir, f"seg{idx:03d}-{startpos}-{endpos}-*.mp3")
                # 使用glob找到实际文件
                import glob
                cn_files = glob.glob(cn_audio_file)
                if cn_files:
                    # 使用绝对路径
                    cn_file_abs = os.path.abspath(cn_files[0])
                    f.write(f"file '{cn_file_abs}'\n")
                
                # 2. addend静音
                if addend and addend > 0:
                    silence_file = os.path.join(temp_dir, f"silence_end_{idx}.mp3")
                    generate_silence(addend, silence_file)
                    # 使用绝对路径
                    silence_file_abs = os.path.abspath(silence_file)
                    f.write(f"file '{silence_file_abs}'\n")
                
                # 3. 英文TTS - 只使用网络共享位置的TTS文件
                en_tts_pattern = os.path.join(en_tts_dir, f"*-{idx:04d}.mp3")
                import glob
                en_files = glob.glob(en_tts_pattern)
                
                if en_files:
                    # 打印使用的网络TTS文件路径
                    print(f"使用网络TTS文件: {en_files[0]}")
                    # 调整TTS语速为70%
                    tts_file = en_files[0]
                    slowed_tts_file = os.path.join(temp_dir, f"slowed_tts_{idx:04d}.mp3")
                    # 使用FFmpeg调整语速，保持声调
                    subprocess.run([
                        'ffmpeg', '-y', '-i', tts_file, 
                        '-filter:a', 'atempo=0.7', 
                        '-ac', '2', '-ar', '44100', 
                        slowed_tts_file
                    ], check=True, capture_output=True)
                    # 使用绝对路径
                    slowed_tts_file_abs = os.path.abspath(slowed_tts_file)
                    f.write(f"file '{slowed_tts_file_abs}'\n")
                
                # 4. 下一句的addstart静音（除了最后一句）
                if i < len(enhanced_subtitles) - 1:
                    next_addstart = enhanced_subtitles[i+1][5]
                    if next_addstart and next_addstart > 0:
                        silence_file = os.path.join(temp_dir, f"silence_start_{i+1}.mp3")
                        generate_silence(next_addstart, silence_file)
                        # 使用绝对路径
                        silence_file_abs = os.path.abspath(silence_file)
                        f.write(f"file '{silence_file_abs}'\n")
        
        # 执行拼接
        output_file = f"{adname}_bilingual.mp3"
        cmd = [
            "ffmpeg", "-y",
            "-f", "concat",
            "-safe", "0",
            "-i", filelist_path,
            "-acodec", "libmp3lame",
            "-ar", "44100",
            "-ac", "2",
            output_file
        ]
        
        print("开始拼接双语音频...")
        # 使用binary模式读取输出，避免编码错误
        result = subprocess.run(cmd, capture_output=True)
        
        if result.returncode == 0:
            print(f"拼接完成！输出文件: {output_file}")
            return True
        else:
            # 尝试解码错误信息
            try:
                error_msg = result.stderr.decode('utf-8', errors='replace')
            except:
                try:
                    error_msg = result.stderr.decode('gbk', errors='replace')
                except:
                    error_msg = str(result.stderr)
            print(f"拼接失败！错误信息: {error_msg}")
            return False


def main():
    """
    主函数
    """
    if len(sys.argv) != 2:
        print("用法: python combine_bilingual_audio.py <adid>")
        print("示例: python combine_bilingual_audio.py 8496")
        sys.exit(1)
    
    try:
        adid = int(sys.argv[1])
    except ValueError:
        print("错误：adid必须是数字")
        sys.exit(1)
    
    print(f"=== 双语音频拼接工具 ===")
    print(f"adid: {adid}")
    
    success = combine_bilingual_audio(adid)
    
    if success:
        print("\n拼接完成！")
    else:
        print("\n拼接失败！")
        sys.exit(1)


if __name__ == "__main__":
    main()
