feat(server): make slide audio transcript parallel (#11692)
This commit is contained in:
@@ -9,6 +9,11 @@ import { CopilotJob } from './common/copilot';
|
|||||||
type CreateCopilotJobInput = Omit<CopilotJob, 'id' | 'status' | 'payload'>;
|
type CreateCopilotJobInput = Omit<CopilotJob, 'id' | 'status' | 'payload'>;
|
||||||
type UpdateCopilotJobInput = Pick<CopilotJob, 'status' | 'payload'>;
|
type UpdateCopilotJobInput = Pick<CopilotJob, 'status' | 'payload'>;
|
||||||
|
|
||||||
|
const FinishedStatus: Set<AiJobStatus> = new Set([
|
||||||
|
AiJobStatus.finished,
|
||||||
|
AiJobStatus.claimed,
|
||||||
|
]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copilot Job Model
|
* Copilot Job Model
|
||||||
*/
|
*/
|
||||||
@@ -90,6 +95,10 @@ export class CopilotJobModel extends BaseModel {
|
|||||||
data: {
|
data: {
|
||||||
status: data.status || undefined,
|
status: data.status || undefined,
|
||||||
payload: data.payload || undefined,
|
payload: data.payload || undefined,
|
||||||
|
finishedAt:
|
||||||
|
data.status && FinishedStatus.has(data.status)
|
||||||
|
? new Date()
|
||||||
|
: undefined,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return ret.count > 0;
|
return ret.count > 0;
|
||||||
|
|||||||
@@ -212,6 +212,28 @@ export class CopilotTranscriptionService {
|
|||||||
return `${hoursStr}:${minutesStr}:${secondsStr}`;
|
return `${hoursStr}:${minutesStr}:${secondsStr}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async callTranscript(url: string, mimeType: string, offset: number) {
|
||||||
|
const result = await this.chatWithPrompt(
|
||||||
|
'Transcript audio',
|
||||||
|
{
|
||||||
|
attachments: [url],
|
||||||
|
params: { mimetype: mimeType },
|
||||||
|
},
|
||||||
|
TranscriptionResponseSchema
|
||||||
|
);
|
||||||
|
|
||||||
|
const transcription = TranscriptionResponseSchema.parse(
|
||||||
|
JSON.parse(result)
|
||||||
|
).map(t => ({
|
||||||
|
speaker: t.a,
|
||||||
|
start: this.convertTime(t.s, offset),
|
||||||
|
end: this.convertTime(t.e, offset),
|
||||||
|
transcription: t.t,
|
||||||
|
}));
|
||||||
|
|
||||||
|
return transcription;
|
||||||
|
}
|
||||||
|
|
||||||
@OnJob('copilot.transcript.submit')
|
@OnJob('copilot.transcript.submit')
|
||||||
async transcriptAudio({
|
async transcriptAudio({
|
||||||
jobId,
|
jobId,
|
||||||
@@ -222,28 +244,11 @@ export class CopilotTranscriptionService {
|
|||||||
}: Jobs['copilot.transcript.submit']) {
|
}: Jobs['copilot.transcript.submit']) {
|
||||||
try {
|
try {
|
||||||
const blobInfos = this.mergeInfos(infos, url, mimeType);
|
const blobInfos = this.mergeInfos(infos, url, mimeType);
|
||||||
const transcriptions = [];
|
const transcriptions = await Promise.all(
|
||||||
for (const [idx, { url, mimeType }] of blobInfos.entries()) {
|
Array.from(blobInfos.entries()).map(([idx, { url, mimeType }]) =>
|
||||||
const result = await this.chatWithPrompt(
|
this.callTranscript(url, mimeType, idx * 10 * 60)
|
||||||
'Transcript audio',
|
)
|
||||||
{
|
);
|
||||||
attachments: [url],
|
|
||||||
params: { mimetype: mimeType },
|
|
||||||
},
|
|
||||||
TranscriptionResponseSchema
|
|
||||||
);
|
|
||||||
|
|
||||||
const offset = idx * 10 * 60;
|
|
||||||
const transcription = TranscriptionResponseSchema.parse(
|
|
||||||
JSON.parse(result)
|
|
||||||
).map(t => ({
|
|
||||||
speaker: t.a,
|
|
||||||
start: this.convertTime(t.s, offset),
|
|
||||||
end: this.convertTime(t.e, offset),
|
|
||||||
transcription: t.t,
|
|
||||||
}));
|
|
||||||
transcriptions.push(transcription);
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.models.copilotJob.update(jobId, {
|
await this.models.copilotJob.update(jobId, {
|
||||||
payload: { transcription: transcriptions.flat() },
|
payload: { transcription: transcriptions.flat() },
|
||||||
|
|||||||
Reference in New Issue
Block a user