app.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. import os
  2. os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
  3. os.environ['TF_ENABLE_ONEDNN_OPTS'] = '0'
  4. import dash
  5. import dash_bootstrap_components as dbc
  6. from dash import html, dcc
  7. from dash.dependencies import Input, Output
  8. from components.navigation import create_navbar
  9. from components.hotwords import HotwordsLayout, ManageHotwordLayout
  10. from components.intents import IntentsLayout
  11. from components.nlp import NLPLayout
  12. from components.voice_detection import VoiceDetectionLayout
  13. from components.tts import TTSLayout
  14. from components.data_source import DataSourceLayout
  15. from components.callbacks import register_callbacks
  16. from flask import send_from_directory, send_file
  17. from utils.file_utils import ensure_directory_exists
  18. from importlib import import_module
  19. from utils.training_interface import TrainerInterface
  20. from utils.file_utils import trainer_classes
  21. # Ensure directories exist
  22. ensure_directory_exists('./static/css/')
  23. ensure_directory_exists('./trainer_scripts/')
  24. def load_trainer_classes():
  25. trainer_dir = './trainer_scripts'
  26. for file in os.listdir(trainer_dir):
  27. if file.endswith('.py'):
  28. module_name = file[:-3]
  29. module = import_module(f'trainer_scripts.{module_name}')
  30. for attr in dir(module):
  31. cls = getattr(module, attr)
  32. if isinstance(cls, type) and issubclass(cls, TrainerInterface) and cls is not TrainerInterface:
  33. trainer_classes[module_name] = cls
  34. load_trainer_classes()
  35. app = dash.Dash(__name__, external_stylesheets=['/static/css/bootstrap.min.css'], suppress_callback_exceptions=True)
  36. app.title = "Trainer"
  37. app.layout = dbc.Container(
  38. [
  39. dcc.Location(id='url', refresh=False),
  40. create_navbar(),
  41. html.Div(id='main-navigation', className='mt-4'),
  42. ],
  43. fluid=True,
  44. )
  45. @app.server.route('/static/<path:path>')
  46. def serve_static(path):
  47. return send_from_directory('static', path)
  48. @app.server.route('/audio/<path:filename>')
  49. def serve_audio(filename: str):
  50. ext = filename.split(".")[-1]
  51. if ext == "png":
  52. return display_image(filename[0:-4], "png")
  53. elif ext == "jpg":
  54. return display_image(filename[0:-4], "jpg")
  55. elif ext == "jpeg":
  56. return display_image(filename[0:-5], "jpg")
  57. else:
  58. return send_from_directory('training', filename)
  59. def display_image(filename, ext):
  60. import matplotlib.pyplot as plt
  61. import numpy as np
  62. import wave
  63. wavefile = f"training/{filename}.wav"
  64. imagefile = f"training/{filename}.{ext}"
  65. if not os.path.exists(imagefile):
  66. print(f"Generate Wave Image: {filename} as {ext} from {wavefile}")
  67. with wave.open(wavefile, 'r') as wav_file:
  68. signal = wav_file.readframes(-1)
  69. signal = np.frombuffer(signal, dtype=np.int16)
  70. channels = [[] for channel in range(wav_file.getnchannels())]
  71. for index, datum in enumerate(signal):
  72. channels[index % len(channels)].append(datum)
  73. fs = wav_file.getframerate()
  74. Time = np.linspace(0, len(signal) / len(channels) / fs, num=int(len(signal) / len(channels)))
  75. plt.figure(figsize=(8, 1))
  76. for channel in channels:
  77. plt.plot(Time, channel)
  78. plt.xlabel("")
  79. plt.ylabel("")
  80. plt.title("")
  81. plt.grid()
  82. plt.tight_layout()
  83. plt.axis('off')
  84. if ext == "png":
  85. plt.savefig(imagefile, format='png', transparent=True, bbox_inches='tight', pad_inches=0)
  86. else:
  87. plt.savefig(imagefile, format='jpg', bbox_inches='tight', pad_inches=0)
  88. plt.close()
  89. if ext == "png":
  90. return send_file(imagefile, mimetype='image/png')
  91. else:
  92. return send_file(imagefile, mimetype='image/jpeg')
  93. @app.callback(Output('main-navigation', 'children'),
  94. [Input('url', 'pathname')])
  95. def display_page(pathname):
  96. if pathname == '/hotwords':
  97. return HotwordsLayout()
  98. elif pathname == '/intents':
  99. return IntentsLayout()
  100. elif pathname == '/nlp':
  101. return NLPLayout()
  102. elif pathname == '/voice_detection':
  103. return VoiceDetectionLayout()
  104. elif pathname == '/tts':
  105. return TTSLayout()
  106. elif pathname == '/data_source':
  107. return DataSourceLayout()
  108. elif pathname and pathname.startswith('/manage_hotword/'):
  109. model_name = pathname.split('/')[-1]
  110. return ManageHotwordLayout(model_name)
  111. else:
  112. return html.H1("Home", className="text-center")
  113. register_callbacks(app)
  114. if __name__ == "__main__":
  115. app.run_server(debug=True)