Skip to content

Commit

Permalink
Merge pull request #66 from Racix/live-recording-refinements
Browse files Browse the repository at this point in the history
Live recording refinements
  • Loading branch information
IsakLundstrom authored Dec 15, 2023
2 parents fb9ca7c + a447d43 commit 2898fdf
Show file tree
Hide file tree
Showing 13 changed files with 234 additions and 236 deletions.
173 changes: 88 additions & 85 deletions backend/api/app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,14 @@ async def delete_media_analysis(media_id: str):
return {"message": "Analysis deleted successfully", "media_id": media_id}


@app.get("/media/{media_id}/analysis/translate/{language}")
async def get_translation(media_id: str, language: str):
try_find_media(media_id)
translation_info = try_find_translation(media_id, language)

return translation_info


@app.post("/media/{media_id}/analysis/translate/{language}", status_code=status.HTTP_201_CREATED)
async def start_translation(media_id: str, language: str,):
# Check if media exists
Expand All @@ -268,7 +276,7 @@ async def translate_analysis(media_id: str, to_language: str) -> dict:
json_analysis = analysis_col.find_one({"media_id": ObjectId(media_id)})
json_analysis['_id'] = str(json_analysis['_id'])
json_analysis['media_id'] = str(json_analysis['media_id'])
detected_language = json_analysis["diarization"]["Detected language"]
detected_language = json_analysis["diarization"]["detected_language"]
async with session.post(translate_url, json=json_analysis, params={"from_language": detected_language, "to_language": to_language}) as response:
if response.status == status.HTTP_201_CREATED:
translation = await response.json()
Expand All @@ -290,13 +298,6 @@ async def translate_analysis(media_id: str, to_language: str) -> dict:
return translation


@app.get("/media/{media_id}/analysis/translate/{language}")
async def get_translation(media_id: str, language: str):
try_find_media(media_id)
translation_info = try_find_translation(media_id, language)

return translation_info

@app.delete("/media/{media_id}/analysis/translate/{language}")
async def delete_translation(media_id: str, language: str):
# Check if media and analysis exists
Expand All @@ -308,6 +309,80 @@ async def delete_translation(media_id: str, language: str):

return {"message": "Translation(" + language + ") deleted successfully", "media_id": media_id}


@app.get("/media/{media_id}/analysis/summary")
async def get_media_summary(media_id: str):
# Check if media and analysis exists
try_find_media(media_id)
analysis_info = try_find_analysis(media_id)

return analysis_info.get('summary', '')


@app.post("/media/{media_id}/analysis/summary")
async def start_media_summary(media_id: str, background_tasks: BackgroundTasks):
# Check if media and analysis exists
media_info = try_find_media(media_id)

# Start analysis in the background
background_tasks.add_task(do_summary, media_info['file_path'], media_id)
return {"message": "Media file summary started"}


async def do_summary(file_path: str, media_id: str):
timeout_seconds = 300
session_timeout = aiohttp.ClientTimeout(total=timeout_seconds)
summarize_url = f"http://{os.environ['SUMMARIZATION_ADDRESS']}:{os.environ['API_PORT_GUEST']}/summarize"
summarize = {}
try_find_media(media_id)
analysis_info = try_find_analysis(media_id)

try:
async with aiohttp.ClientSession(timeout=session_timeout) as session:
status_data = {"status": status.HTTP_200_OK, "message": "Summarization started..."}
asyncio.create_task(analysisManager.broadcast(status_data, media_id))

with open(file_path, 'rb') as file:
form_new = aiohttp.FormData()
form_new.add_field('json_data', json.dumps(analysis_info), content_type='application/json')
form_new.add_field('file', file)

async with aiohttp.request('POST', summarize_url, data=form_new) as response:
if response.status == status.HTTP_201_CREATED:
summarize = await response.json()
status_data = {"status": status.HTTP_200_OK, "message": "Summarization done."}
else:
status_data = {"status": response.status, "message": "Summarization error."}
return
except TimeoutError as e:
print("TimeoutError while summarizing:", e)
status_data = {"status": status.HTTP_504_GATEWAY_TIMEOUT, "message": "Summarization timed out."}
return
except Exception as e:
print("Unknown error while summarizing:", e)
status_data = {"status": status.HTTP_500_INTERNAL_SERVER_ERROR, "message": "Summarization error."}
return
finally:
asyncio.create_task(analysisManager.broadcast(status_data, media_id))

analysis_info['summary'] = summarize.get('summarization', {}).get('response', '')
analysis_col.update_one({"media_id": ObjectId(media_id)}, {"$set": {"summary": analysis_info['summary']}})
status_data = {"status": status.HTTP_201_CREATED, "message": "Summarization done."}
asyncio.create_task(analysisManager.broadcast(status_data, media_id))


@app.delete("/media/{media_id}/analysis/summary")
async def delete_media_summary(media_id: str):
# Check if media and analysis exists
try_find_media(media_id)
try_find_analysis(media_id)

# Find and remove the summary feild
analysis_col.update_one({"media_id": ObjectId(media_id)}, { "$unset": {"summary": ""}})

return {"message": "Summary deleted successfully", "media_id": media_id}


@app.websocket("/ws/analysis/{media_id}")
async def analysis_websocket(websocket: WebSocket, media_id: str):
await analysisManager.connect(websocket, media_id)
Expand Down Expand Up @@ -346,10 +421,10 @@ async def live_transcription_websocket(websocket: WebSocket, live_id: str):
timeout_seconds = 30 #Set a good timeout
session_timeout = aiohttp.ClientTimeout(total=timeout_seconds)
transcribe_url = f"http://{os.environ['LIVE_TRANSCRIPTION_ADDRESS']}:{os.environ['API_PORT_GUEST']}/transcribe-live"
max_state_len = 35
min_state_len = 25
max_len_sent = 10
min_len_sent = 4
max_state_len = 40
min_state_len = 30
max_len_sent = 20
min_len_sent = 2

if live_id not in LIVE_RECORDING_STATE:
LIVE_RECORDING_STATE[live_id] = [0, [], []] # [total_time, state, old_segments]
Expand Down Expand Up @@ -405,8 +480,7 @@ async def live_transcription_websocket(websocket: WebSocket, live_id: str):
transcription['transcription']['segments'] = new_segments
old_segments = new_segments

print("transcription:", transcription)
if transcription is not None:
print("transcription:", transcription)
await liveTransciptionManager.broadcast(transcription, live_id)

except (WebSocketDisconnect, ConnectionClosedOK) as e:
Expand All @@ -421,77 +495,6 @@ async def live_transcription_websocket(websocket: WebSocket, live_id: str):
print(f"Client {websocket.client} disconnected")


@app.post("/media/{media_id}/analysis/summary")
async def get_media_summary(media_id: str, background_tasks: BackgroundTasks):
# Check if media and analysis exists
media_info = try_find_media(media_id)

# Start analysis in the background
background_tasks.add_task(do_summary, media_info['file_path'], media_id)
return {"message": "Media file summary started"}


@app.get("/media/{media_id}/analysis/summary")
async def get_media_analysis(media_id: str):
# Check if media and analysis exists
try_find_media(media_id)
analysis_info = try_find_analysis(media_id)

return analysis_info.get('summary', '')

@app.delete("/media/{media_id}/analysis/summary")
async def delete_media_summary(media_id: str):
# Check if media and analysis exists
try_find_media(media_id)
try_find_analysis(media_id)

# Find and remove the summary feild
analysis_col.update_one({"media_id": ObjectId(media_id)}, { "$unset": {"summary": ""}})

return {"message": "Summary deleted successfully", "media_id": media_id}

async def do_summary(file_path: str, media_id: str):
timeout_seconds = 300
session_timeout = aiohttp.ClientTimeout(total=timeout_seconds)
summarize_url = f"http://{os.environ['SUMMARIZATION_ADDRESS']}:{os.environ['API_PORT_GUEST']}/summarize"
summarize = {}
try_find_media(media_id)
analysis_info = try_find_analysis(media_id)

try:
async with aiohttp.ClientSession(timeout=session_timeout) as session:
status_data = {"status": status.HTTP_200_OK, "message": "Summarization started..."}
asyncio.create_task(analysisManager.broadcast(status_data, media_id))

with open(file_path, 'rb') as file:
form_new = aiohttp.FormData()
form_new.add_field('json_data', json.dumps(analysis_info), content_type='application/json')
form_new.add_field('file', file)

async with aiohttp.request('POST', summarize_url, data=form_new) as response:
if response.status == status.HTTP_201_CREATED:
summarize = await response.json()
status_data = {"status": status.HTTP_200_OK, "message": "Summarization done."}
else:
status_data = {"status": response.status, "message": "Summarization error."}
return
except TimeoutError as e:
print("TimeoutError while summarizing:", e)
status_data = {"status": status.HTTP_504_GATEWAY_TIMEOUT, "message": "Summarization timed out."}
return
except Exception as e:
print("Unknown error while summarizing:", e)
status_data = {"status": status.HTTP_500_INTERNAL_SERVER_ERROR, "message": "Summarization error."}
return
finally:
asyncio.create_task(analysisManager.broadcast(status_data, media_id))

analysis_info['summary'] = summarize.get('summarization', {}).get('response', '')
analysis_col.update_one({"media_id": ObjectId(media_id)}, {"$set": {"summary": analysis_info['summary']}})
status_data = {"status": status.HTTP_201_CREATED, "message": "Summarization done."}
asyncio.create_task(analysisManager.broadcast(status_data, media_id))


def is_media_file(file: UploadFile):
# Allowed media types
allowed_media_types = ['audio', 'video']
Expand Down
9 changes: 3 additions & 6 deletions backend/live-transcription/app/transcribe.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

def transcribe(file_path: str) -> dict:
print(f"Transcription of {file_path} started...")
start_time = time.time() # TODO only for time print, remove later
start_time = time.time()
segments, info = model.transcribe(file_path, beam_size=5)
transcription_segments = []
for segment in segments:
Expand All @@ -16,12 +16,9 @@ def transcribe(file_path: str) -> dict:
"duration": segment.end - segment.start
})
result_dict = {
"Detected language": info.language,
"detected_language": info.language,
"Language probability": info.language_probability * 100,
"segments": transcription_segments
}
# TODO only for time print, remove later
end_time = time.time()
total_time = end_time - start_time
print(f"Transcription of {file_path} finished. Total time: {str(total_time)}")
print(f"Transcription of {file_path} finished. Total time: {str(time.time() - start_time)}")
return result_dict
5 changes: 3 additions & 2 deletions backend/transcription/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@ FROM python:3.10

WORKDIR /transcription

RUN apt-get update && apt-get install -y ffmpeg

COPY ./requirements.txt /transcription/requirements.txt

RUN pip install --no-cache-dir --upgrade -r /transcription/requirements.txt

COPY ./loadModel.py /transcription/loadModel.py

RUN python /transcription/loadModel.py

COPY ./app /transcription/app

RUN apt-get update && apt-get install -y ffmpeg

# EXPOSE 8080

# CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8080"]
4 changes: 2 additions & 2 deletions backend/transcription/app/transcribe.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from transformers import pipeline
from langdetect import detect
import time
import traceback
Expand All @@ -8,6 +7,7 @@
def transcribe(file_path: str) -> dict:
try:
print(f"Transcription of {file_path} started...")
start_time = time.time()
# Transcribe the video to the original language
transcription = whisper_pipeline(file_path, return_timestamps=True, chunk_length_s=30, batch_size=32, generate_kwargs={"task": "transcribe"})
chunks = transcription['chunks']
Expand All @@ -26,14 +26,14 @@ def transcribe(file_path: str) -> dict:
'text': text,
'start': start_timestamp,
'duration': duration,
'Speaker': "Speaker0"
}
transcription_data.append(sentence)

result_dict = {
"detected_language": detected_language,
"segments": transcription_data,
}
print(f"Transcription of {file_path} finished. Total time: {str(time.time() - start_time)}")
return result_dict
except Exception as e:
print(traceback.format_exc())
Loading

0 comments on commit 2898fdf

Please sign in to comment.