mirror of https://github.com/Chocobozzz/PeerTube
chore(test): wip ctranslate 2 adapat
parent
ae8ce3b696
commit
79c12baa9a
|
@ -11,6 +11,7 @@ config.truncateThreshold = 0
|
||||||
describe('Whisper CTranslate2 transcriber', function () {
|
describe('Whisper CTranslate2 transcriber', function () {
|
||||||
const transcriptDirectory = join(root(), 'test-transcript')
|
const transcriptDirectory = join(root(), 'test-transcript')
|
||||||
const shortVideoPath = buildAbsoluteFixturePath('video_short.mp4')
|
const shortVideoPath = buildAbsoluteFixturePath('video_short.mp4')
|
||||||
|
const frVideoPath = buildAbsoluteFixturePath('transcription/communiquer-lors-dune-classe-transplantee.mp4')
|
||||||
const transcriber = new Ctranslate2Transcriber(
|
const transcriber = new Ctranslate2Transcriber(
|
||||||
{
|
{
|
||||||
name: 'anyNameShouldBeFineReally',
|
name: 'anyNameShouldBeFineReally',
|
||||||
|
@ -80,6 +81,51 @@ You
|
||||||
`)
|
`)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('May transcribe a media file using a local CTranslate2 model', async function () {
|
||||||
|
const transcript = await transcriber.transcribe(
|
||||||
|
shortVideoPath,
|
||||||
|
{ name: 'myLocalModel', path: buildAbsoluteFixturePath('transcription/tiny-ctranslate2.bin') },
|
||||||
|
'en',
|
||||||
|
'txt'
|
||||||
|
)
|
||||||
|
expect(transcript).to.deep.equals({
|
||||||
|
path: join(transcriptDirectory, 'video_short.txt'),
|
||||||
|
language: 'en',
|
||||||
|
format: 'txt'
|
||||||
|
})
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
||||||
|
expect(existsSync(transcript.path), `Transcript file ${transcript.path} doesn't exist.`).to.be.true
|
||||||
|
expect(await readFile(transcript.path, 'utf8')).to.equal(`You
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('May transcribe a media file in french', async function () {
|
||||||
|
this.timeout(45000)
|
||||||
|
const transcript = await transcriber.transcribe(frVideoPath, { name: 'tiny' }, 'fr', 'txt')
|
||||||
|
expect(transcript).to.deep.equals({
|
||||||
|
path: join(transcriptDirectory, 'communiquer-lors-dune-classe-transplantee.txt'),
|
||||||
|
language: 'fr',
|
||||||
|
format: 'txt'
|
||||||
|
})
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
||||||
|
expect(existsSync(transcript.path), `Transcript file ${transcript.path} doesn't exist.`).to.be.true
|
||||||
|
expect(await readFile(transcript.path, 'utf8')).to.equal(
|
||||||
|
`Communiquez lors d'une classe transplante. Utilisez les photos prises lors de cette classe pour raconter quotidiennement le séjour vécu.
|
||||||
|
C'est le scénario P-Dagujic présenté par monsieur Navoli, professeur ainsi que le 3 sur une école alimentaire de Montpellier.
|
||||||
|
La première application a utilisé ce ralame déatec. L'enseignant va alors transférer les différentes photos réalisés lors de la classe transplante.
|
||||||
|
Dans un dossier, spécifique pour que les élèves puissent le retrouver plus facilement. Il téléverse donc ses photos dans le dossier, dans le venté, dans la médiatèque de la classe.
|
||||||
|
Pour terminer, il s'assure que le dossier soit bien ouvert aux utilisateurs afin que tout le monde puisse l'utiliser.
|
||||||
|
Les élèves par la suite utilisera le blog. A partir de leurs nantes, il pourront se loi de parposte rédigeant un article d'un reinté.
|
||||||
|
Ils illustront ses articles à l'aide des photos de que mon numérique mise à n'accélier dans le venté.
|
||||||
|
Pour se faire, il pourront utiliser les diteurs avancés qui les renvèrent directement dans la médiatèque de la classe où il pourront retrouver le dossier créé par leurs enseignants.
|
||||||
|
Une fois leur article terminée, les élèves soumétront se lui-ci au professeur qui pourra soit la noté pour correction ou le public.
|
||||||
|
Ensuite, il pourront lire et commenter ce de leurs camarades ou répondre aux commentaires de la veille.
|
||||||
|
`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
it('Should produce the same transcript text as openai-whisper given the same parameters', async function () {
|
it('Should produce the same transcript text as openai-whisper given the same parameters', async function () {
|
||||||
const transcribeArguments: Parameters<typeof transcriber.transcribe> = [
|
const transcribeArguments: Parameters<typeof transcriber.transcribe> = [
|
||||||
shortVideoPath,
|
shortVideoPath,
|
||||||
|
|
|
@ -1,5 +1,57 @@
|
||||||
import { OpenaiTranscriber } from './openai-transcriber.js'
|
import { OpenaiTranscriber } from './openai-transcriber.js'
|
||||||
|
import { TranscriptionModel } from '../../transcription-model.js'
|
||||||
|
import { Transcript, TranscriptFormat } from '../../transcript.js'
|
||||||
|
import { $ } from 'execa'
|
||||||
|
import { getFileInfo } from '../../file-utils.js'
|
||||||
|
import { join } from 'path'
|
||||||
|
import { copyFile, rm } from 'node:fs/promises'
|
||||||
|
import { dirname, basename } from 'node:path'
|
||||||
|
|
||||||
export class Ctranslate2Transcriber extends OpenaiTranscriber {
|
export class Ctranslate2Transcriber extends OpenaiTranscriber {
|
||||||
|
public static readonly MODEL_FILENAME = 'model.bin'
|
||||||
|
|
||||||
|
async transcribe (
|
||||||
|
mediaFilePath: string,
|
||||||
|
model: TranscriptionModel = { name: 'tiny' },
|
||||||
|
language: string = 'en',
|
||||||
|
format: TranscriptFormat = 'vtt'
|
||||||
|
): Promise<Transcript> {
|
||||||
|
this.createPerformanceMark()
|
||||||
|
// Shall we run the command with `{ shell: true }` to get the same error as in sh ?
|
||||||
|
// ex: ENOENT => Command not found
|
||||||
|
const $$ = $({ verbose: true })
|
||||||
|
const { baseName } = getFileInfo(mediaFilePath)
|
||||||
|
|
||||||
|
let modelFilepath = model.path
|
||||||
|
const shouldCreateModelCopy = (model.path && basename(model.path) !== Ctranslate2Transcriber.MODEL_FILENAME)
|
||||||
|
if (shouldCreateModelCopy) {
|
||||||
|
modelFilepath = join(dirname(model.path), Ctranslate2Transcriber.MODEL_FILENAME)
|
||||||
|
await copyFile(model.path, modelFilepath)
|
||||||
|
}
|
||||||
|
|
||||||
|
const modelArgs = model.path ? [ '--model_directory', dirname(model.path) ] : [ '--model', model.name ]
|
||||||
|
|
||||||
|
await $$`${this.engine.binary} ${[
|
||||||
|
mediaFilePath,
|
||||||
|
...modelArgs,
|
||||||
|
'--output_format',
|
||||||
|
format,
|
||||||
|
'--output_dir',
|
||||||
|
this.transcriptDirectory,
|
||||||
|
'--language',
|
||||||
|
language
|
||||||
|
]}`
|
||||||
|
|
||||||
|
if (shouldCreateModelCopy) {
|
||||||
|
// await rm(modelFilepath)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.measurePerformanceMark()
|
||||||
|
|
||||||
|
return {
|
||||||
|
language,
|
||||||
|
path: join(this.transcriptDirectory, `${baseName}.${format}`),
|
||||||
|
format
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue