jacky3102 commited on
Commit
12d5c60
·
verified ·
1 Parent(s): b90b2ee

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +43 -5
app.py CHANGED
@@ -20,6 +20,41 @@ def format_timestamp(seconds: float) -> str:
20
  millisecs = int((seconds - int(seconds)) * 1000)
21
  return f"{hours:02d}:{minutes:02d}:{secs:02d},{millisecs:03d}"
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  def generate_srt(segments) -> str:
24
  srt_content = []
25
  for i, segment in enumerate(segments, 1):
@@ -54,7 +89,8 @@ async def health_check():
54
  async def generate_subtitle(
55
  file: UploadFile = File(...),
56
  output_format: str = Form("srt"),
57
- language: Optional[str] = Form(None)
 
58
  ):
59
  valid_formats = ["srt", "vtt", "txt", "json"]
60
  if output_format not in valid_formats:
@@ -67,18 +103,20 @@ async def generate_subtitle(
67
  tmp_path = tmp_file.name
68
 
69
  try:
70
- transcribe_options = {}
71
  if language:
72
  transcribe_options["language"] = language
73
 
74
  result = model.transcribe(tmp_path, **transcribe_options)
75
 
 
 
76
  if output_format == "srt":
77
- subtitle_text = generate_srt(result["segments"])
78
  media_type = "text/plain"
79
  filename = "subtitle.srt"
80
  elif output_format == "vtt":
81
- subtitle_text = generate_vtt(result["segments"])
82
  media_type = "text/plain"
83
  filename = "subtitle.vtt"
84
  elif output_format == "txt":
@@ -88,7 +126,7 @@ async def generate_subtitle(
88
  elif output_format == "json":
89
  subtitle_text = json.dumps({
90
  "text": result["text"],
91
- "segments": result["segments"],
92
  "language": result["language"]
93
  }, ensure_ascii=False, indent=2)
94
  media_type = "application/json"
 
20
  millisecs = int((seconds - int(seconds)) * 1000)
21
  return f"{hours:02d}:{minutes:02d}:{secs:02d},{millisecs:03d}"
22
 
23
+ def group_by_chars(result, max_chars: int):
24
+ """用词级时间戳按字数重新组合字幕段,时间戳精确来自 Whisper"""
25
+ words = []
26
+ for seg in result["segments"]:
27
+ for w in seg.get("words", []):
28
+ word = w["word"].strip()
29
+ if word:
30
+ words.append({"word": word, "start": w["start"], "end": w["end"]})
31
+
32
+ if not words:
33
+ # 没有词级时间戳,回退原始分段
34
+ return result["segments"]
35
+
36
+ segments = []
37
+ buf_text = ""
38
+ buf_start = None
39
+ buf_end = None
40
+
41
+ for w in words:
42
+ if buf_start is None:
43
+ buf_start = w["start"]
44
+ buf_text += w["word"]
45
+ buf_end = w["end"]
46
+
47
+ # 达到字数上限,或遇到句末标点就切断
48
+ if len(buf_text) >= max_chars or buf_text[-1] in ",。!?、,.!?":
49
+ segments.append({"start": buf_start, "end": buf_end, "text": buf_text})
50
+ buf_text = ""
51
+ buf_start = None
52
+
53
+ if buf_text:
54
+ segments.append({"start": buf_start, "end": buf_end, "text": buf_text})
55
+
56
+ return segments
57
+
58
  def generate_srt(segments) -> str:
59
  srt_content = []
60
  for i, segment in enumerate(segments, 1):
 
89
  async def generate_subtitle(
90
  file: UploadFile = File(...),
91
  output_format: str = Form("srt"),
92
+ language: Optional[str] = Form(None),
93
+ max_chars: int = Form(0) # 0 = 不拆分,用 Whisper 原始分段
94
  ):
95
  valid_formats = ["srt", "vtt", "txt", "json"]
96
  if output_format not in valid_formats:
 
103
  tmp_path = tmp_file.name
104
 
105
  try:
106
+ transcribe_options = {"word_timestamps": True}
107
  if language:
108
  transcribe_options["language"] = language
109
 
110
  result = model.transcribe(tmp_path, **transcribe_options)
111
 
112
+ segments = group_by_chars(result, max_chars) if max_chars > 0 else result["segments"]
113
+
114
  if output_format == "srt":
115
+ subtitle_text = generate_srt(segments)
116
  media_type = "text/plain"
117
  filename = "subtitle.srt"
118
  elif output_format == "vtt":
119
+ subtitle_text = generate_vtt(segments)
120
  media_type = "text/plain"
121
  filename = "subtitle.vtt"
122
  elif output_format == "txt":
 
126
  elif output_format == "json":
127
  subtitle_text = json.dumps({
128
  "text": result["text"],
129
+ "segments": segments,
130
  "language": result["language"]
131
  }, ensure_ascii=False, indent=2)
132
  media_type = "application/json"