This commit is contained in:
Yannik Schmidt
2020-02-09 02:17:26 +01:00
parent aaf88a35ef
commit fe3d6cadc6
6 changed files with 85 additions and 262 deletions

View File

@@ -1,45 +0,0 @@
#!/usr/bin/python3
import socketserver
import server_interface
from configparse_wrapper.cpwrap import CFG, parse_config, change_cfg
class AppRequestHandler(socketserver.BaseRequestHandler):
def __init__(self, request, client_address, server):
socketserver.BaseRequestHandler.__init__(self, request, client_address, server)
return
def setup(self):
return socketserver.BaseRequestHandler.setup(self)
def handle(self):
data = b""
print("Recieved request")
while True:
tmp = self.request.recv(1024)
if not tmp or b"\nterminate\n" in tmp:
if len(tmp) > len("\nterminate\n"):
data += tmp[:-len("\nterminate\n")]
break
data += tmp
retval = server_interface.parse_request(data)
try:
self.request.send(retval)
self.request.send(b"terminate\n")
print("Replied with: {}".format(retval))
except BrokenPipeError:
print("Connection was closed before reply could be sent.")
return
def finish(self):
return socketserver.BaseRequestHandler.finish(self)
def start_server():
socketserver.TCPServer.allow_reuse_address = True
server = socketserver.TCPServer((CFG("interface"),CFG("port")),AppRequestHandler)
server.serve_forever()
if __name__ == "__main__":
parse_config()
start_server()

View File

@@ -3,89 +3,42 @@ import os.path
import audiosegment_wrapper as AudioSegment import audiosegment_wrapper as AudioSegment
from configparse_wrapper.cpwrap import CFG from configparse_wrapper.cpwrap import CFG
audiofiles = []
FTP_DIR = CFG("shareDir") FTP_DIR = CFG("shareDir")
def save_audio(filename, base64_string): def saveAudio(filename, data):
global audiofiles '''Save a single Audiofile to disk'''
audiofiles += [filename[:-4]]
decoded = None
orig_filename = filename[:-4]+"_orig"
try:
decoded = base64.b64decode(base64_string)
except TypeError:
return b"ERROR_INVALID_ENCODING_64"
if os.path.isfile(filename): if os.path.isfile(filename):
return b"ERROR_FILE_EXISTS" raise ValueError("File: {} already exists.".format(filename))
write_file(orig_filename, decoded)
seg = AudioSegment.from_file(orig_filename) with open(filename,"wb") as f:
seg = seg.resample(sample_rate_Hz=32000, sample_width=2, channels=1) f.write(data)
seg.export(filename,format="wav") if False:
seg.export(FTP_DIR + filename,format="wav") seg = AudioSegment.from_file(orig_filename)
seg = seg.resample(sample_rate_Hz=32000, sample_width=2, channels=1)
seg.export("{}.wav".format(filename), format="wav")
return b"SUCCESS" def saveAudioChain(filename, dataArray):
'''Combine multiple received audio files into one and save it'''
def save_audio_chain(file_str_tupels):
completeAudio = None completeAudio = None
for fname, base64_string in file_str_tupels: for index, data in enumerate(dataArray):
print("Filename: {}".format(fname)) tmpFile = "{}.{}.tmp".format(filename, index)
decoded = None with open(filename, "wb") as f:
orig_filename = fname[:-4]+"_orig" f.write(data)
try: if not completeAudio:
decoded = base64.b64decode(base64_string) completeAudio = AudioSegment.from_file(tmpFile)
except TypeError:
return b"ERROR_INVALID_ENCODING_64"
with open(orig_filename,"wb") as f:
f.write(decoded)
if completeAudio == None:
completeAudio = AudioSegment.from_file(orig_filename)
else: else:
completeAudio += AudioSegment.from_file(orig_filename) completeAudio += AudioSegment.from_file(tmpFile)
if not completeAudio:
return b"ERROR_AUDIO_CONCAT_FAILED"
else:
completeAudio = completeAudio.resample(sample_rate_Hz=32000, sample_width=2, channels=1)
completeAudio.export(file_str_tupels[0][0],format="wav")
completeAudio.export(FTP_DIR + file_str_tupels[0][0],format="wav")
return b"SUCCESS"
def save_transcript(filename, transcript): completeAudio = completeAudio.resample(sample_rate_Hz=32000, sample_width=2, channels=1)
global audiofiles completeAudio.export("{}.wav".format(filename), format="wav")
try:
audiofiles.remove(filename[:4]) def saveTranscript(filename, transcript):
except: with open("{}_transcript.txt".format(filename), "w") as f:
print("Audiofile not in working list")
if os.path.isfile(filename):
pass
with open(filename + "_transcript","w") as f:
f.write(transcript)
with open(FTP_DIR + filename + "_transcript","w") as f:
f.write(transcript) f.write(transcript)
def get_transcript(filename): def get_transcript(filename):
global audiofiles with open("{}_transcript.txt".format(filename), "r") as f:
try:
with open("data/" + filename + ".wav_transcript","r") as f:
return f.read() return f.read()
except FileNotFoundError:
if filename in audiofiles:
return "ERROR_FILE_STILL_IN_WORK"
return "ERROR_FILE_NOT_AVAILIABLE"
def filelist():
return ""
def fileinfo(filename):
return ""
def copy_to_output(filename):
return ""
def write_file(filename, data):
global FTP_DIR
with open(FTP_DIR + filename,"wb") as f:
f.write(data)
with open(filename,"wb") as f:
f.write(data)

46
python-server/server.py Executable file
View File

@@ -0,0 +1,46 @@
#!/usr/bin/python3
import flask
@app.route('/submit')
def transferToServer():
# TODO receive data
data = None
decoded = decoded = base64.b64decode(data)
filesystem.saveAudio(filename, data)
return "", 204
@app.route('/submit-chain')
def transferToServerChain():
# TODO receive data
data = []
dataDecoded = [ base64.b64decode(d) for d in data ]
filesystem.saveAudioChain(filename, dataDecoded)
return "", 204
@app.route('/transcript')
def queryTranscript():
filename = flask.request.args.filename
transcript = filesystem.getTranscript(filename)
return transcript
@app.route('/fileinfo')
def singleFileInfo():
filename = flask.request.args.filename
return filesystem.fileinfo(filename)
@app.route('/filelist')
def getMultiFileInfo():
return filesystem.filelist()
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Start speech app server', \
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('--interface', default="localhost", \
help='Interface on which flask (this server) will take requests on')
parser.add_argument('--port', default="5002", \
help='Port on which flask (this server) will take requests on')
args = parser.parse_args()
app.run(host=args.interface, port=args.port)

View File

@@ -1,111 +0,0 @@
import speech
import filesystem
from configparse_wrapper.cpwrap import CFG
MAIN_DIR = bytes(CFG("mainDataDir"),CFG("encoding"))
def parse_request(data):
''' parse request and call correct function '''
#return b"DUMMY"
print(data.split(b",")[0])
# echo/test connection #
cleared_data = is_data_type(b"ECHOREQUEST,",data)
if cleared_data:
return cleared_data
# reply transcript #
cleared_data = is_data_type(b"GET_TRANSCRIPT,",data)
if cleared_data:
filename = cleared_data.decode("utf-8")
return filesystem.get_transcript(filename).encode("utf-8")
# get single file info #
cleared_data = is_data_type(b"GET_FILEINFO,",data)
if cleared_data:
filename = data.decode("utf-8")
return filesystem.fileinfo(filename).encode("utf-8")
# get single file info #
cleared_data = is_data_type(b"GET_FILEINFO_ALL,",data)
if cleared_data:
return filesystem.filelist().encode("utf-8")
# handle audio transmission #
cleared_data = is_data_type(b"AUDIO_TRANSMISSION,",data)
if cleared_data:
print("Handling audio transmission")
filename = None
try:
filename, base64_string = cleared_data.split(b',')
filename = MAIN_DIR + filename.split(b"/")[-1] + b".wav"
filename = filename.decode("utf-8")
except ValueError:
return b"ERROR_MALFORMED_REQUEST"
ret = filesystem.save_audio(filename, base64_string)
if b"ERROR" in ret:
return ret
speech.async_create_transcript(filename)
return ret
# handle a chain of audiotransmissions #
if data.startswith(b"CHAIN_AUDIO_TRANSMISSION"):
file_str_tuples = []
arr = data.split(b"|")
for el in arr[1:-1]:
filename, base64_string = el.split(b',')
filename = MAIN_DIR + filename.split(b"/")[-1] + b".wav"
filename = filename.decode("utf-8")
file_str_tuples += [(filename,base64_string)]
if len(file_str_tuples) < 2: # a chain has 2 or more elements
return bytes("ERROR_INVALID_NUMBER_FILES_{}".format(len(file_str_tuples)),"utf-8")
ret = filesystem.save_audio_chain(file_str_tuples);
if b"ERROR" in ret:
return ret
speech.async_create_transcript(file_str_tuples[0][0])
return ret
# other shit
return b"UNRECOGNIZED_SERVER_OPTION\n"
def is_data_type(tag,data):
data = data.strip(b"\n")
if data.startswith(tag):
ret = data.split(tag)[1]
if not ret:
ret = b"NULL\n"
return ret
return None
def reply_logs(loglevel=0,lines=100):
''' replies with recent logs '''
pass
def reply_backend(backend=None):
''' replies with current backend if None or sets the new one '''
pass
def reply_files(after=None, before=None, regex=None):
''' replies with a list of transcribed or to be transcribed files '''
def reply_transcript(filename=None):
''' replies with the latest transcript or the transcript of the chosen name '''
pass
def reply_audio(filename=None):
''' replies with the chosen audio as a file '''
pass
def recive_transcribe_request(audiofile):
''' saves and transcribes and audiofile '''
pass
def android_unittest_transcribe_request(audiofile):
''' the android unittests append a special keyword, requests are dummy handled '''
pass

View File

@@ -1,43 +1,23 @@
import speech_recognition as spr
import multiprocessing as mp import multiprocessing as mp
import os.path import os.path
import filesystem import filesystem
import log import log
import transcribe_async import transcribe
import os
USE_FREE=False USE_FREE=False
USE_PAID=True USE_PAID=True
def async_create_transcript(filename): def asyncCreateTranscript(filename):
print("Creating transcript..") mp.Process(target=createAndSaveTranscript, args=(filename,)).start()
mp.Process(target=create_and_save_transcript,args=(filename,)).start()
def create_and_save_transcript(filename): def createAndSaveTranscript(filename):
transcript = analyse(filename) if no hasTranscript(filename):
filesystem.save_transcript(filename, transcript) try:
#os.system("../permissions.sh") string = transcribe.transcribeFile(filename)
except spr.UnknownValueError:
def analyse(filename): log.log("Audio file is broken or not an audio file.")
''' returns the transcripted audio, or None if the analysis fails ''' raise e
try: except spr.RequestError as e:
if USE_FREE: log.log("Could not connect to google API: {}".format(e))
recognizer = spr.Recognizer() raise e
with spr.AudioFile(filename) as source: filesystem.saveTranscript(filename, string)
audio = recognizer.record(source)
string = free_google_backend(recognizer, audio)
elif USE_PAID:
string = paid_google_backend(filename)
except spr.UnknownValueError:
log.log("Audio file is broken or not an audio file")
return "ERROR_AUDIO_FILE_INVALID"
except spr.RequestError as e:
log.log("Could not connect to google API: {}".format(e))
return "ERROR_API_FAILURE"
return string
def free_google_backend(recognizer, audio):
return recognizer.recognize_google(audio,language="de-DE")
def paid_google_backend(filename):
return transcribe_async.transcribe_file(filename)