vumichien commited on
Commit
14afd56
1 Parent(s): fd86f70

Upload folder using huggingface_hub

Browse files
.idea/.gitignore ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ # Default ignored files
2
+ /shelf/
3
+ /workspace.xml
4
+ # Datasource local storage ignored files
5
+ /dataSources/
6
+ /dataSources.local.xml
7
+ # Editor-based HTTP Client requests
8
+ /httpRequests/
.idea/ai-avatar-backend.iml ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="PYTHON_MODULE" version="4">
3
+ <component name="NewModuleRootManager">
4
+ <content url="file://$MODULE_DIR$" />
5
+ <orderEntry type="jdk" jdkName="Python 3.9 (avatar-ai)" jdkType="Python SDK" />
6
+ <orderEntry type="sourceFolder" forTests="false" />
7
+ </component>
8
+ <component name="TestRunnerService">
9
+ <option name="PROJECT_TEST_RUNNER" value="pytest" />
10
+ </component>
11
+ </module>
.idea/inspectionProfiles/Project_Default.xml ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <component name="InspectionProjectProfileManager">
2
+ <profile version="1.0">
3
+ <option name="myName" value="Project Default" />
4
+ <inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
5
+ <Languages>
6
+ <language minSize="79" name="Python" />
7
+ </Languages>
8
+ </inspection_tool>
9
+ <inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
10
+ <option name="ignoredPackages">
11
+ <value>
12
+ <list size="45">
13
+ <item index="0" class="java.lang.String" itemvalue="beautifulsoup4" />
14
+ <item index="1" class="java.lang.String" itemvalue="bs4" />
15
+ <item index="2" class="java.lang.String" itemvalue="mecab-python3" />
16
+ <item index="3" class="java.lang.String" itemvalue="pydantic" />
17
+ <item index="4" class="java.lang.String" itemvalue="joblib" />
18
+ <item index="5" class="java.lang.String" itemvalue="scikit-learn" />
19
+ <item index="6" class="java.lang.String" itemvalue="torch" />
20
+ <item index="7" class="java.lang.String" itemvalue="numpy" />
21
+ <item index="8" class="java.lang.String" itemvalue="requests" />
22
+ <item index="9" class="java.lang.String" itemvalue="unidic-lite" />
23
+ <item index="10" class="java.lang.String" itemvalue="mysql-connector-python" />
24
+ <item index="11" class="java.lang.String" itemvalue="sqlalchemy" />
25
+ <item index="12" class="java.lang.String" itemvalue="pycaret" />
26
+ <item index="13" class="java.lang.String" itemvalue="tensorflow-text" />
27
+ <item index="14" class="java.lang.String" itemvalue="keybert" />
28
+ <item index="15" class="java.lang.String" itemvalue="pandas" />
29
+ <item index="16" class="java.lang.String" itemvalue="tqdm" />
30
+ <item index="17" class="java.lang.String" itemvalue="fastapi" />
31
+ <item index="18" class="java.lang.String" itemvalue="spacy" />
32
+ <item index="19" class="java.lang.String" itemvalue="regex" />
33
+ <item index="20" class="java.lang.String" itemvalue="tensorflow-hub" />
34
+ <item index="21" class="java.lang.String" itemvalue="uvicorn" />
35
+ <item index="22" class="java.lang.String" itemvalue="xgboost" />
36
+ <item index="23" class="java.lang.String" itemvalue="onnxruntime" />
37
+ <item index="24" class="java.lang.String" itemvalue="av" />
38
+ <item index="25" class="java.lang.String" itemvalue="onnx" />
39
+ <item index="26" class="java.lang.String" itemvalue="opencv-python-headless" />
40
+ <item index="27" class="java.lang.String" itemvalue="streamlit_webrtc" />
41
+ <item index="28" class="java.lang.String" itemvalue="torchvision" />
42
+ <item index="29" class="java.lang.String" itemvalue="cdifflib" />
43
+ <item index="30" class="java.lang.String" itemvalue="protobuf" />
44
+ <item index="31" class="java.lang.String" itemvalue="python-stdnum" />
45
+ <item index="32" class="java.lang.String" itemvalue="transformers" />
46
+ <item index="33" class="java.lang.String" itemvalue="nltk" />
47
+ <item index="34" class="java.lang.String" itemvalue="sentence-transformers" />
48
+ <item index="35" class="java.lang.String" itemvalue="datasets" />
49
+ <item index="36" class="java.lang.String" itemvalue="fsspec" />
50
+ <item index="37" class="java.lang.String" itemvalue="neuralcoref" />
51
+ <item index="38" class="java.lang.String" itemvalue="dateparse" />
52
+ <item index="39" class="java.lang.String" itemvalue="faker" />
53
+ <item index="40" class="java.lang.String" itemvalue="sentencepiece" />
54
+ <item index="41" class="java.lang.String" itemvalue="langid" />
55
+ <item index="42" class="java.lang.String" itemvalue="boto3" />
56
+ <item index="43" class="java.lang.String" itemvalue="redis" />
57
+ <item index="44" class="java.lang.String" itemvalue="celery" />
58
+ </list>
59
+ </value>
60
+ </option>
61
+ </inspection_tool>
62
+ <inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
63
+ <option name="ignoredErrors">
64
+ <list>
65
+ <option value="N801" />
66
+ </list>
67
+ </option>
68
+ </inspection_tool>
69
+ <inspection_tool class="PyTypedDictInspection" enabled="false" level="WARNING" enabled_by_default="false" />
70
+ <inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true">
71
+ <option name="ignoredIdentifiers">
72
+ <list>
73
+ <option value="wbc.assets.templates.template_script.process.pattern_name" />
74
+ </list>
75
+ </option>
76
+ </inspection_tool>
77
+ </profile>
78
+ </component>
.idea/inspectionProfiles/profiles_settings.xml ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ <component name="InspectionProjectProfileManager">
2
+ <settings>
3
+ <option name="USE_PROJECT_PROFILE" value="false" />
4
+ <version value="1.0" />
5
+ </settings>
6
+ </component>
.idea/misc.xml ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9 (avatar-ai)" project-jdk-type="Python SDK" />
4
+ </project>
.idea/modules.xml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/ai-avatar-backend.iml" filepath="$PROJECT_DIR$/.idea/ai-avatar-backend.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
.idea/vcs.xml ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="$PROJECT_DIR$" vcs="Git" />
5
+ </component>
6
+ </project>
.idea/workspace.xml ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ChangeListManager">
4
+ <list default="true" id="74049918-f54d-42f5-ad7d-c4697cbf6820" name="Default Changelist" comment="">
5
+ <change afterPath="$PROJECT_DIR$/Dockerfile" afterDir="false" />
6
+ <change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
7
+ </list>
8
+ <option name="SHOW_DIALOG" value="false" />
9
+ <option name="HIGHLIGHT_CONFLICTS" value="true" />
10
+ <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
11
+ <option name="LAST_RESOLUTION" value="IGNORE" />
12
+ </component>
13
+ <component name="Git.Settings">
14
+ <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
15
+ </component>
16
+ <component name="ProjectId" id="2WCeCg5aWbUXqGVwe1ThKSdE6Li" />
17
+ <component name="ProjectViewState">
18
+ <option name="hideEmptyMiddlePackages" value="true" />
19
+ <option name="showLibraryContents" value="true" />
20
+ </component>
21
+ <component name="PropertiesComponent">
22
+ <property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
23
+ <property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
24
+ <property name="WebServerToolWindowFactoryState" value="false" />
25
+ <property name="last_opened_file_path" value="$PROJECT_DIR$" />
26
+ <property name="nodejs_package_manager_path" value="npm" />
27
+ <property name="settings.editor.selected.configurable" value="com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable" />
28
+ </component>
29
+ <component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
30
+ <component name="TaskManager">
31
+ <task active="true" id="Default" summary="Default task">
32
+ <changelist id="74049918-f54d-42f5-ad7d-c4697cbf6820" name="Default Changelist" comment="" />
33
+ <created>1696240862794</created>
34
+ <option name="number" value="Default" />
35
+ <option name="presentableId" value="Default" />
36
+ <updated>1696240862794</updated>
37
+ <workItem from="1696240864567" duration="150000" />
38
+ </task>
39
+ <servers />
40
+ </component>
41
+ <component name="TypeScriptGeneratedFilesManager">
42
+ <option name="version" value="3" />
43
+ </component>
44
+ <component name="Vcs.Log.Tabs.Properties">
45
+ <option name="TAB_STATES">
46
+ <map>
47
+ <entry key="MAIN">
48
+ <value>
49
+ <State />
50
+ </value>
51
+ </entry>
52
+ </map>
53
+ </option>
54
+ </component>
55
+ </project>
Dockerfile ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM node:16
2
+
3
+ # Set the working directory inside the container
4
+ WORKDIR /usr/src/app
5
+
6
+ # Copy package.json and package-lock.json (if available) to the working directory
7
+ COPY package*.json ./
8
+
9
+ # Install application dependencies
10
+ RUN npm install
11
+
12
+ # Copy the rest of the application to the working directory
13
+ COPY . .
14
+
15
+ # Expose the port the app runs on
16
+ EXPOSE 5000
17
+
18
+ # Command to run the application
19
+ CMD [ "npm", "start" ]
README.md CHANGED
@@ -1,11 +1,19 @@
1
- ---
2
- title: Ai Avatar Backend
3
- emoji: 🏃
4
- colorFrom: yellow
5
- colorTo: blue
6
- sdk: docker
7
- pinned: false
8
- license: apache-2.0
9
- ---
10
-
11
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
1
+ # Talking Avatar backend
2
+ The text to speech and blendShapes converter for https://github.com/bornfree/talking_avatar.
3
+ Uses the [Azure APIs](https://learn.microsoft.com/en-us/azure/cognitive-services/speech-service/how-to-speech-synthesis-viseme) to get stuff done.
4
+
5
+ This is a simple ExpressJS app.
6
+
7
+ ### Get keys from Azure and create a `.env` in the root directory with
8
+ ```
9
+ AZURE_KEY=
10
+ AZURE_REGION=
11
+ ```
12
+
13
+
14
+ ### To run
15
+ ```
16
+ $ npm install
17
+ $ npm start
18
+ ```
19
+
app.js ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var createError = require('http-errors');
2
+ var express = require('express');
3
+ var path = require('path');
4
+ var cookieParser = require('cookie-parser');
5
+ var logger = require('morgan');
6
+ var cors = require('cors');
7
+
8
+ var indexRouter = require('./routes/index');
9
+
10
+ var app = express();
11
+
12
+
13
+ // view engine setup
14
+ app.set('views', path.join(__dirname, 'views'));
15
+ app.set('view engine', 'pug');
16
+
17
+ var corsOptions = {
18
+ origin: '*'
19
+ };
20
+ app.use(cors(corsOptions));
21
+ app.use(logger('dev'));
22
+ app.use(express.json());
23
+ app.use(express.urlencoded({ extended: false }));
24
+ app.use(cookieParser());
25
+ app.use(express.static(path.join(__dirname, 'public')));
26
+
27
+ app.use('/', indexRouter);
28
+
29
+ // catch 404 and forward to error handler
30
+ app.use(function(req, res, next) {
31
+ next(createError(404));
32
+ });
33
+
34
+ // error handler
35
+ app.use(function(err, req, res, next) {
36
+ // set locals, only providing error in development
37
+ res.locals.message = err.message;
38
+ res.locals.error = req.app.get('env') === 'development' ? err : {};
39
+
40
+ // render the error page
41
+ res.status(err.status || 500);
42
+ res.render('error');
43
+ });
44
+
45
+ module.exports = app;
bin/www ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Module dependencies.
5
+ */
6
+
7
+ var app = require('../app');
8
+ var debug = require('debug')('talking-avatar-backend:server');
9
+ var http = require('http');
10
+
11
+ /**
12
+ * Get port from environment and store in Express.
13
+ */
14
+
15
+ var port = normalizePort(process.env.PORT || '5000');
16
+ app.set('port', port);
17
+
18
+ /**
19
+ * Create HTTP server.
20
+ */
21
+
22
+ var server = http.createServer(app);
23
+
24
+ /**
25
+ * Listen on provided port, on all network interfaces.
26
+ */
27
+
28
+ server.listen(port);
29
+ server.on('error', onError);
30
+ server.on('listening', onListening);
31
+
32
+ /**
33
+ * Normalize a port into a number, string, or false.
34
+ */
35
+
36
+ function normalizePort(val) {
37
+ var port = parseInt(val, 10);
38
+
39
+ if (isNaN(port)) {
40
+ // named pipe
41
+ return val;
42
+ }
43
+
44
+ if (port >= 0) {
45
+ // port number
46
+ return port;
47
+ }
48
+
49
+ return false;
50
+ }
51
+
52
+ /**
53
+ * Event listener for HTTP server "error" event.
54
+ */
55
+
56
+ function onError(error) {
57
+ if (error.syscall !== 'listen') {
58
+ throw error;
59
+ }
60
+
61
+ var bind = typeof port === 'string'
62
+ ? 'Pipe ' + port
63
+ : 'Port ' + port;
64
+
65
+ // handle specific listen errors with friendly messages
66
+ switch (error.code) {
67
+ case 'EACCES':
68
+ console.error(bind + ' requires elevated privileges');
69
+ process.exit(1);
70
+ break;
71
+ case 'EADDRINUSE':
72
+ console.error(bind + ' is already in use');
73
+ process.exit(1);
74
+ break;
75
+ default:
76
+ throw error;
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Event listener for HTTP server "listening" event.
82
+ */
83
+
84
+ function onListening() {
85
+ var addr = server.address();
86
+ var bind = typeof addr === 'string'
87
+ ? 'pipe ' + addr
88
+ : 'port ' + addr.port;
89
+ debug('Listening on ' + bind);
90
+ }
helpers/blendshapeNames.js ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ module.exports = ["eyeBlinkLeft",
2
+ "eyeLookDownLeft",
3
+ "eyeLookInLeft",
4
+ "eyeLookOutLeft",
5
+ "eyeLookUpLeft",
6
+ "eyeSquintLeft",
7
+ "eyeWideLeft",
8
+ "eyeBlinkRight",
9
+ "eyeLookDownRight",
10
+ "eyeLookInRight",
11
+ "eyeLookOutRight",
12
+ "eyeLookUpRight",
13
+ "eyeSquintRight",
14
+ "eyeWideRight",
15
+ "jawForward",
16
+ "jawLeft",
17
+ "jawRight",
18
+ "jawOpen",
19
+ "mouthClose",
20
+ "mouthFunnel",
21
+ "mouthPucker",
22
+ "mouthLeft",
23
+ "mouthRight",
24
+ "mouthSmileLeft",
25
+ "mouthSmileRight",
26
+ "mouthFrownLeft",
27
+ "mouthFrownRight",
28
+ "mouthDimpleLeft",
29
+ "mouthDimpleRight",
30
+ "mouthStretchLeft",
31
+ "mouthStretchRight",
32
+ "mouthRollLower",
33
+ "mouthRollUpper",
34
+ "mouthShrugLower",
35
+ "mouthShrugUpper",
36
+ "mouthPressLeft",
37
+ "mouthPressRight",
38
+ "mouthLowerDownLeft",
39
+ "mouthLowerDownRight",
40
+ "mouthUpperUpLeft",
41
+ "mouthUpperUpRight",
42
+ "browDownLeft",
43
+ "browDownRight",
44
+ "browInnerUp",
45
+ "browOuterUpLeft",
46
+ "browOuterUpRight",
47
+ "cheekPuff",
48
+ "cheekSquintLeft",
49
+ "cheekSquintRight",
50
+ "noseSneerLeft",
51
+ "noseSneerRight",
52
+ "tongueOut",
53
+ "headRoll",
54
+ "leftEyeRoll",
55
+ "rightEyeRoll"]
helpers/callOpenAI.js ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const OpenAI = require('openai');
2
+
3
+ const openai = new OpenAI({
4
+ apiKey: process.env.OPENAI_API_KEY, // defaults to process.env["OPENAI_API_KEY"]
5
+ dangerouslyAllowBrowser: true
6
+ });
7
+
8
+ async function queryOpenAIAndSave(userContent) {
9
+ const response = await openai.chat.completions.create({
10
+ model: "gpt-3.5-turbo",
11
+ messages: [
12
+ {"role": "system", "content": "You are a helpful assistant made by Detomo company. Please answer the following questions with maximum 2 sentence. Answer by the language of the question."},
13
+ {"role": "user", "content": userContent},
14
+ ],
15
+ });
16
+
17
+ return response.choices[0].message.content;
18
+ }
19
+
20
+ module.exports = queryOpenAIAndSave;
helpers/tts.js ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // azure-cognitiveservices-speech.js
2
+ require('dotenv').config()
3
+ const sdk = require('microsoft-cognitiveservices-speech-sdk');
4
+ const blendShapeNames = require('./blendshapeNames');
5
+ const _ = require('lodash');
6
+ const voicesMap = {
7
+ 'en-US': 'en-US-AmberNeural',
8
+ 'ja-JP': 'ja-JP-MayuNeural',
9
+ 'vi-VN': 'vi-VN-NamMinhNeural',
10
+ };
11
+
12
+ let SSML = `<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="http://www.w3.org/2001/mstts" xml:lang="en-US">
13
+ <voice name="en-US-JennyNeural">
14
+ <mstts:viseme type="FacialExpression"/>
15
+ __TEXT__
16
+ </voice>
17
+ </speak>`;
18
+
19
+ const key = process.env.AZURE_KEY;
20
+ const region = process.env.AZURE_REGION;
21
+
22
+ /**
23
+ * Node.js server code to convert text to speech
24
+ * @returns stream
25
+ * @param {*} text text to convert to audio/speech
26
+ * @param language
27
+ */
28
+ const textToSpeech = async (text, language)=> {
29
+
30
+ // convert callback function to promise
31
+ return new Promise((resolve, reject) => {
32
+
33
+ const voice = voicesMap[language];
34
+ let ssml = SSML.replace("__TEXT__", text).replace("<voice name=\"en-US-JennyNeural\">", `<voice name="${voice}">`);
35
+
36
+
37
+ const speechConfig = sdk.SpeechConfig.fromSubscription(key, region);
38
+ speechConfig.speechSynthesisOutputFormat = 5; // mp3
39
+
40
+ let audioConfig = null;
41
+
42
+ // if (filename) {
43
+ let randomString = Math.random().toString(36).slice(2, 7);
44
+ let filename = `./public/speech-${randomString}.mp3`;
45
+ audioConfig = sdk.AudioConfig.fromAudioFileOutput(filename);
46
+ // }
47
+
48
+ let blendData = [];
49
+ let timeStep = 1/60;
50
+ let timeStamp = 0;
51
+
52
+ const synthesizer = new sdk.SpeechSynthesizer(speechConfig, audioConfig);
53
+
54
+ // Subscribes to viseme received event
55
+ synthesizer.visemeReceived = function (s, e) {
56
+
57
+ // `Animation` is an xml string for SVG or a json string for blend shapes
58
+ var animation = JSON.parse(e.animation);
59
+
60
+ _.each(animation.BlendShapes, blendArray => {
61
+
62
+ let blend = {};
63
+ _.each(blendShapeNames, (shapeName, i) => {
64
+ blend[shapeName] = blendArray[i];
65
+ });
66
+
67
+ blendData.push({
68
+ time: timeStamp,
69
+ blendshapes: blend
70
+ });
71
+ timeStamp += timeStep;
72
+ });
73
+
74
+ }
75
+
76
+
77
+ synthesizer.speakSsmlAsync(
78
+ ssml,
79
+ result => {
80
+
81
+ synthesizer.close();
82
+ resolve({blendData, filename: `/speech-${randomString}.mp3`});
83
+
84
+ },
85
+ error => {
86
+ synthesizer.close();
87
+ reject(error);
88
+ });
89
+ });
90
+ };
91
+
92
+ module.exports = textToSpeech;
package-lock.json ADDED
The diff for this file is too large to render. See raw diff
 
package.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "talking-avatar-backend",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "start": "nodemon ./bin/www"
7
+ },
8
+ "dependencies": {
9
+ "axios": "^1.5.1",
10
+ "cookie-parser": "~1.4.4",
11
+ "cors": "^2.8.5",
12
+ "debug": "~2.6.9",
13
+ "dotenv": "^16.0.3",
14
+ "express": "^4.18.2",
15
+ "fs": "^0.0.1-security",
16
+ "http-errors": "~1.6.3",
17
+ "lodash": "^4.17.21",
18
+ "microsoft-cognitiveservices-speech-sdk": "^1.23.0",
19
+ "morgan": "~1.9.1",
20
+ "openai": "^4.11.0",
21
+ "pug": "^3.0.2"
22
+ }
23
+ }
public/speech-1rgjg.mp3 ADDED
Binary file (62.5 kB). View file
 
public/speech-41t4z.mp3 ADDED
Binary file (16.1 kB). View file
 
public/speech-72ibm.mp3 ADDED
Binary file (70 kB). View file
 
public/speech-8h55r.mp3 ADDED
Binary file (46.9 kB). View file
 
public/speech-93rz1.mp3 ADDED
Binary file (159 kB). View file
 
public/speech-aqzjq.mp3 ADDED
Binary file (84.4 kB). View file
 
public/speech-dhexe.mp3 ADDED
Binary file (173 kB). View file
 
public/speech-epmmj.mp3 ADDED
Binary file (158 kB). View file
 
public/speech-fzuh9.mp3 ADDED
Binary file (37.4 kB). View file
 
public/speech-g241j.mp3 ADDED
Binary file (36.9 kB). View file
 
public/speech-grdkw.mp3 ADDED
Binary file (37.4 kB). View file
 
public/speech-gsce8.mp3 ADDED
Binary file (62.5 kB). View file
 
public/speech-ide8w.mp3 ADDED
Binary file (17.3 kB). View file
 
public/speech-ir0sf.mp3 ADDED
Binary file (62.5 kB). View file
 
public/speech-jrc8j.mp3 ADDED
Binary file (33.1 kB). View file
 
public/speech-k9whu.mp3 ADDED
Binary file (16.1 kB). View file
 
public/speech-n6nec.mp3 ADDED
Binary file (87.8 kB). View file
 
public/speech-pfhzn.mp3 ADDED
Binary file (16.1 kB). View file
 
public/speech-q0zfc.mp3 ADDED
Binary file (173 kB). View file
 
public/speech-un80i.mp3 ADDED
Binary file (158 kB). View file
 
public/speech-vz8nr.mp3 ADDED
Binary file (173 kB). View file
 
public/speech-vzpdi.mp3 ADDED
Binary file (159 kB). View file
 
public/speech-wd5uf.mp3 ADDED
Binary file (22.2 kB). View file
 
public/speech-xcd5h.mp3 ADDED
Binary file (173 kB). View file
 
public/stylesheets/style.css ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ body {
2
+ padding: 50px;
3
+ font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
4
+ }
5
+
6
+ a {
7
+ color: #00B7FF;
8
+ }
routes/index.js ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var express = require('express');
2
+ var router = express.Router();
3
+ var textToSpeech = require('../helpers/tts');
4
+ var callOpenAI = require('../helpers/callOpenAI'); // Import the helper function
5
+
6
+ router.post('/talk', async function(req, res, next) {
7
+ try {
8
+ const ttsResult = await textToSpeech(req.body.text, req.body.language);
9
+ res.json(ttsResult);
10
+
11
+ } catch (err) {
12
+ res.status(500).json({ error: err.message });
13
+ }
14
+ });
15
+
16
+ router.post('/chat', async function(req, res, next) {
17
+ try {
18
+ const userContent = req.body.text;
19
+ const openAIResponse = await callOpenAI(userContent);
20
+
21
+ res.json({ response: openAIResponse });
22
+ } catch (err) {
23
+ res.status(500).json({ error: err.message });
24
+ }
25
+ });
26
+
27
+ module.exports = router;
views/error.pug ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ extends layout
2
+
3
+ block content
4
+ h1= message
5
+ h2= error.status
6
+ pre #{error.stack}
views/index.pug ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ extends layout
2
+
3
+ block content
4
+ h1= title
5
+ p Welcome to #{title}
views/layout.pug ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ doctype html
2
+ html
3
+ head
4
+ title= title
5
+ link(rel='stylesheet', href='/stylesheets/style.css')
6
+ body
7
+ block content