Changeset 35250 for main/trunk/model-interfaces-dev/atea
- Timestamp:
- 2021-08-04T15:17:15+12:00 (3 years ago)
- Location:
- main/trunk/model-interfaces-dev/atea
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
main/trunk/model-interfaces-dev/atea/js/asr/TranscribeService.js
r35243 r35250 3 3 * 4 4 * @typedef {Object} TranscriptionModel 5 * @property {String} file_name The name of the file that was transcribed. 6 * @property {String} log A note of how the transcription was processed. 7 * @property {{char: String, start_time: Number}[]} metadata The character metadata. 8 * @property {boolean} success A value indicating if the transcription was successful or not. 5 9 * @property {String} transcription The transcription. 6 * @property {{char: String, start_time: Number}[]} metadata The character metadata.7 * @property {String} file_name The name of the file that was transcribed.8 10 */ 11 12 class TranscribeError 13 { 14 /** 15 * Initialises a new instance of the {@link TranscribeError} object. 16 * 17 * @param {Number | undefined} statusCode The status code of the error. 18 * @param {String | undefined} statusMessage The status message. 19 */ 20 constructor(statusCode, statusMessage) 21 { 22 this.statusCode = statusCode; 23 this.statusMessage = statusMessage; 24 } 25 } 9 26 10 27 /** … … 20 37 21 38 /** 22 * Uploads files to out transcription API using a fetch request.39 * Performs a query to transcribe the given audio files. 23 40 * 24 41 * @param {FileList} files The files to upload. 25 * @returns {Promise<TranscriptionModel >} A promise for an object representation of the JSON response.42 * @returns {Promise<TranscriptionModel[]>} The transcribed aufio file. 26 43 */ 27 async doFetchUpload(files)44 async transcribeFiles(files) 28 45 { 29 46 const that = this; … … 33 50 for (let i = 0; i < files.length; i++) 34 51 { 35 let f = files[i];36 let key = "audioFile" + i;52 const f = files[i]; 53 const key = "audioFile" + i; 37 54 38 55 formData.append(key, f, f.name); … … 41 58 formData.append("audioFileKeys", audioFileKeys); 42 59 43 const response = await fetch 44 ( 45 that.queryUrl, 46 { 47 method: "POST", 48 body: formData 49 } 50 ); 51 52 return response.json(); 53 } 54 55 /** 56 * @callback TranscriptionPromiseCallback 57 * @param {Promise<Response>} promise A fetch promise containing an HTTP response. 58 * @param {String} filename The file that this transcription is for. 59 * @returns {void} 60 */ 61 62 /** 63 * 64 * @param {FileList} files The files to upload 65 * @param {TranscriptionPromiseCallback} callback A callback made with the fetch promise. 66 */ 67 doIndividualFetchUpload(files, callback) 68 { 69 const that = this; 70 71 for (let f of files) 60 let response; 61 try 72 62 { 73 const formData = new FormData(); 74 formData.append("audioFile", f, f.name); 75 formData.append("audioFileKeys", "audioFile"); 76 77 let promise = fetch 63 response = await fetch 78 64 ( 79 65 that.queryUrl, … … 82 68 body: formData 83 69 } 84 ) 85 callback(promise, f.name); 70 ); 86 71 } 72 catch (e) 73 { 74 console.error(`Transcription failed with reason ${e}`); 75 throw new TranscribeError(undefined, undefined); 76 } 77 78 if (!response.ok) 79 { 80 console.error(`Transcription API failed with status ${response.status} and message ${response.statusText}`); 81 throw new TranscribeError(response.status, response.statusText); 82 } 83 84 return await response.json(); 87 85 } 88 86 … … 132 130 // } 133 131 } 134 135 -
main/trunk/model-interfaces-dev/atea/js/asr/asr-controller.js
r35243 r35250 1 1 // The controller for asr.xsl 2 // @ts-nocheck 2 3 3 4 /** … … 24 25 /** 25 26 * Loads a remote script. 26 * https://stackoverflow.com/questions/950087/how-do-i-include-a-javascript-file-in-another-javascript-file27 * Found at https://stackoverflow.com/questions/950087/how-do-i-include-a-javascript-file-in-another-javascript-file 27 28 * 28 29 * @param {string} url The URL from which to load the script. … … 31 32 function loadScript(url, callback = () => {}) 32 33 { 33 // A dding the script tag to the head as suggested before34 var head = document.head;34 // Append the script to the body element 35 var body = document.body; 35 36 var script = document.createElement('script'); 36 37 script.type = 'text/javascript'; 37 38 script.src = url; 38 39 // Then bind the event to the callback function. 40 // There are several events for cross browser compatibility. 41 // script.onreadystatechange = callback; // TODO: Does this callback no longer exist? 39 42 40 script.onload = callback; 43 41 44 head.appendChild(script);42 body.appendChild(script); 45 43 } 46 44 47 45 loadScript("./interfaces/atea/js/asr/TranscribeService.js"); 48 46 49 function doAudioUpload()47 async function doAudioUpload() 50 48 { 51 49 const files = $(FILE_UPLOAD_INPUT_NAME)[0].files; 52 50 const transcribeService = new TranscribeService(); 53 51 54 52 $(FILE_UPLOAD_PROGRESS_CONTAINER_NAME).removeClass("asr-hidden"); 55 53 56 54 // Remove old transcriptions 57 const parent = document.querySelector("#transcriptionsList"); 58 while (parent.lastChild) { 59 parent.removeChild(parent.lastChild); 55 const transcriptionsList = document.querySelector("#transcriptionsList"); 56 if (transcriptionsList == null) 57 { 58 console.error("Cannot find transcriptions list"); 59 return; 60 60 } 61 61 62 transcribeService.doIndividualFetchUpload(files, (promise, fileName) => { 63 promise 64 .then 65 ( 66 async response => 67 { 68 /** @type {TranscriptionModel[]} */ 69 const transcription = await response.json(); 62 while (transcriptionsList.lastChild) { 63 transcriptionsList.removeChild(transcriptionsList.lastChild); 64 } 70 65 71 // Note that there will only be one transcription here, however the proxy API always returns a list. 72 for (let t of transcription) { 73 console.log("Inserting one transcription"); 74 insertTranscription(t); 75 } 66 try 67 { 68 const transcriptions = await transcribeService.transcribeFiles(files); 69 for (const t of transcriptions) 70 { 71 if (!t.success) { 72 insertError(t.file_name, t.log); 76 73 } 77 ) 78 .catch 79 ( 80 reason => 81 { 82 insertError(fileName); 83 console.log(`Transcription for file ${fileName} failed with reason ${reason}`); 74 else { 75 insertTranscription(t); 84 76 } 85 ); 86 }) 77 } 78 } 79 catch (e) 80 { 81 insertError("all", e.statusMessage); 82 } 87 83 88 // transcribeService.doFetchUpload(files) 89 // .then 90 // ( 91 // transcriptions => { 92 // // Insert each new transcription 93 // for (let t of transcriptions) { 94 // insertTranscription(t); 95 // } 96 // }, 97 // reason => { 98 // console.log(reason) 99 // } 100 // ) 101 // .catch(error => console.log("Failed to upload audio files for transcription: " + error)) // TODO: display error to user 102 // .finally(() => $(FILE_UPLOAD_PROGRESS_CONTAINER_NAME).addClass("asr-hidden")); 103 return false; 84 $(FILE_UPLOAD_PROGRESS_CONTAINER_NAME).addClass("asr-hidden"); 104 85 } 105 86 … … 107 88 const transcriptionTemplate = document.querySelector('#transcriptionTemplate'); 108 89 const metadataTemplate = document.querySelector("#metadataTemplate"); 109 const errorTemplate = document.querySelector("#errorTemplate");110 90 111 91 /** … … 119 99 let list = document.querySelector("#transcriptionsList"); 120 100 121 if (list == null || transcriptionTemplate == null) {122 console.error("Could not find transcription list and/or template.");123 return;124 }125 126 101 // Insert a new transcription row 127 102 let clone = transcriptionTemplate.content.firstElementChild.cloneNode(true); … … 133 108 let metadataList = clone.querySelector("#metadataList"); 134 109 135 if (metadataList == null || metadataTemplate == null) { 110 if (metadataList == null || metadataTemplate == null) 111 { 136 112 console.error("Could not find metadata list and/or template."); 137 113 return; … … 139 115 140 116 // Insert metadata rows 141 for (let metadata of transcription.metadata) { 117 for (let metadata of transcription.metadata) 118 { 142 119 let metadataClone = metadataTemplate.content.firstElementChild.cloneNode(true); 143 120 let metadataSpans = metadataClone.querySelectorAll("td"); … … 152 129 } 153 130 131 const errorTemplate = document.querySelector("#errorTemplate"); 132 154 133 /** 155 134 * Inserts a transcription error into the DOM. 156 135 * 157 136 * @param {String} fileName 137 * @param {String | undefined} statusMessage 158 138 */ 159 function insertError(fileName )139 function insertError(fileName, statusMessage) 160 140 { 161 141 // Get the transcription list and template 162 142 let list = document.querySelector("#transcriptionsList"); 163 143 164 if (list == null || errorTemplate == null) { 144 if (list == null || errorTemplate == null) 145 { 165 146 console.error("Could not find transcription list and/or error template"); 166 147 return; … … 170 151 let clone = errorTemplate.content.firstElementChild.cloneNode(true); 171 152 let spans = clone.querySelectorAll("span"); 172 spans[0].textContent = fileName; 153 spans[0].textContent = statusMessage; 154 spans[1].textContent = fileName; 173 155 174 156 list.appendChild(clone); … … 179 161 function toggleUploadButtonState(e) 180 162 { 181 if (e.target.files.length <= 0) 163 if (e.target.files.length <= 0) { 182 164 $(FILE_UPLOAD_BUTTON_NAME).prop("disabled", true); 183 else 165 } 166 else { 184 167 $(FILE_UPLOAD_BUTTON_NAME).prop("disabled", false); 168 } 185 169 } -
main/trunk/model-interfaces-dev/atea/style/asr.css
r35243 r35250 73 73 margin: -.5em -.5em 0; 74 74 padding: .5em; 75 cursor: pointer; 75 76 } 76 77 -
main/trunk/model-interfaces-dev/atea/transform/pages/asr.xsl
r35243 r35250 41 41 42 42 <div> 43 <form onSubmit=" return doAudioUpload()" enctype="multipart/form-data">43 <form onSubmit="doAudioUpload(); return false;" enctype="multipart/form-data"> 44 44 <label for="fileUpload">Audio File:</label> 45 45 <input id="fileUpload" type="file" accept="audio/wav" multiple="multiple" /> … … 66 66 </div> 67 67 <details> 68 <summary> Metadata</summary>68 <summary>Character Information</summary> 69 69 <table id="metadataList" class="metadata-list"> 70 70 <thead> … … 84 84 <li class="error-list-item"> 85 85 <div> 86 Transcription failed !<br />86 Transcription failed: <span></span><br /> 87 87 <b>File: </b><span></span> 88 88 </div>
Note:
See TracChangeset
for help on using the changeset viewer.