#!/usr/bin/env python3
"""
将第一段视频延长一倍时长+500毫秒，后半部分使用最后一帧作为静止画面并添加字幕
"""
import subprocess
import os
import tempfile

# 导入编码处理模块
from console_helper import (
    safe_print, print_header, print_step, print_info,
    print_success, print_fail, print_done
)

def get_video_duration(video_path):
    """获取视频时长（使用ffprobe）"""
    args = [
        'ffprobe',
        '-v', 'quiet',
        '-print_format', 'json',
        '-show_format',
        video_path
    ]
    
    try:
        result = subprocess.run(args, check=True, capture_output=True, text=True)
        import json
        data = json.loads(result.stdout)
        return float(data['format']['duration'])
    except Exception as e:
        safe_print(f"      获取时长失败: {e}")
        return None

def extract_last_frame(video_path, output_image, ffmpeg_path="ffmpeg"):
    """提取视频最后一帧"""
    # 先获取视频时长
    duration = get_video_duration(video_path)
    if duration is None:
        return False
    
    # 在视频结束前0.1秒提取一帧
    args = [
        ffmpeg_path,
        '-y',
        '-ss', str(max(0, duration - 0.1)),
        '-i', video_path,
        '-vframes', '1',
        '-q:v', '2',
        output_image
    ]
    
    try:
        subprocess.run(args, check=True, capture_output=True)
        return True
    except subprocess.CalledProcessError as e:
        safe_print(f"      提取最后一帧失败: {e}")
        return False

def read_subtitle_line(subtitle_path, line_number=1):
    """从字幕文件读取指定行的文本"""
    try:
        with open(subtitle_path, 'r', encoding='utf-8') as f:
            lines = f.readlines()
        
        # 查找指定行号的字幕
        current_line = 0
        for i, line in enumerate(lines):
            line = line.strip()
            if line.isdigit():
                current_line = int(line)
                if current_line == line_number:
                    # 找到字幕文本（跳过时间轴行）
                    for j in range(i+2, len(lines)):
                        subtitle_text = lines[j].strip()
                        if subtitle_text:
                            return subtitle_text
        return None
    except Exception as e:
        safe_print(f"      读取字幕失败: {e}")
        return None

def create_paused_video_with_subtitle(image_path, duration, subtitle_text, output_path, ffmpeg_path="ffmpeg"):
    """使用静态图片创建视频并添加字幕"""
    # 为字幕文本转义
    safe_subtitle = subtitle_text.replace('\\', '\\\\').replace("'", "\\'")
    
    # 创建带字幕的视频
    args = [
        ffmpeg_path,
        '-y',
        '-loop', '1',
        '-i', image_path,
        '-c:v', 'libx264',
        '-t', str(duration),
        '-pix_fmt', 'yuv420p',
        '-vf', f"fps=30,drawtext=text='{safe_subtitle}':fontsize=48:fontcolor=white:box=1:boxcolor=black@0.5:boxborderw=5:x=(w-text_w)/2:y=100",
        # 只输出视频流
        '-an',
        output_path
    ]
    
    try:
        subprocess.run(args, check=True, capture_output=True)
        return True
    except subprocess.CalledProcessError as e:
        safe_print(f"      创建带字幕的暂停视频失败: {e}")
        return False

def concatenate_videos(video_list, output_path, ffmpeg_path="ffmpeg"):
    """拼接多个视频（仅视频流）"""
    # 创建临时文件列表
    list_file = 'video_list.txt'
    with open(list_file, 'w', encoding='utf-8') as f:
        for video in video_list:
            escaped_path = video.replace('\\', '/')
            f.write(f"file '{escaped_path}'\n")
    
    args = [
        ffmpeg_path,
        '-y',
        '-f', 'concat',
        '-safe', '0',
        '-i', list_file,
        '-c:v', 'libx264',
        '-pix_fmt', 'yuv420p',
        # 只输出视频流
        '-an',
        output_path
    ]
    
    try:
        result = subprocess.run(args, check=True, capture_output=True, text=True)
        os.remove(list_file)
        return True
    except subprocess.CalledProcessError as e:
        safe_print(f"      拼接视频失败")
        if e.stderr:
            error_msg = e.stderr
            if "Permission denied" in error_msg:
                safe_print(f"      错误: 文件权限被拒绝，请更换输出文件名")
            else:
                safe_print(f"      错误信息: {error_msg[:300]}")
        try:
            os.remove(list_file)
        except:
            pass
        return False

def extract_audio(input_video, output_audio, ffmpeg_path="ffmpeg"):
    """提取音频流"""
    args = [
        ffmpeg_path,
        '-y',
        '-i', input_video,
        '-c:a', 'aac',
        '-ar', '44100',
        '-ac', '1',
        # 只输出音频流
        '-vn',
        output_audio
    ]
    
    try:
        subprocess.run(args, check=True, capture_output=True)
        return True
    except subprocess.CalledProcessError as e:
        safe_print(f"      提取音频失败: {e}")
        return False

def create_silent_audio(duration, output_audio, ffmpeg_path="ffmpeg"):
    """创建静音音频"""
    args = [
        ffmpeg_path,
        '-y',
        '-f', 'lavfi',
        '-i', 'anullsrc=r=44100:cl=mono',
        '-c:a', 'aac',
        '-ar', '44100',
        '-ac', '1',
        '-t', str(duration),
        output_audio
    ]
    
    try:
        subprocess.run(args, check=True, capture_output=True)
        return True
    except subprocess.CalledProcessError as e:
        safe_print(f"      创建静音音频失败: {e}")
        return False

def concatenate_audio(audio_list, output_audio, ffmpeg_path="ffmpeg"):
    """拼接多个音频"""
    # 创建临时文件列表
    list_file = 'audio_list.txt'
    with open(list_file, 'w', encoding='utf-8') as f:
        for audio in audio_list:
            escaped_path = audio.replace('\\', '/')
            f.write(f"file '{escaped_path}'\n")
    
    args = [
        ffmpeg_path,
        '-y',
        '-f', 'concat',
        '-safe', '0',
        '-i', list_file,
        '-c:a', 'aac',
        '-ar', '44100',
        '-ac', '1',
        output_audio
    ]
    
    try:
        result = subprocess.run(args, check=True, capture_output=True, text=True)
        os.remove(list_file)
        return True
    except subprocess.CalledProcessError as e:
        safe_print(f"      拼接音频失败: {e}")
        try:
            os.remove(list_file)
        except:
            pass
        return False

def merge_video_audio(video_path, audio_path, output_path, ffmpeg_path="ffmpeg"):
    """合并视频和音频"""
    args = [
        ffmpeg_path,
        '-y',
        '-i', video_path,
        '-i', audio_path,
        '-c:v', 'copy',
        '-c:a', 'aac',
        '-ar', '44100',
        '-ac', '1',
        '-shortest',
        output_path
    ]
    
    try:
        subprocess.run(args, check=True, capture_output=True)
        return True
    except subprocess.CalledProcessError as e:
        safe_print(f"      合并视频和音频失败: {e}")
        return False

def main():
    input_video = "segment_01.mp4"
    subtitle_path = "subtitles.srt"
    output_video = "segment_01_extended_with_subtitle.mp4"
    temp_dir = tempfile.gettempdir()
    
    # 延长时间（500毫秒）
    extra_duration = 0.5  # 500毫秒
    
    # 临时文件
    last_frame_image = os.path.join(temp_dir, "last_frame.png")
    paused_video = os.path.join(temp_dir, "paused_video.mp4")
    concatenated_video = os.path.join(temp_dir, "concatenated_video.mp4")
    original_audio = os.path.join(temp_dir, "original_audio.aac")
    silent_audio = os.path.join(temp_dir, "silent_audio.aac")
    concatenated_audio = os.path.join(temp_dir, "concatenated_audio.aac")
    
    print_header("视频延长工具 (带字幕)")
    safe_print(f"输入视频: {input_video}")
    safe_print(f"字幕文件: {subtitle_path}")
    safe_print("")
    
    # 1. 获取原始视频时长
    print_step(1, 7, "获取原始视频时长...")
    duration = get_video_duration(input_video)
    if duration is None:
        safe_print("获取时长失败，退出")
        return
    print_info("时长", f"{duration:.3f}秒")
    
    # 计算静止视频时长（原时长 + 500毫秒）
    paused_duration = duration + extra_duration
    print_info("静止视频时长", f"{paused_duration:.3f}秒 (原时长 + {extra_duration*1000}毫秒)")
    safe_print("")
    
    # 2. 读取字幕
    print_step(2, 7, "读取字幕...")
    subtitle_text = read_subtitle_line(subtitle_path, line_number=1)  # 读取第一行字幕
    if subtitle_text is None:
        safe_print("读取字幕失败，退出")
        return
    print_info("字幕文本", subtitle_text)
    safe_print("")
    
    # 3. 提取最后一帧
    print_step(3, 7, "提取最后一帧...")
    if not extract_last_frame(input_video, last_frame_image):
        safe_print("提取失败，退出")
        return
    print_info("已保存", last_frame_image)
    safe_print("")
    
    # 4. 创建带字幕的静止画面视频
    print_step(4, 7, "创建带字幕的静止画面视频...")
    if not create_paused_video_with_subtitle(last_frame_image, paused_duration, subtitle_text, paused_video):
        safe_print("创建失败，退出")
        return
    print_info("已创建", paused_video)
    print_info("时长", f"{paused_duration:.3f}秒")
    safe_print("")
    
    # 5. 拼接视频流
    print_step(5, 7, "拼接视频流...")
    if not concatenate_videos([input_video, paused_video], concatenated_video):
        safe_print("拼接失败，退出")
        return
    print_info("已拼接", concatenated_video)
    safe_print("")
    
    # 6. 处理音频
    print_step(6, 7, "处理音频...")
    
    # 6.1 提取原始音频
    if not extract_audio(input_video, original_audio):
        safe_print("提取音频失败，退出")
        return
    print_info("已提取原始音频", original_audio)
    
    # 6.2 创建静音音频（与静止视频同长）
    if not create_silent_audio(paused_duration, silent_audio):
        safe_print("创建静音音频失败，退出")
        return
    print_info("已创建静音音频", silent_audio)
    
    # 6.3 拼接音频
    if not concatenate_audio([original_audio, silent_audio], concatenated_audio):
        safe_print("拼接音频失败，退出")
        return
    print_info("已拼接音频", concatenated_audio)
    safe_print("")
    
    # 7. 合并视频和音频
    print_step(7, 7, "合并视频和音频...")
    if not merge_video_audio(concatenated_video, concatenated_audio, output_video):
        safe_print("合并失败，退出")
        return
    print_info("输出", output_video)
    
    # 8. 验证结果
    final_duration = get_video_duration(output_video)
    print_info("最终时长", f"{final_duration:.3f}秒 (原始时长 + 延长时间)")
    safe_print("")
    
    # 清理临时文件
    try:
        files_to_remove = [
            last_frame_image, paused_video, concatenated_video,
            original_audio, silent_audio, concatenated_audio
        ]
        for f in files_to_remove:
            if os.path.exists(f):
                os.remove(f)
        safe_print("[清理] 临时文件已删除")
    except Exception as e:
        safe_print(f"[清理] 清理临时文件时出错: {e}")
    
    print_done()

if __name__ == '__main__':
    main()
