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
from configparse_wrapper.cpwrap import CFG
audiofiles = []
FTP_DIR = CFG("shareDir")
def save_audio(filename, base64_string):
global audiofiles
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):
return b"ERROR_FILE_EXISTS"
write_file(orig_filename, decoded)
def saveAudio(filename, data):
'''Save a single Audiofile to disk'''
if os.path.isfile(filename):
raise ValueError("File: {} already exists.".format(filename))
with open(filename,"wb") as f:
f.write(data)
if False:
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")
seg.export(filename,format="wav")
seg.export(FTP_DIR + filename,format="wav")
def saveAudioChain(filename, dataArray):
'''Combine multiple received audio files into one and save it'''
return b"SUCCESS"
def save_audio_chain(file_str_tupels):
completeAudio = None
for fname, base64_string in file_str_tupels:
print("Filename: {}".format(fname))
decoded = None
orig_filename = fname[:-4]+"_orig"
try:
decoded = base64.b64decode(base64_string)
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:
completeAudio += AudioSegment.from_file(orig_filename)
for index, data in enumerate(dataArray):
tmpFile = "{}.{}.tmp".format(filename, index)
with open(filename, "wb") as f:
f.write(data)
if not completeAudio:
return b"ERROR_AUDIO_CONCAT_FAILED"
completeAudio = AudioSegment.from_file(tmpFile)
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"
completeAudio += AudioSegment.from_file(tmpFile)
def save_transcript(filename, transcript):
global audiofiles
try:
audiofiles.remove(filename[:4])
except:
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:
completeAudio = completeAudio.resample(sample_rate_Hz=32000, sample_width=2, channels=1)
completeAudio.export("{}.wav".format(filename), format="wav")
def saveTranscript(filename, transcript):
with open("{}_transcript.txt".format(filename), "w") as f:
f.write(transcript)
def get_transcript(filename):
global audiofiles
try:
with open("data/" + filename + ".wav_transcript","r") as f:
with open("{}_transcript.txt".format(filename), "r") as f:
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 os.path
import filesystem
import log
import transcribe_async
import os
import transcribe
USE_FREE=False
USE_PAID=True
def async_create_transcript(filename):
print("Creating transcript..")
mp.Process(target=create_and_save_transcript,args=(filename,)).start()
def asyncCreateTranscript(filename):
mp.Process(target=createAndSaveTranscript, args=(filename,)).start()
def create_and_save_transcript(filename):
transcript = analyse(filename)
filesystem.save_transcript(filename, transcript)
#os.system("../permissions.sh")
def analyse(filename):
''' returns the transcripted audio, or None if the analysis fails '''
def createAndSaveTranscript(filename):
if no hasTranscript(filename):
try:
if USE_FREE:
recognizer = spr.Recognizer()
with spr.AudioFile(filename) as source:
audio = recognizer.record(source)
string = free_google_backend(recognizer, audio)
elif USE_PAID:
string = paid_google_backend(filename)
string = transcribe.transcribeFile(filename)
except spr.UnknownValueError:
log.log("Audio file is broken or not an audio file")
return "ERROR_AUDIO_FILE_INVALID"
log.log("Audio file is broken or not an audio file.")
raise e
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)
raise e
filesystem.saveTranscript(filename, string)