File size: 3,310 Bytes
f7598da
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
from datetime import timedelta
import subprocess

def timestamp_to_srt(seconds):
    td = timedelta(seconds=seconds)
    total_seconds = int(td.total_seconds())
    micros = td.microseconds
    hours, remainder = divmod(total_seconds, 3600)
    minutes, seconds = divmod(remainder, 60)
    return f"{hours:02}:{minutes:02}:{seconds:02},{micros//1000:03}"

def json_to_srt(json_data):
    """

    Converts internal JSON subtitle format to SRT.

    If 'words' key is present, generates word-level timestamps (Karaoke/Editing style).

    Otherwise, uses segment-level timestamps.

    """
    srt_content = ""
    counter = 1
    
    for block in json_data:
        # Check if words detail is available for Word-Level SRT
        if isinstance(block, dict) and "words" in block and block["words"]:
            for word_obj in block["words"]:
                start = word_obj.get('start', 0)
                end = word_obj.get('end', 0)
                text = word_obj.get('word', "")
                
                srt_content += f"{counter}\n"
                srt_content += f"{timestamp_to_srt(start)} --> {timestamp_to_srt(end)}\n"
                srt_content += f"{text}\n\n"
                counter += 1
        else:
            # Fallback to segment level
            start = 0
            end = 0
            text = ""
            if isinstance(block, dict):
                start = block.get('start', 0)
                end = block.get('end', 0)
                text = block.get('text', "")
            elif isinstance(block, (list, tuple)) and len(block) >= 3:
                start, end, text = block[0], block[1], block[2]
                
            srt_content += f"{counter}\n"
            srt_content += f"{timestamp_to_srt(start)} --> {timestamp_to_srt(end)}\n"
            srt_content += f"{text}\n\n"
            counter += 1
            
    return srt_content

def get_video_dims(vid_path):
    """Returns (width, height, duration_frames)"""
    try:
        cmd_w = ["ffprobe", "-v", "error", "-select_streams", "v:0", "-show_entries", "stream=width", "-of", "default=noprint_wrappers=1:nokey=1", vid_path]
        width = int(subprocess.check_output(cmd_w).decode().strip())
        
        cmd_h = ["ffprobe", "-v", "error", "-select_streams", "v:0", "-show_entries", "stream=height", "-of", "default=noprint_wrappers=1:nokey=1", vid_path]
        height = int(subprocess.check_output(cmd_h).decode().strip())
        
        cmd_dur = ["ffprobe", "-v", "error", "-show_entries", "format=duration", "-of", "default=noprint_wrappers=1:nokey=1", vid_path]
        dur_sec = float(subprocess.check_output(cmd_dur).decode().strip())
        
        # Assume 30fps for calculation if not probed, but probing is better
        cmd_fps = ["ffprobe", "-v", "error", "-select_streams", "v:0", "-show_entries", "stream=r_frame_rate", "-of", "default=noprint_wrappers=1:nokey=1", vid_path]
        fps_str = subprocess.check_output(cmd_fps).decode().strip()
        num, den = map(int, fps_str.split('/'))
        fps = num / den if den > 0 else 30.0
        
        return width, height, int(dur_sec * fps), fps
    except Exception as e:
        print(f"Error probing video: {e}")
        return 1920, 1080, 300, 30.0