Kaynağa Gözat

feat(subtitles): Don't show delayed final

If a non final transcript was displayed and then hidden and then we receive a final transcript we remove the part that has already been shown before. If the final transcript is the same as the non final that was already displayed we don't show the final.
factor2
Hristo Terezov 11 ay önce
ebeveyn
işleme
91e1007e5b

+ 11
- 0
react/features/subtitles/actionTypes.ts Dosyayı Görüntüle

@@ -9,6 +9,17 @@
9 9
  */
10 10
 export const REMOVE_TRANSCRIPT_MESSAGE = 'REMOVE_TRANSCRIPT_MESSAGE';
11 11
 
12
+/**
13
+ * The type of (redux) action which indicates that an cached transcript
14
+ * has to be removed from the state.
15
+ *
16
+ * {
17
+ *      type: REMOVE_CACHED_TRANSCRIPT_MESSAGE,
18
+ *      transciptMessageID: string,
19
+ * }
20
+ */
21
+export const REMOVE_CACHED_TRANSCRIPT_MESSAGE = 'REMOVE_CACHED_TRANSCRIPT_MESSAGE';
22
+
12 23
 /**
13 24
  * The type of (redux) action which indicates that a transcript with an
14 25
  * given message_id to be added or updated is received.

+ 17
- 0
react/features/subtitles/actions.any.ts Dosyayı Görüntüle

@@ -1,6 +1,7 @@
1 1
 import { DEFAULT_LANGUAGE } from '../base/i18n/i18next';
2 2
 
3 3
 import {
4
+    REMOVE_CACHED_TRANSCRIPT_MESSAGE,
4 5
     REMOVE_TRANSCRIPT_MESSAGE,
5 6
     SET_REQUESTING_SUBTITLES,
6 7
     TOGGLE_REQUESTING_SUBTITLES,
@@ -23,6 +24,22 @@ export function removeTranscriptMessage(transcriptMessageID: string) {
23 24
     };
24 25
 }
25 26
 
27
+/**
28
+ * Signals that a cached transcript has to be removed from the state.
29
+ *
30
+ * @param {string} transcriptMessageID - The message_id to be removed.
31
+ * @returns {{
32
+*      type: REMOVE_CACHED_TRANSCRIPT_MESSAGE,
33
+*      transcriptMessageID: string,
34
+* }}
35
+*/
36
+export function removeCachedTranscriptMessage(transcriptMessageID: string) {
37
+    return {
38
+        type: REMOVE_CACHED_TRANSCRIPT_MESSAGE,
39
+        transcriptMessageID
40
+    };
41
+}
42
+
26 43
 /**
27 44
  * Signals that a transcript with the given message_id to be added or updated
28 45
  * is received.

+ 31
- 9
react/features/subtitles/middleware.ts Dosyayı Görüntüle

@@ -13,6 +13,7 @@ import {
13 13
     TOGGLE_REQUESTING_SUBTITLES
14 14
 } from './actionTypes';
15 15
 import {
16
+    removeCachedTranscriptMessage,
16 17
     removeTranscriptMessage,
17 18
     setRequestingSubtitles,
18 19
     updateTranscriptMessage
@@ -134,18 +135,16 @@ function _endpointMessageReceived(store: IStore, next: Function, action: AnyActi
134 135
         name
135 136
     };
136 137
 
138
+    let newTranscriptMessage: ITranscriptMessage | undefined;
139
+
137 140
     if (json.type === JSON_TYPE_TRANSLATION_RESULT && json.language === language) {
138 141
         // Displays final results in the target language if translation is
139 142
         // enabled.
140
-
141
-        const newTranscriptMessage = {
143
+        newTranscriptMessage = {
142 144
             clearTimeOut: undefined,
143
-            final: json.text,
145
+            final: json.text?.trim(),
144 146
             participant
145 147
         };
146
-
147
-        _setClearerOnTranscriptMessage(dispatch, transcriptMessageID, newTranscriptMessage);
148
-        dispatch(updateTranscriptMessage(transcriptMessageID, newTranscriptMessage));
149 148
     } else if (json.type === JSON_TYPE_TRANSCRIPTION_RESULT) {
150 149
         // Displays interim and final results without any translation if
151 150
         // translations are disabled.
@@ -209,13 +208,12 @@ function _endpointMessageReceived(store: IStore, next: Function, action: AnyActi
209 208
         // message ID or adds a new transcript message if it does not
210 209
         // exist in the map.
211 210
         const existingMessage = state['features/subtitles']._transcriptMessages.get(transcriptMessageID);
212
-        const newTranscriptMessage: ITranscriptMessage = {
211
+
212
+        newTranscriptMessage = {
213 213
             clearTimeOut: existingMessage?.clearTimeOut,
214 214
             participant
215 215
         };
216 216
 
217
-        _setClearerOnTranscriptMessage(dispatch, transcriptMessageID, newTranscriptMessage);
218
-
219 217
         // If this is final result, update the state as a final result
220 218
         // and start a count down to remove the subtitle from the state
221 219
         if (!json.is_interim) {
@@ -231,7 +229,31 @@ function _endpointMessageReceived(store: IStore, next: Function, action: AnyActi
231 229
             // after the stable part.
232 230
             newTranscriptMessage.unstable = text;
233 231
         }
232
+    }
233
+
234
+    if (newTranscriptMessage) {
235
+        if (newTranscriptMessage.final) {
236
+            const cachedTranscriptMessage
237
+                = state['features/subtitles']._cachedTranscriptMessages?.get(transcriptMessageID);
234 238
 
239
+            if (cachedTranscriptMessage) {
240
+                const cachedText = (cachedTranscriptMessage.stable || cachedTranscriptMessage.unstable)?.trim();
241
+                const newText = newTranscriptMessage.final;
242
+
243
+                if (cachedText && cachedText.length > 0 && newText && newText.length > 0
244
+                    && newText.toLowerCase().startsWith(cachedText.toLowerCase())) {
245
+                    newTranscriptMessage.final = newText.slice(cachedText.length)?.trim();
246
+                }
247
+                dispatch(removeCachedTranscriptMessage(transcriptMessageID));
248
+
249
+                if (!newTranscriptMessage.final || newTranscriptMessage.final.length === 0) {
250
+                    return next(action);
251
+                }
252
+            }
253
+        }
254
+
255
+
256
+        _setClearerOnTranscriptMessage(dispatch, transcriptMessageID, newTranscriptMessage);
235 257
         dispatch(updateTranscriptMessage(transcriptMessageID, newTranscriptMessage));
236 258
     }
237 259
 

+ 38
- 0
react/features/subtitles/reducer.ts Dosyayı Görüntüle

@@ -2,6 +2,7 @@ import ReducerRegistry from '../base/redux/ReducerRegistry';
2 2
 import { TRANSCRIBER_LEFT } from '../transcribing/actionTypes';
3 3
 
4 4
 import {
5
+    REMOVE_CACHED_TRANSCRIPT_MESSAGE,
5 6
     REMOVE_TRANSCRIPT_MESSAGE,
6 7
     SET_REQUESTING_SUBTITLES,
7 8
     TOGGLE_REQUESTING_SUBTITLES,
@@ -13,6 +14,7 @@ import { ITranscriptMessage } from './types';
13 14
  * Default State for 'features/transcription' feature.
14 15
  */
15 16
 const defaultState = {
17
+    _cachedTranscriptMessages: new Map(),
16 18
     _displaySubtitles: false,
17 19
     _transcriptMessages: new Map(),
18 20
     _requestingSubtitles: false,
@@ -20,6 +22,7 @@ const defaultState = {
20 22
 };
21 23
 
22 24
 export interface ISubtitlesState {
25
+    _cachedTranscriptMessages: Map<string, ITranscriptMessage>;
23 26
     _displaySubtitles: boolean;
24 27
     _language: string | null;
25 28
     _requestingSubtitles: boolean;
@@ -35,6 +38,8 @@ ReducerRegistry.register<ISubtitlesState>('features/subtitles', (
35 38
     switch (action.type) {
36 39
     case REMOVE_TRANSCRIPT_MESSAGE:
37 40
         return _removeTranscriptMessage(state, action);
41
+    case REMOVE_CACHED_TRANSCRIPT_MESSAGE:
42
+        return _removeCachedTranscriptMessage(state, action);
38 43
     case UPDATE_TRANSCRIPT_MESSAGE:
39 44
         return _updateTranscriptMessage(state, action);
40 45
     case SET_REQUESTING_SUBTITLES:
@@ -70,16 +75,45 @@ ReducerRegistry.register<ISubtitlesState>('features/subtitles', (
70 75
  */
71 76
 function _removeTranscriptMessage(state: ISubtitlesState, { transcriptMessageID }: { transcriptMessageID: string; }) {
72 77
     const newTranscriptMessages = new Map(state._transcriptMessages);
78
+    const message = newTranscriptMessages.get(transcriptMessageID);
79
+    let { _cachedTranscriptMessages } = state;
80
+
81
+    if (message && !message.final) {
82
+        _cachedTranscriptMessages = new Map(_cachedTranscriptMessages);
83
+        _cachedTranscriptMessages.set(transcriptMessageID, message);
84
+    }
73 85
 
74 86
     // Deletes the key from Map once a final message arrives.
75 87
     newTranscriptMessages.delete(transcriptMessageID);
76 88
 
77 89
     return {
78 90
         ...state,
91
+        _cachedTranscriptMessages,
79 92
         _transcriptMessages: newTranscriptMessages
80 93
     };
81 94
 }
82 95
 
96
+
97
+/**
98
+ * Reduces a specific Redux action REMOVE_CACHED_TRANSCRIPT_MESSAGE of the feature transcription.
99
+ *
100
+ * @param {Object} state - The Redux state of the feature transcription.
101
+ * @param {Action} action -The Redux action REMOVE_CACHED_TRANSCRIPT_MESSAGE to reduce.
102
+ * @returns {Object} The new state of the feature transcription after the reduction of the specified action.
103
+ */
104
+function _removeCachedTranscriptMessage(state: ISubtitlesState,
105
+        { transcriptMessageID }: { transcriptMessageID: string; }) {
106
+    const newCachedTranscriptMessages = new Map(state._cachedTranscriptMessages);
107
+
108
+    // Deletes the key from Map once a final message arrives.
109
+    newCachedTranscriptMessages.delete(transcriptMessageID);
110
+
111
+    return {
112
+        ...state,
113
+        _cachedTranscriptMessages: newCachedTranscriptMessages
114
+    };
115
+}
116
+
83 117
 /**
84 118
  * Reduces a specific Redux action UPDATE_TRANSCRIPT_MESSAGE of the feature
85 119
  * transcription.
@@ -92,12 +126,16 @@ function _removeTranscriptMessage(state: ISubtitlesState, { transcriptMessageID
92 126
 function _updateTranscriptMessage(state: ISubtitlesState, { transcriptMessageID, newTranscriptMessage }:
93 127
     { newTranscriptMessage: ITranscriptMessage; transcriptMessageID: string; }) {
94 128
     const newTranscriptMessages = new Map(state._transcriptMessages);
129
+    const _cachedTranscriptMessages = new Map(state._cachedTranscriptMessages);
130
+
131
+    _cachedTranscriptMessages.delete(transcriptMessageID);
95 132
 
96 133
     // Updates the new message for the given key in the Map.
97 134
     newTranscriptMessages.set(transcriptMessageID, newTranscriptMessage);
98 135
 
99 136
     return {
100 137
         ...state,
138
+        _cachedTranscriptMessages,
101 139
         _transcriptMessages: newTranscriptMessages
102 140
     };
103 141
 }

Loading…
İptal
Kaydet