fix(whisper): acepta la transcripción en texto plano y permite descargarla
El servicio devolvía la transcripción correcta y la reportábamos como
error: "respuesta inesperada del servicio de transcripción: <la
transcripción completa>". La causa es que mandábamos response_format=json,
que es la convención de la API de OpenAI — whisper-asr-webservice usa el
query param `output`, así que ignoró el campo y respondió en su formato
por defecto (txt), y el parser exigía JSON.
- textoDeRespuestaWhisper acepta las dos formas (JSON {"text":...} o texto
pelado) en vez de adivinar qué variante corre del otro lado. Con test:
8 casos, incluidos JSON sin campo text y un texto que empieza con "{".
- Whisper y OCR: la caja de resultado ahora muestra el conteo de
caracteres, scrollea si es largo, y tiene Copiar y Descargar .txt (Blob
+ <a download>, el texto ya está en el navegador).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
7146539f86
commit
6817ad1e6c
@@ -45,7 +45,16 @@
|
||||
<label class="label">Imagen</label>
|
||||
<input type="file" accept="image/*" @change="archivo=$event.target.files[0]" class="input-field w-full">
|
||||
<p x-show="testError" x-text="testError" class="text-red-500 text-sm mt-3"></p>
|
||||
<div x-show="testText" class="bg-slate-50 border border-slate-200 rounded-lg p-3 mt-3 text-sm text-slate-700 whitespace-pre-wrap" x-text="testText"></div>
|
||||
<div x-show="testText" class="mt-3">
|
||||
<div class="flex items-center justify-between mb-1">
|
||||
<span class="text-xs text-slate-500" x-text="testText.length + ' caracteres'"></span>
|
||||
<div class="flex gap-2">
|
||||
<button type="button" @click="copiar()" class="text-xs text-slate-500 hover:text-slate-700 underline" x-text="copiado?'Copiado':'Copiar'"></button>
|
||||
<button type="button" @click="descargarTxt()" class="text-xs text-slate-500 hover:text-slate-700 underline">Descargar .txt</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-slate-50 border border-slate-200 rounded-lg p-3 text-sm text-slate-700 whitespace-pre-wrap max-h-80 overflow-y-auto" x-text="testText"></div>
|
||||
</div>
|
||||
<div class="flex justify-end mt-4">
|
||||
<button type="submit" :disabled="testing || !archivo" class="btn-primary" x-text="testing?'Extrayendo...':'Extraer texto'"></button>
|
||||
</div>
|
||||
@@ -59,7 +68,7 @@ function ocrApp() {
|
||||
return {
|
||||
form:{ base_url:'', token:'', notas:'' },
|
||||
showToken:false, saving:false, error:'', saved:false,
|
||||
archivo:null, testing:false, testError:'', testText:'',
|
||||
archivo:null, testing:false, testError:'', testText:'', copiado:false,
|
||||
|
||||
async init(){ await this.loadConfig(); },
|
||||
|
||||
@@ -82,6 +91,20 @@ function ocrApp() {
|
||||
finally{ this.saving=false; }
|
||||
},
|
||||
|
||||
copiar(){
|
||||
navigator.clipboard.writeText(this.testText);
|
||||
this.copiado=true; setTimeout(()=>this.copiado=false, 2000);
|
||||
},
|
||||
|
||||
descargarTxt(){
|
||||
const base=(this.archivo?.name||'texto-extraido').replace(/\.[^.]+$/, '');
|
||||
const url=URL.createObjectURL(new Blob([this.testText], {type:'text/plain;charset=utf-8'}));
|
||||
const a=document.createElement('a');
|
||||
a.href=url; a.download=base+'.txt';
|
||||
document.body.appendChild(a); a.click(); a.remove();
|
||||
URL.revokeObjectURL(url);
|
||||
},
|
||||
|
||||
async test(){
|
||||
if(!this.archivo) return;
|
||||
this.testing=true; this.testError=''; this.testText='';
|
||||
|
||||
@@ -49,7 +49,16 @@
|
||||
<label class="label">Audio</label>
|
||||
<input type="file" accept="audio/*" @change="archivo=$event.target.files[0]" class="input-field w-full">
|
||||
<p x-show="testError" x-text="testError" class="text-red-500 text-sm mt-3"></p>
|
||||
<div x-show="testText" class="bg-slate-50 border border-slate-200 rounded-lg p-3 mt-3 text-sm text-slate-700 whitespace-pre-wrap" x-text="testText"></div>
|
||||
<div x-show="testText" class="mt-3">
|
||||
<div class="flex items-center justify-between mb-1">
|
||||
<span class="text-xs text-slate-500" x-text="testText.length + ' caracteres'"></span>
|
||||
<div class="flex gap-2">
|
||||
<button type="button" @click="copiar()" class="text-xs text-slate-500 hover:text-slate-700 underline" x-text="copiado?'Copiado':'Copiar'"></button>
|
||||
<button type="button" @click="descargarTxt()" class="text-xs text-slate-500 hover:text-slate-700 underline">Descargar .txt</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-slate-50 border border-slate-200 rounded-lg p-3 text-sm text-slate-700 whitespace-pre-wrap max-h-80 overflow-y-auto" x-text="testText"></div>
|
||||
</div>
|
||||
<div class="flex justify-end mt-4">
|
||||
<button type="submit" :disabled="testing || !archivo" class="btn-primary" x-text="testing?'Transcribiendo...':'Transcribir'"></button>
|
||||
</div>
|
||||
@@ -63,7 +72,7 @@ function whisperAsrApp() {
|
||||
return {
|
||||
form:{ base_url:'', username:'', password:'', notas:'' },
|
||||
showPass:false, saving:false, error:'', saved:false,
|
||||
archivo:null, testing:false, testError:'', testText:'',
|
||||
archivo:null, testing:false, testError:'', testText:'', copiado:false,
|
||||
|
||||
async init(){ await this.loadConfig(); },
|
||||
|
||||
@@ -86,6 +95,22 @@ function whisperAsrApp() {
|
||||
finally{ this.saving=false; }
|
||||
},
|
||||
|
||||
copiar(){
|
||||
navigator.clipboard.writeText(this.testText);
|
||||
this.copiado=true; setTimeout(()=>this.copiado=false, 2000);
|
||||
},
|
||||
|
||||
// Blob + <a download>: no hace falta que el servidor sirva el archivo,
|
||||
// el texto ya está en el navegador.
|
||||
descargarTxt(){
|
||||
const base=(this.archivo?.name||'transcripcion').replace(/\.[^.]+$/, '');
|
||||
const url=URL.createObjectURL(new Blob([this.testText], {type:'text/plain;charset=utf-8'}));
|
||||
const a=document.createElement('a');
|
||||
a.href=url; a.download=base+'.txt';
|
||||
document.body.appendChild(a); a.click(); a.remove();
|
||||
URL.revokeObjectURL(url);
|
||||
},
|
||||
|
||||
async test(){
|
||||
if(!this.archivo) return;
|
||||
this.testing=true; this.testError=''; this.testText='';
|
||||
|
||||
Reference in New Issue
Block a user