-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspeechtotext.py
196 lines (160 loc) · 7.14 KB
/
speechtotext.py
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
import os
import sys
from google.cloud import storage
import json
import io
from google.cloud import speech_v1
from google.cloud.speech_v1 import types
import subprocess
from pydub.utils import mediainfo
import subprocess
import math
import datetime
import srt
import glob
os.environ["GOOGLE_APPLICATION_CREDENTIALS"]="active-guild-395117-9e1d030b7f0d.json"
def video_info(video_filepath):
""" this function returns number of channels, bit rate, and sample rate of the video"""
video_data = mediainfo(video_filepath)
channels = video_data["channels"]
bit_rate = video_data["bit_rate"]
sample_rate = video_data["sample_rate"]
return channels, bit_rate, sample_rate
def upload_blob(bucket_name, source_file_name, destination_blob_name):
"""Uploads a file to the bucket."""
# bucket_name = "your-bucket-name"
# source_file_name = "local/path/to/file"
# destination_blob_name = "storage-object-name"
bucket_name = "my-stt-bucket-01"
destination_blob_name = "audio"
storage_client = storage.Client()
bucket = storage_client.bucket(bucket_name)
blob = bucket.blob(destination_blob_name)
blob.upload_from_filename(source_file_name)
print(
"File {} uploaded to {}.".format(
source_file_name, destination_blob_name
)
)
def long_running_recognize(storage_uri, channels, sample_rate, audio_path):
client = speech_v1.SpeechClient()
config = {
"language_code": "ar",
"sample_rate_hertz": int(sample_rate),
"encoding": speech_v1.RecognitionConfig.AudioEncoding.LINEAR16,
"audio_channel_count": int(channels),
"enable_word_time_offsets": True,
"model": "Default",
"enable_automatic_punctuation": False
}
# Load the audio file
with open(audio_path, "rb") as audio_file:
content = audio_file.read()
audio = types.RecognitionAudio(content=content)
operation = client.long_running_recognize(config=config, audio=audio)
print(u"Waiting for operation to complete...")
response = operation.result()
return response
def subtitle_generation(response, offset, bin_size=3):
"""We define a bin of time period to display the words in sync with audio.
Here, bin_size = 3 means each bin is of 3 secs.
All the words in the interval of 3 secs in result will be grouped togather."""
transcriptions = []
index = 0
offset_seconds = offset
offset_microseconds = offset * 1000
for result in response.results:
print("results: " + str(result))
try:
if result.alternatives[0].words[0].start_time.seconds:
# bin start -> for first word of result
start_sec = result.alternatives[0].words[0].start_time.seconds + offset_seconds
start_microsec = result.alternatives[0].words[0].start_time.microseconds + offset_microseconds
else:
# bin start -> For First word of response
start_sec = 0 + offset
start_microsec = 0 + offset_microseconds
end_sec = start_sec + bin_size # bin end sec
# for last word of result
last_word_end_sec = result.alternatives[0].words[-1].end_time.seconds + offset_seconds
print("last_word_end_sec: " + str(result.alternatives[0].words[-1].end_time.seconds))
last_word_end_microsec = result.alternatives[0].words[-1].end_time.microseconds + offset_microseconds
# bin transcript
transcript = result.alternatives[0].words[0].word
index += 1 # subtitle index
for i in range(len(result.alternatives[0].words) - 1):
try:
word = result.alternatives[0].words[i + 1].word
word_start_sec = result.alternatives[0].words[i + 1].start_time.seconds + offset_seconds
word_start_microsec = result.alternatives[0].words[i + 1].start_time.microseconds + offset_microseconds
word_end_sec = result.alternatives[0].words[i + 1].end_time.seconds + offset_seconds
word_end_microsec = result.alternatives[0].words[i + 1].end_time.microseconds + offset_microseconds
if word_end_sec < end_sec:
transcript = transcript + " " + word
else:
previous_word_end_sec = result.alternatives[0].words[i].end_time.seconds + offset_seconds
previous_word_end_microsec = result.alternatives[0].words[i].end_time.microseconds + offset_microseconds
# append bin transcript
transcriptions.append(srt.Subtitle(index, datetime.timedelta(0, start_sec, start_microsec), datetime.timedelta(0, previous_word_end_sec, previous_word_end_microsec), transcript))
# reset bin parameters
start_sec = word_start_sec
start_microsec = word_start_microsec
end_sec = start_sec + bin_size
transcript = result.alternatives[0].words[i + 1].word
index += 1
except IndexError:
pass
# append transcript of last transcript in bin
transcriptions.append(srt.Subtitle(index, datetime.timedelta(0, start_sec, start_microsec), datetime.timedelta(0, last_word_end_sec, last_word_end_microsec), transcript))
index += 1
except IndexError:
pass
# turn transcription list into subtitles
# print(transcript)
subtitles = srt.compose(transcriptions)
print(subtitles)
return subtitles
def main(video_path, audio_path):
source_file_name = "sourcefile"
channels, bit_rate, sample_rate = video_info(video_path)
audio_info = mediainfo(video_path)
# Extract desired information
channels = audio_info['channels']
bit_rate = audio_info['bit_rate']
sample_rate = audio_info['sample_rate']
storage_url = "gs://my-stt-bucket-01/audio"
split_command = [
'ffmpeg',
'-i',
audio_path,
'-f',
'segment',
'-segment_time',
'30',
'-c',
'copy',
'splitted-'+audio_path+'-%03d.wav'
]
# Execute the command
subprocess.run(split_command)
directory_path = './'
string_pattern = 'splitted-'+audio_path+'*'
# Use glob to find files that match the specified pattern
matching_files = glob.glob(directory_path + '/' + string_pattern)
sorted_list = sorted(matching_files, key=lambda x: int(x.split('-')[-1].split('.')[0]))
print(sorted_list)
# Loop through the matching files
i = 000
offset = 0
for file_name in sorted_list:
print(file_name)
response = long_running_recognize(storage_url, channels, sample_rate, file_name)
subtitles = str(subtitle_generation(response, offset))
with open("subtitles"+audio_path+".srt", "a") as f:
f.write(subtitles)
i += 1
offset += 30
if __name__ == "__main__":
video_path = sys.argv[1]
audio_path = sys.argv[2]
main(video_path, audio_path)