Greysuki commited on
Commit
e4570d0
1 Parent(s): fa832fa
Files changed (4) hide show
  1. .vscode/settings.json +39 -0
  2. app.py +140 -0
  3. gitignore +25 -0
  4. requirements.txt +3 -0
.vscode/settings.json ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "editor.trimAutoWhitespace": true,
3
+ "files.trimTrailingWhitespace": true, // 儲存的時候,會幫你自動過濾多餘的空格
4
+ "files.autoSave": "onFocusChange", // 是否自動儲存檔案
5
+ "editor.formatOnSave": true,
6
+ // "editor.defaultFormatter": "esbenp.prettier-vscode",
7
+ // "[javascriptreact]": {
8
+ // "editor.defaultFormatter": "esbenp.prettier-vscode",
9
+ // "editor.formatOnPaste": false, //Black didn;t support format selection
10
+ // "editor.formatOnSave": true,
11
+ // "editor.insertSpaces": true,
12
+ // "editor.detectIndentation": true,
13
+ // "editor.tabSize": 2
14
+ // },
15
+ "editor.wordWrapColumn": 240,
16
+ "python.linting.enabled": false,
17
+ "python.linting.pylintEnabled": true,
18
+ "python.linting.pylintPath": "pylint",
19
+ "python.linting.pylintArgs": [
20
+ "--max-line-length",
21
+ "240",
22
+ "--aggressive"
23
+ ],
24
+ // "python.formatting.provider": "black", // or "black" here
25
+ // "python.formatting.blackArgs": [
26
+ // "--line-length",
27
+ // "80"
28
+ // ],
29
+ "[python]": {
30
+ // 加入這幾行
31
+ "editor.formatOnPaste": false, //Black didn;t support format selection
32
+ "editor.formatOnSave": true,
33
+ // "editor.renderIndentGuides": true,
34
+ "editor.insertSpaces": true,
35
+ "editor.detectIndentation": true,
36
+ "editor.tabSize": 4
37
+ },
38
+ // "python.analysis.typeCheckingMode": "basic",
39
+ }
app.py ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import openai
3
+ from typing import Iterator, TextIO
4
+ import tempfile
5
+ from pydub import AudioSegment
6
+
7
+
8
+ def audio_from_file(filename: str) -> AudioSegment:
9
+ try:
10
+ audio = AudioSegment.from_file(filename)
11
+ except FileNotFoundError:
12
+ raise ValueError(
13
+ f"Cannot load audio from file: `{filename}` not found. Do you forgot to install `ffmpeg`."
14
+ )
15
+
16
+ return audio
17
+
18
+
19
+ def format_timestamp(seconds: float, always_include_hours: bool = False):
20
+ assert seconds >= 0, "non-negative timestamp expected"
21
+ milliseconds = round(seconds * 1000.0)
22
+
23
+ hours = milliseconds // 3_600_000
24
+ milliseconds -= hours * 3_600_000
25
+
26
+ minutes = milliseconds // 60_000
27
+ milliseconds -= minutes * 60_000
28
+
29
+ seconds = milliseconds // 1_000
30
+ milliseconds -= seconds * 1_000
31
+
32
+ hours_marker = f"{hours}:" if always_include_hours or hours > 0 else ""
33
+ return f"{hours_marker}{minutes:02d}:{seconds:02d}.{milliseconds:03d}"
34
+
35
+
36
+ def write_srt(transcript: Iterator[dict], file: TextIO):
37
+ """
38
+ Write a transcript to a file in SRT format.
39
+ Example usage:
40
+ from pathlib import Path
41
+ from whisper.utils import write_srt
42
+ result = transcribe(model, audio_path, temperature=temperature, **args)
43
+ # save SRT
44
+ audio_basename = Path(audio_path).stem
45
+ with open(Path(output_dir) / (audio_basename + ".srt"), "w", encoding="utf-8") as srt:
46
+ write_srt(result["segments"], file=srt)
47
+ """
48
+ with open(file, "w", encoding="UTF-8") as f:
49
+ for segment in transcript:
50
+ # write srt lines
51
+ id = segment["id"]
52
+ start = format_timestamp(segment["start"], always_include_hours=True)
53
+ end = format_timestamp(segment["end"], always_include_hours=True)
54
+ text = segment["text"].strip().replace("-->", "->")
55
+
56
+ f.write(f"{id}\n{start} --> {end}\n{text}\n\n")
57
+
58
+
59
+ def create_main_tab():
60
+ with gr.Blocks() as demo:
61
+ with gr.Row():
62
+ with gr.Column():
63
+ api_text = gr.Textbox(label="OpenAI API Key")
64
+
65
+ file_type = gr.Radio(
66
+ ["Video", "Audio"],
67
+ value="Video",
68
+ label="File Type",
69
+ interactive=True,
70
+ )
71
+ video = gr.Video()
72
+ audio = gr.Audio(visible=False)
73
+ with gr.Row():
74
+ compress_btn = gr.Button("Compress")
75
+ submit_btn = gr.Button("Submit")
76
+ with gr.Column():
77
+ compress_file = gr.File(label="Compress file", interactive=False)
78
+ subtitle_file = gr.File(label="Subtitle")
79
+ message_text = gr.Textbox(label="Info")
80
+
81
+ def handle_file_type_change(evt: gr.SelectData):
82
+ if evt.index == 0:
83
+ # Video
84
+ return [gr.update(visible=True), gr.update(visible=False)]
85
+ elif evt.index == 1:
86
+ # Audio
87
+ return [gr.update(visible=False), gr.update(visible=True)]
88
+
89
+ file_type.select(
90
+ handle_file_type_change,
91
+ None,
92
+ [video, audio],
93
+ )
94
+
95
+ def handle_compress_btn_submit(file_type, video, audio):
96
+ if file_type == "Video":
97
+ audio_data = audio_from_file(video)
98
+ elif file_type == "Audio":
99
+ audio_data = audio_from_file(audio)
100
+
101
+ with tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) as tmp_file:
102
+ audio_data.export(tmp_file.name, format="mp3", bitrate="96k")
103
+
104
+ return tmp_file.name
105
+
106
+ compress_btn.click(
107
+ fn=handle_compress_btn_submit,
108
+ inputs=[file_type, video, audio],
109
+ outputs=[compress_file],
110
+ )
111
+
112
+ def handle_btn_submit(compress_file, api_text):
113
+ def transcribe_audio(input_file, output_file):
114
+ with open(input_file, "rb") as f:
115
+ try:
116
+ result = openai.Audio.transcribe("whisper-1", f)
117
+ write_srt(result["segments"], output_file)
118
+ return "Success! The subtitle file will be named: {output_file}"
119
+ except Exception as e:
120
+ return f"Error. OpenAI API unavailable. Received: {e}"
121
+
122
+ openai.api_key = api_text
123
+
124
+ with tempfile.NamedTemporaryFile(suffix=".srt", delete=False) as out_file:
125
+ out_message = transcribe_audio(compress_file.name, out_file.name)
126
+
127
+ return out_file.name, out_message
128
+
129
+ submit_btn.click(
130
+ fn=handle_btn_submit,
131
+ inputs=[compress_file, api_text],
132
+ outputs=[subtitle_file, message_text],
133
+ )
134
+
135
+ return demo
136
+
137
+
138
+ demo = create_main_tab()
139
+ if __name__ == "__main__":
140
+ demo.launch()
gitignore ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ .vscode/
3
+ build/
4
+ dist/
5
+ dist_onefile/
6
+ flagged/
7
+
8
+ venv/
9
+
10
+ test/
11
+ img/
12
+ mp4/
13
+ out/
14
+ wav/
15
+ tmp/
16
+ project/
17
+ repositories/
18
+
19
+ __pycache__/
20
+ pretrained_models/
21
+
22
+ # *.srt
23
+
24
+ test.py
25
+ **/.openai
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ gradio
2
+ openai
3
+ pydub