Skip to content

Commit 6ae9883

Browse files
Merge pull request #53 from makeiteasierapps/pscript-bug
Pscript bug
2 parents d30de98 + 0dc51f8 commit 6ae9883

File tree

4 files changed

+113
-89
lines changed

4 files changed

+113
-89
lines changed

.gitignore

+3-1
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,6 @@ _site/
6666

6767
# Ignore folders generated by Bundler
6868
.bundle/
69-
vendor/
69+
vendor/
70+
71+
venv/

docs/guides/use_python_recorder.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ Here's a brief overview of the script's parameters:
6969
-u: --base-url(required): The URL to which the recordings are sent.
7070
-t: --token(required): API token for server authentication.
7171
-s: --seconds: Duration of recording segments in seconds (default: 30).
72-
-m: --sensitivity: Microphone sensitivity threshold (0.0 to 100.0, default: 35.0). Set to 0 for continuous recording.
72+
-m: --sensitivity: Microphone sensitivity threshold (0.0 to 100.0, default: 0). Set to 0 for continuous recording.
7373
-l: --save: Save recordings locally.
7474
-v: --verbose: Enable verbose output for debugging.
7575
```
@@ -91,5 +91,5 @@ And that is it, you should now be able to record things locally, and test the fr
9191
#### **Important Notes**
9292

9393
- Ensure your base_url and token are correct to successfully send recordings.
94-
- Adjust the sensitivity to your microphone setup to avoid missing recordings or record silance.
94+
- Adjust the sensitivity to your microphone setup to avoid missing recordings or record silance. Too high will make the audio unable to be transcribed.
9595
- Use the save option if you want to keep local copies of the recordings (file names "recording{timestamp}.wav").

scripts/python_recorder_client/main.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
help="API token for authentication with the server.")
2222
parser.add_argument('-s', '--seconds', type=int, default=30,
2323
help="Duration of each recording segment in seconds. (default 30)")
24-
parser.add_argument('-m', '--sensitivity', type=float, default=35.0,
25-
help="Microphone sensitivity threshold (0.0 to 100.0, default: 35.0).")
24+
parser.add_argument('-m', '--sensitivity', type=float, default=0.0,
25+
help="Microphone sensitivity threshold (0.0 to 100.0, default: 0).")
2626
parser.add_argument('-l', '--save', action='store_true', help="Save recordings locally.")
2727
parser.add_argument('-v', '--verbose', action='store_true',
2828
help="Enable verbose output for debugging.")
@@ -69,7 +69,6 @@ def get_base_url():
6969

7070
def store_sound(frames):
7171
logger.debug('Store and sending wav.')
72-
# Save the recorded data as a WAV file
7372
filename = get_wav_filename()
7473
wf = wave.open(filename, 'wb')
7574
wf.setnchannels(CHANNELS)
@@ -78,11 +77,12 @@ def store_sound(frames):
7877
wf.writeframes(b''.join(frames))
7978
wf.close()
8079

81-
files = {'file': open(filename, 'rb')}
82-
response = requests.post(f'{get_base_url()}/functions/v1/process-audio', files=files, headers={
83-
'apikey': args.token,
84-
'Content-Type': 'audio/wav,',
85-
})
80+
with open(filename, 'rb') as f:
81+
files = {'file': (filename, f, 'audio/wav')}
82+
response = requests.post(f'{get_base_url()}/functions/v1/process-audio', files=files, headers={
83+
'Authorization': f'Bearer {args.token}',
84+
'apikey': args.token,
85+
}, timeout=540)
8686
logger.info(response.text)
8787

8888

+100-78
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,119 @@
1-
import { serve } from "https://deno.land/[email protected]/http/server.ts";
2-
import OpenAI, { toFile } from "https://deno.land/x/[email protected]/mod.ts";
1+
import { serve } from 'https://deno.land/std/http/server.ts';
2+
import { multiParser } from 'https://deno.land/x/[email protected]/mod.ts';
3+
import OpenAI, { toFile } from 'https://deno.land/x/[email protected]/mod.ts';
34

4-
import { corsHeaders } from "../common/cors.ts";
5-
import { supabaseClient } from "../common/supabaseClient.ts";
5+
import { corsHeaders } from '../common/cors.ts';
6+
import { supabaseClient } from '../common/supabaseClient.ts';
67

78
const processAudio = async (req: Request) => {
8-
9-
if (req.method !== "POST") {
10-
return new Response("Method Not Allowed", { status: 405 });
11-
}
9+
if (req.method !== 'POST') {
10+
return new Response('Method Not Allowed', { status: 405 });
11+
}
1212

13-
const supabase = supabaseClient(req);
14-
const openaiClient = new OpenAI({
15-
apiKey: Deno.env.get("OPENAI_API_KEY"),
16-
});
13+
const supabase = supabaseClient(req);
14+
const openaiClient = new OpenAI({
15+
apiKey: Deno.env.get('OPENAI_API_KEY'),
16+
});
1717

18-
// Validate Content-Type
19-
const contentType = req.headers.get("Content-Type") || "";
20-
if (!contentType.includes("audio/wav") && !contentType.includes("audio/x-wav")) {
21-
return new Response("Unsupported Media Type", { status: 415 });
22-
}
18+
const contentType = req.headers.get('Content-Type') || '';
19+
let arrayBuffer: ArrayBuffer;
20+
let filenameTimestamp = `audio_${Date.now()}.wav`;
2321

24-
const arrayBuffer = await req.arrayBuffer();
22+
if (contentType.includes('multipart/form-data')) {
23+
const form = await multiParser(req);
24+
if (!form || !form.files || !form.files.file) {
25+
return new Response('File not found in form', {
26+
status: 400,
27+
headers: corsHeaders,
28+
});
29+
}
30+
console.log('Form:', form);
31+
const file = form.files.file;
32+
arrayBuffer = file.content.buffer;
33+
filenameTimestamp = file.filename || filenameTimestamp;
34+
} else {
35+
arrayBuffer = await req.arrayBuffer();
36+
}
2537

26-
let transcript: string;
27-
let embeddings: any;
28-
try {
29-
const filenameTimestamp = `adeus_wav_${Date.now()}.wav`;
30-
const wavFile = await toFile(arrayBuffer, filenameTimestamp);
38+
let transcript: string;
39+
let embeddings: any;
40+
try {
41+
const filenameTimestamp = `adeus_wav_${Date.now()}.wav`;
42+
const wavFile = await toFile(arrayBuffer, filenameTimestamp);
43+
console.log(typeof wavFile, wavFile);
3144

32-
// const { data, error } = await supabase.storage
33-
// .from("test")
34-
// .upload(filenameTimestamp, wavFile);
45+
// const { data, error } = await supabase.storage
46+
// .from("test")
47+
// .upload(filenameTimestamp, wavFile);
3548

36-
// if (error) {
37-
// console.error("Error uploading file:", error);
38-
// }
49+
// if (error) {
50+
// console.error("Error uploading file:", error);
51+
// }
3952

40-
const transcriptResponse = await openaiClient.audio.transcriptions.create({
41-
file: await toFile(wavFile, filenameTimestamp),
42-
model: "whisper-1",
43-
prompt:
44-
'If this audio file does not contain any speech, please return "None"',
45-
});
46-
transcript = transcriptResponse.text;
47-
let transcriptLowered = transcript.toLowerCase();
48-
// ("thank" in transcriptLowered &&
49-
// "watch" in transcriptLowered &&
50-
// "video" in transcriptLowered)
51-
if (
52-
transcript == "None" ||
53-
transcript == "" ||
54-
transcript == null ||
55-
(transcriptLowered.includes("thank") &&
56-
transcriptLowered.includes("watch"))
57-
) {
58-
return new Response(JSON.stringify({ message: "No transcript found." }), {
59-
headers: { ...corsHeaders, "Content-Type": "application/json" },
60-
status: 200,
61-
});
62-
}
53+
const transcriptResponse =
54+
await openaiClient.audio.transcriptions.create({
55+
file: wavFile,
56+
model: 'whisper-1',
57+
prompt: 'If this audio file does not contain any speech, please return "None"',
58+
});
59+
transcript = transcriptResponse.text;
60+
let transcriptLowered = transcript.toLowerCase();
61+
// ("thank" in transcriptLowered &&
62+
// "watch" in transcriptLowered &&
63+
// "video" in transcriptLowered)
64+
if (
65+
transcript == 'None' ||
66+
transcript == '' ||
67+
transcript == null ||
68+
(transcriptLowered.includes('thank') &&
69+
transcriptLowered.includes('watch'))
70+
) {
71+
return new Response(
72+
JSON.stringify({ message: 'No transcript found.' }),
73+
{
74+
headers: {
75+
...corsHeaders,
76+
'Content-Type': 'application/json',
77+
},
78+
status: 200,
79+
}
80+
);
81+
}
6382

64-
console.log("Transcript:", transcript);
83+
console.log('Transcript:', transcript);
6584

66-
const embeddingsResponse = await openaiClient.embeddings.create({
67-
model: "text-embedding-ada-002",
68-
input: transcript.replace(/\n/g, " ").replace(/\s{2,}/g, " "),
69-
});
70-
embeddings = embeddingsResponse.data[0].embedding;
71-
console.log("Embeddings:", embeddings);
85+
const embeddingsResponse = await openaiClient.embeddings.create({
86+
model: 'text-embedding-ada-002',
87+
input: transcript.replace(/\n/g, ' ').replace(/\s{2,}/g, ' '),
88+
});
89+
embeddings = embeddingsResponse.data[0].embedding;
90+
console.log('Embeddings:', embeddings);
7291

73-
const { data, error } = await supabase
74-
.from("records")
75-
.insert({ raw_text: transcript, embeddings: embeddings });
92+
const { data, error } = await supabase
93+
.from('records')
94+
.insert({ raw_text: transcript, embeddings: embeddings });
7695

77-
if (error) {
78-
console.error("Error inserting record:", error);
96+
if (error) {
97+
console.error('Error inserting record:', error);
98+
}
99+
} catch (error) {
100+
console.error('Transcription error:', error);
101+
return new Response(JSON.stringify({ error: error.message }), {
102+
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
103+
status: 500,
104+
});
79105
}
80-
} catch (error) {
81-
console.error("Transcription error:", error);
82-
return new Response(JSON.stringify({ error: error.message }), {
83-
headers: { ...corsHeaders, "Content-Type": "application/json" },
84-
status: 500,
85-
});
86-
}
87106

88-
return new Response(
89-
JSON.stringify({ message: "Audio transcribed successfully.", transcript }),
90-
{
91-
headers: { ...corsHeaders, "Content-Type": "application/json" },
92-
status: 200,
93-
}
94-
);
107+
return new Response(
108+
JSON.stringify({
109+
message: 'Audio transcribed successfully.',
110+
transcript,
111+
}),
112+
{
113+
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
114+
status: 200,
115+
}
116+
);
95117
};
96118

97119
serve(processAudio);

0 commit comments

Comments
 (0)