1+ import os
2+ import subprocess
3+ import json
4+ from time import perf_counter
5+ from ffmpy import FFmpeg
6+ import utils
7+
8+ # Path to the Whisper executable inside the container
9+ WHISPER_EXECUTABLE = os .environ .get ('WHISPER_EXE' ,'whisper' ) # Executable 'main' is assumed to be in the same directory as this script
10+ MODEL = os .environ .get ('WHISPER_MODEL' ,'models/ggml-base.en.bin' )
11+
12+ def convert_video_to_wav (input_filepath , offset = None ):
13+ """
14+ Converts a video file to WAV format using ffmpy.
15+ """
16+ try :
17+ start_time = perf_counter ()
18+ if offset is None :
19+ offset = 0.0
20+
21+ nthreads = utils .getMaxThreads ()
22+
23+ print (f"Converting video '{ input_filepath } ' to WAV with offset { offset } using { nthreads } thread(s)." )
24+ output_filepath = utils .getTmpFile ()
25+ ext = '.wav'
26+
27+ ff = FFmpeg (
28+ global_options = f"-hide_banner -loglevel error -nostats -threads { nthreads } " ,
29+ inputs = {input_filepath : f'-ss { offset } ' },
30+ outputs = {output_filepath : '-c:a pcm_s16le -ac 1 -y -ar 16000 -f wav' }
31+ )
32+ print (f"Starting conversion. Audio output will be saved in { output_filepath } " )
33+ ff .run ()
34+ end_time = perf_counter ()
35+ print (f"Conversion complete. Duration: { int (end_time - start_time )} seconds" )
36+ return output_filepath , ext
37+ except Exception as e :
38+ print ("Exception during conversion:" + str (e ))
39+ raise e
40+
41+ def transcribe_audio (media_filepath , testing = False ):
42+ if testing :
43+ json_output_path = f"/PythonRpcServer/transcribe_hellohellohello.wav.json"
44+ with open (json_output_path , 'r' ) as json_file :
45+ transcription_result = json .load (json_file )
46+
47+ # Print the transcription result (testing purpose)
48+ print ("Transcription result:" )
49+ print (json .dumps (transcription_result , indent = 4 ))
50+
51+ return transcription_result
52+
53+ if media_filepath == 'TEST-transcribe_example_result' :
54+ result_json_file = 'transcribe_exampleffmp_result.json'
55+ with open (result_json_file , 'r' ) as json_file :
56+ transcription_result = json .load (json_file )
57+ return transcription_result
58+
59+ # Ensure the media file exists
60+ if not os .path .exists (media_filepath ):
61+ raise FileNotFoundError (f"Media file not found: { media_filepath } " )
62+
63+ # convert video to wav if needed
64+ wav_created = False # Track if WAV was created
65+ if not media_filepath .endswith ('.wav' ):
66+ media_filepath , _ = convert_video_to_wav (media_filepath )
67+ wav_created = True # WAV file was created
68+
69+
70+ # Path to the output JSON file that Whisper will generate
71+ json_output_path = f"{ media_filepath } .json"
72+ if os .path .exists (json_output_path ):
73+ os .remove (json_output_path )
74+
75+ # Command to run Whisper.cpp inside the container using the main executable
76+ whisper_command = [
77+ WHISPER_EXECUTABLE , # Path to Whisper executable
78+ '-ojf' , # Output as JSON file
79+ '-f' , media_filepath , # Media file path
80+ '-m' , MODEL
81+ ]
82+
83+ print ("Running Whisper transcription inside the container..." )
84+
85+ # Execute the Whisper command
86+ result = subprocess .run (whisper_command , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
87+
88+ # Handle command failure
89+ if result .returncode != 0 :
90+ raise Exception (f"Whisper failed with error:\n { result .stderr .decode ('utf-8' )} " )
91+
92+ # Check if the output JSON file was generated
93+ print (f"Checking for JSON output at: { json_output_path } " )
94+ if not os .path .exists (json_output_path ):
95+ raise FileNotFoundError (f"Expected JSON output file not found: { json_output_path } " )
96+
97+ # Load the JSON transcription result
98+ with open (json_output_path , 'r' ) as json_file :
99+ transcription_result = json .load (json_file )
100+
101+ # Print the transcription result (testing purpose)
102+ print ("Transcription result:" )
103+ print (json .dumps (transcription_result , indent = 4 ))
104+
105+ # Delete the JSON file after reading it
106+ os .remove (json_output_path )
107+ print (f"Deleted the JSON file: { json_output_path } " )
108+
109+ if wav_created :
110+ try :
111+ os .remove (media_filepath )
112+ print (f"Deleted the WAV file: { media_filepath } " )
113+ except Exception as e :
114+ print (f"Error deleting WAV file: { str (e )} " )
115+
116+ return transcription_result
117+
118+ # Example usage
119+ if __name__ == '__main__' :
120+ # Example media file path inside the container (the actual path will depend on where the file is located)
121+ json_output_path = f"/PythonRpcServer/transcribe_hellohellohello.wav.json"
122+ with open (json_output_path , 'r' ) as json_file :
123+ transcription_result = json .load (json_file )
124+
125+ print ("Transcription Result:" , json .dumps (transcription_result , indent = 4 ))
126+
0 commit comments