Changeset 35545 for main/trunk


Ignore:
Timestamp:
2021-10-01T15:55:02+13:00 (3 years ago)
Author:
cstephen
Message:

Show word timestamps in the WordTimingSelector component. Improve word generation algorithm and make them a computed property of the TranscriptionItem component.

Location:
main/trunk/model-interfaces-dev/atea/korero-maori-asr/src/components
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • main/trunk/model-interfaces-dev/atea/korero-maori-asr/src/components/TranscriptionItemEditor.vue

    r35542 r35545  
    130130        return {
    131131            enableEditing: false,
    132             words: [],
    133132            lastHighlightedWordIndex: 0,
    134133            selectedIndex: 0
     
    136135    },
    137136    computed: {
     137        /**
     138         * Gets the words in a transcription.
     139         * @param {TranscriptionViewModel} transcription The transcription.
     140         * @returns {Word[]}
     141         */
     142        words() {
     143            const metadata = this.transcription.metadata;
     144
     145            if (metadata.length === 0) {
     146                return;
     147            }
     148
     149            /** @type {Word[]} */
     150            const words = [];
     151
     152            let currentWord = "";
     153            let currStartTime = metadata[0].start_time;
     154
     155            for (let i = 0; i < metadata.length; i++) {
     156                const mChar = metadata[i];
     157
     158                if (mChar.char === " ") {
     159                    words.push(new Word(currentWord, currStartTime, mChar.start_time));
     160                    currentWord = "";
     161
     162                    if (i + 1 < metadata.length) {
     163                        currStartTime = metadata[i + 1].start_time;
     164                    }
     165                    else {
     166                        break;
     167                    }
     168                }
     169                else {
     170                    currentWord += mChar.char;
     171                }
     172            }
     173
     174            // Push the last word, as most transcriptions will not end in a space (hence breaking the above algorithm)
     175            if (currentWord.length > 0) {
     176                const newWord = new Word(currentWord, currStartTime, metadata[metadata.length - 1].start_time)
     177                words.push(newWord);
     178            }
     179
     180            return words;
     181        },
    138182        currentPlaybackTime: {
    139183            get() {
     
    164208    },
    165209    methods: {
     210
    166211        async playAudio(startTime) {
    167212            await AudioPlayback.play(this.transcription.id, startTime);
    168213        },
     214
    169215        getSurroundingWords(index) {
    170216            const BUFFER = 2; // The number of words to take on each side
     
    182228            return this.words.slice(min, max);
    183229        },
     230
    184231        /**
    185232         * Invoked when the value of a word changes.
     
    326373            }
    327374        },
     375
    328376        mergeWordForward(word, index) {
    329377            if (this.words.length < 2) {
     
    337385            this.setFocus(index, false);
    338386        },
     387
    339388        mergeWordBackward(word, index) {
    340389            if (this.words.length < 2) {
     
    348397            this.setFocus(index, true);
    349398        },
     399
    350400        onEditorFocus(index) {
    351401            if (this.currentPlaybackTime < this.words[index].startTime || this.currentPlaybackTime > this.words[index].endTime) {
     
    356406            this.selectedIndex = index;
    357407        },
     408
    358409        onEditorFocusOut(index) {
    359410            // Remove empty words when they lose focus
     
    395446            }
    396447        }
     448
    397449    },
    398450    watch: {
     
    419471            }
    420472        }
    421     },
    422     beforeMount() {
    423         this.words = getWords(this.transcription);
    424473    }
    425474}
    426 
    427 /**
    428  * Gets the words in a transcription.
    429  * @param {TranscriptionViewModel} transcription The transcription.
    430  * @returns {Word[]}
    431  */
    432 export function getWords(transcription) {
    433     /** @type {Word[]} */
    434     const words = [];
    435 
    436     let lastWord = "";
    437     let currStartTime = 0;
    438 
    439     for (const metadata of transcription.metadata) {
    440         if (metadata.char === " ") {
    441             words.push(new Word(lastWord, currStartTime, metadata.start_time));
    442 
    443             lastWord = "";
    444             currStartTime = metadata.start_time;
    445         }
    446         else {
    447             lastWord += metadata.char;
    448         }
    449     }
    450 
    451     // Push the last word, as most transcriptions will not end in a space (hence breaking the above algorithm)
    452     if (lastWord.length > 0) {
    453         const newWord = new Word(lastWord, currStartTime, transcription.metadata[transcription.metadata.length - 1].start_time)
    454         words.push(newWord);
    455     }
    456 
    457     return words;
    458 }
    459475</script>
  • main/trunk/model-interfaces-dev/atea/korero-maori-asr/src/components/WordTimingSelector.vue

    r35543 r35545  
    99        </div>
    1010
    11         <span v-if="isMounted && !isProduction" class="material-icons mdi-m word-handle" :style="{ left: leftHandleLeft }"
    12             @mousedown="canShiftMinValue = true">
    13             first_page
    14         </span>
    15         <span v-if="isMounted && !isProduction" class="material-icons mdi-m word-handle" :style="{ left: rightHandleLeft }"
    16             @mousedown="canShiftMaxValue = true">
    17             last_page
    18         </span>
     11        <div class="word-attachment-container" :style="{ left: leftHandleLeft }">
     12            <span>{{ wordStartTime }}</span>
     13            <span v-if="isMounted && !isProduction" class="material-icons mdi-m word-handle" @mousedown="canShiftMinValue = true">
     14                first_page
     15            </span>
     16        </div>
     17
     18        <div class="word-attachment-container" :style="{ left: rightHandleLeft }">
     19            <span v-if="isMounted && !isProduction" class="material-icons mdi-m word-handle" @mousedown="canShiftMaxValue = true">
     20                last_page
     21            </span>
     22            <span>{{ wordEndTime }}</span>
     23        </div>
    1924    </div>
    2025
     
    5156}
    5257
     58.word-attachment-container {
     59    position: absolute;
     60    top: -105%;
     61    display: flex;
     62    align-items: center
     63}
     64
    5365.word-handle {
    5466    @extend .theme-flat;
    55 
    56     position: absolute;
    57     top: -105%;
    5867
    5968    color: var(--fg-color);
     
    136145            return Util.formatSecondsTimeString(this.surroundingWords[this.surroundingWords.length - 1].endTime, false, 2);
    137146        },
     147        wordStartTime() {
     148            return Util.formatSecondsTimeString(this.word.startTime, false, 2);
     149        },
     150        wordEndTime() {
     151            return Util.formatSecondsTimeString(this.word.endTime, false, 2);
     152        },
    138153        leftHandleLeft() {
    139             return `calc(${this.myWord.left}px - 1em)`;
     154            return `calc(${this.myWord.left}px - 5.5em)`;
    140155        },
    141156        rightHandleLeft() {
Note: See TracChangeset for help on using the changeset viewer.