@@ -3,6 +3,11 @@ package io.openfuture.openmessenger.kurento.recording
33import com.google.gson.Gson
44import com.google.gson.GsonBuilder
55import com.google.gson.JsonObject
6+ import io.openfuture.openmessenger.assistant.gemini.GeminiService
7+ import io.openfuture.openmessenger.repository.MeetingNoteRepository
8+ import io.openfuture.openmessenger.repository.entity.MeetingNoteEntity
9+ import io.openfuture.openmessenger.service.RecordingManagementService
10+ import io.openfuture.openmessenger.service.SpeechToTextService
611import org.kurento.client.IceCandidate
712import org.kurento.client.KurentoClient
813import org.kurento.client.MediaPipeline
@@ -14,21 +19,27 @@ import org.springframework.web.socket.TextMessage
1419import org.springframework.web.socket.WebSocketSession
1520import org.springframework.web.socket.handler.TextWebSocketHandler
1621import java.io.IOException
22+ import java.time.LocalDateTime
1723import java.util.concurrent.ConcurrentHashMap
1824
1925class RecordingCallHandler (
2026 private val kurento : KurentoClient ,
2127 private val registry : UserRegistry ,
28+ private val recordingManagementService : RecordingManagementService ,
29+ private val speechToTextService : SpeechToTextService ,
30+ private val geminiService : GeminiService ,
31+ private val meetingNoteRepository : MeetingNoteRepository
2232): TextWebSocketHandler() {
2333 val pipelines = ConcurrentHashMap <String , MediaPipeline ?>()
34+ val recordings = ConcurrentHashMap <String , String >()
2435
2536 @Throws(Exception ::class )
2637 public override fun handleTextMessage (session : WebSocketSession , message : TextMessage ) {
2738 val jsonMessage = gson.fromJson(
2839 message.payload,
2940 JsonObject ::class .java
3041 )
31- val user = registry!! .getBySession(session)
42+ val user = registry.getBySession(session)
3243
3344 if (user != null ) {
3445 log.debug(" Incoming message from user '{}': {}" , user.name, jsonMessage)
@@ -113,16 +124,16 @@ class RecordingCallHandler(
113124 private fun incomingCallResponse (callee : UserSession , jsonMessage : JsonObject ) {
114125 val callResponse = jsonMessage[" callResponse" ].asString
115126 val from = jsonMessage[" from" ].asString
116- val calleer = registry!! .getByName(from)
117- val to = calleer ?.callingTo
127+ val caller = registry.getByName(from)
128+ val to = caller ?.callingTo
118129
119130 if (" accept" == callResponse) {
120131 log.debug(" Accepted call from '{}' to '{}'" , from, to)
121132
122- val callMediaPipeline = CallMediaPipeline (
123- kurento !! , from, to
124- )
125- pipelines[calleer !! .sessionId] = callMediaPipeline.pipeline
133+ val callMediaPipeline = CallMediaPipeline (kurento, from, to)
134+ recordings[caller !! .sessionId] = callMediaPipeline.recordedFileUri
135+ recordings[callee.sessionId] = callMediaPipeline.recordedFileUri
136+ pipelines[caller .sessionId] = callMediaPipeline.pipeline
126137 pipelines[callee.sessionId] = callMediaPipeline.pipeline
127138
128139 callee.setWebRtcEndpoint(callMediaPipeline.calleeWebRtcEp)
@@ -153,14 +164,14 @@ class RecordingCallHandler(
153164
154165 val callerSdpOffer = registry.getByName(from)?.sdpOffer
155166
156- calleer !! .setWebRtcEndpoint(callMediaPipeline.callerWebRtcEp)
167+ caller .setWebRtcEndpoint(callMediaPipeline.callerWebRtcEp)
157168 callMediaPipeline.callerWebRtcEp.addIceCandidateFoundListener { event ->
158169 val response = JsonObject ()
159170 response.addProperty(" id" , " iceCandidate" )
160171 response.add(" candidate" , JsonUtils .toJsonObject(event.candidate))
161172 try {
162- synchronized(calleer .session) {
163- calleer .session.sendMessage(TextMessage (response.toString()))
173+ synchronized(caller .session) {
174+ caller .session.sendMessage(TextMessage (response.toString()))
164175 }
165176 } catch (e: IOException ) {
166177 log.debug(e.message)
@@ -174,8 +185,8 @@ class RecordingCallHandler(
174185 response.addProperty(" response" , " accepted" )
175186 response.addProperty(" sdpAnswer" , callerSdpAnswer)
176187
177- synchronized(calleer ) {
178- calleer .sendMessage(response)
188+ synchronized(caller ) {
189+ caller .sendMessage(response)
179190 }
180191
181192 callMediaPipeline.callerWebRtcEp.gatherCandidates()
@@ -185,15 +196,14 @@ class RecordingCallHandler(
185196 val response = JsonObject ()
186197 response.addProperty(" id" , " callResponse" )
187198 response.addProperty(" response" , " rejected" )
188- calleer !! .sendMessage(response)
199+ caller !! .sendMessage(response)
189200 }
190201 }
191202
192203 @Throws(IOException ::class )
193204 fun stop (session : WebSocketSession ) {
194- // Both users can stop the communication. A 'stopCommunication'
195- // message will be sent to the other peer.
196- val stopperUser = registry!! .getBySession(session)
205+ val stopperUser = registry.getBySession(session)
206+
197207 if (stopperUser != null ) {
198208 val stoppedUser =
199209 if ((stopperUser.callingFrom != null ))
@@ -211,6 +221,36 @@ class RecordingCallHandler(
211221 stoppedUser.clear()
212222 }
213223 stopperUser.clear()
224+
225+ val caller = stopperUser.callingFrom ? : stoppedUser?.callingFrom
226+ val callee = stopperUser.callingTo ? : stoppedUser?.callingTo
227+ log.info(" Caller = $caller , callee = $callee " )
228+
229+ pipelines[stoppedUser?.sessionId]
230+
231+ val fileUriString = recordings[stoppedUser?.sessionId]
232+ fileUriString?.let { val uploadToS3 = recordingManagementService.uploadToS3(it)
233+ if (uploadToS3 == - 1 ) {
234+ log.warn(" No file was uploaded for call session ${stoppedUser?.sessionId} " )
235+ return
236+ }
237+ val transcript = speechToTextService.extractTranscript(uploadToS3)
238+ val chat = geminiService.chat(" Generate a summary from the following meeting record: {$transcript }" )
239+
240+ val meetingNoteEntity = MeetingNoteEntity (
241+ caller,
242+ 777 ,
243+ 999 ,
244+ " [$caller , $callee ]" ,
245+ callee,
246+ LocalDateTime .now(),
247+ 1 ,
248+ LocalDateTime .now(),
249+ LocalDateTime .now(),
250+ chat
251+ )
252+ meetingNoteRepository.save(meetingNoteEntity)
253+ }
214254 }
215255 }
216256
@@ -294,11 +334,12 @@ class RecordingCallHandler(
294334 @Throws(Exception ::class )
295335 override fun afterConnectionClosed (session : WebSocketSession , status : CloseStatus ) {
296336 stop(session)
297- registry!! .removeBySession(session)
337+ registry.removeBySession(session)
298338 }
299339
300340 companion object {
301341 private val log: Logger = LoggerFactory .getLogger(RecordingCallHandler ::class .java)
302342 private val gson: Gson = GsonBuilder ().create()
303343 }
344+
304345}
0 commit comments