File size: 2,735 Bytes
fe72b7c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import subprocess
import os
import tempfile

def merge_videos(video_files):
    """
    合併多個 MP4 影片檔案
    
    Args:
        video_files: 影片檔案路徑列表
    
    Returns:
        tuple: (輸出檔案路徑, 狀態訊息)
    """
    if not video_files or len(video_files) == 0:
        return None, "請至少上傳一個影片檔案"
    
    if len(video_files) == 1:
        return None, "請上傳至少兩個影片進行合併"
    
    try:
        # 創建臨時檔案列表
        list_file = tempfile.mktemp(suffix='.txt')
        output_path = tempfile.mktemp(suffix='.mp4')
        
        # 寫入 ffmpeg concat 檔案列表
        with open(list_file, 'w', encoding='utf-8') as f:
            for video_file in video_files:
                # 使用絕對路徑並轉義特殊字元
                abs_path = os.path.abspath(video_file)
                f.write(f"file '{abs_path}'\n")
        
        # 使用 ffmpeg concat demuxer 合併影片
        merge_cmd = [
            'ffmpeg',
            '-f', 'concat',
            '-safe', '0',
            '-i', list_file,
            '-c', 'copy',
            output_path,
            '-y'
        ]
        
        result = subprocess.run(merge_cmd, capture_output=True, text=True)
        
        # 清理臨時列表檔案
        if os.path.exists(list_file):
            os.remove(list_file)
        
        if result.returncode != 0:
            # 如果直接複製失敗,嘗試重新編碼
            merge_cmd_reencode = [
                'ffmpeg',
                '-f', 'concat',
                '-safe', '0',
                '-i', list_file,
                '-c:v', 'libx264',
                '-c:a', 'aac',
                '-preset', 'medium',
                output_path,
                '-y'
            ]
            
            # 重新創建列表檔案
            with open(list_file, 'w', encoding='utf-8') as f:
                for video_file in video_files:
                    abs_path = os.path.abspath(video_file)
                    f.write(f"file '{abs_path}'\n")
            
            result = subprocess.run(merge_cmd_reencode, capture_output=True, text=True)
            
            if os.path.exists(list_file):
                os.remove(list_file)
            
            if result.returncode != 0:
                return None, f"合併失敗: {result.stderr}"
        
        if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
            return output_path, f"成功合併 {len(video_files)} 個影片!"
        else:
            return None, "合併失敗,請確認影片格式正確"
            
    except Exception as e:
        return None, f"發生錯誤: {str(e)}"