diff --git a/seplis_play_server/routes/subtitle_file.py b/seplis_play_server/routes/subtitle_file.py index a6e731e..60590ac 100644 --- a/seplis_play_server/routes/subtitle_file.py +++ b/seplis_play_server/routes/subtitle_file.py @@ -9,7 +9,7 @@ async def download_subtitle( source_index: int, lang: constr(min_length=1), - start_time: int | float = 0, + offset: int | float = 0, metadata=Depends(get_metadata) ): if not metadata: @@ -20,12 +20,12 @@ async def download_subtitle( sub = await get_subtitle_file( metadata=metadata[source_index], lang=lang, - start_time=start_time + offset=offset ) else: sub = await get_subtitle_file_from_external( id_=int(lang.split(':')[1])-1000, - start_time=start_time, + offset=offset, ) if not sub: raise HTTPException(500, 'Unable retrive subtitle file') diff --git a/seplis_play_server/transcoders/subtitle.py b/seplis_play_server/transcoders/subtitle.py index b78a774..8c17c83 100644 --- a/seplis_play_server/transcoders/subtitle.py +++ b/seplis_play_server/transcoders/subtitle.py @@ -5,7 +5,7 @@ from seplis_play_server import config, logger, models, database from .video import stream_index_by_lang, to_subprocess_arguments -async def get_subtitle_file(metadata: Dict, lang: str, start_time: int): +async def get_subtitle_file(metadata: Dict, lang: str, offset: int): if not lang: return sub_index = stream_index_by_lang(metadata, 'subtitle', lang) @@ -14,7 +14,6 @@ async def get_subtitle_file(metadata: Dict, lang: str, start_time: int): args = [ {'-analyzeduration': '200M'}, {'-probesize': '200M'}, - {'-ss': str(start_time)}, {'-i': metadata['format']['filename']}, {'-y': None}, {'-vn': None}, @@ -36,10 +35,10 @@ async def get_subtitle_file(metadata: Dict, lang: str, start_time: int): if process.returncode != 0: logger.warning(f'Subtitle file could not be exported!: {stderr}') return None - return stdout + return stdout if not offset else offset_webvtt(stdout, offset) -async def get_subtitle_file_from_external(id_: int, start_time: int): +async def get_subtitle_file_from_external(id_: int, offset: int): async with database.session() as session: sub_metadata = await session.scalar(sa.select(models.External_subtitle).where( @@ -50,7 +49,8 @@ async def get_subtitle_file_from_external(id_: int, start_time: int): return None if sub_metadata.path.endswith('.vtt'): - return await get_subtitle_file_from_vtt(sub_metadata.path) + vtt = await get_subtitle_file_from_vtt(sub_metadata.path) + return vtt if not offset else offset_webvtt(vtt, offset) if not os.path.exists(sub_metadata.path): logger.warning(f'Subtitle file could not be found: {sub_metadata.path}') @@ -59,7 +59,6 @@ async def get_subtitle_file_from_external(id_: int, start_time: int): args = [ {'-analyzeduration': '200M'}, {'-probesize': '200M'}, - {'-ss': str(start_time)}, {'-i': sub_metadata.path}, {'-y': None}, {'-vn': None}, @@ -80,7 +79,9 @@ async def get_subtitle_file_from_external(id_: int, start_time: int): if process.returncode != 0: logger.warning(f'Subtitle file could not be exported!: {stderr}') return None - return stdout + + logger.info(offset) + return stdout if not offset else offset_webvtt(stdout, offset) async def get_subtitle_file_from_vtt(path: str): @@ -90,3 +91,35 @@ async def get_subtitle_file_from_vtt(path: str): logger.warning(f'Subtitle file could not be found: {path}') return None return data + + +def offset_webvtt(webvtt_content, offset_seconds): + lines = webvtt_content.split('\n') + output_lines = [] + for line in lines: + if '-->' in line: + times = line.split(' --> ') + if len(times) == 2: + start_time, end_time = times + try: + start_seconds = sum(float(x) * 60 ** index for index, x in enumerate(reversed(start_time.split(':')))) + end_seconds = sum(float(x) * 60 ** index for index, x in enumerate(reversed(end_time.split(':')))) + new_start = start_seconds + offset_seconds + new_end = end_seconds + offset_seconds + + new_start_formatted = '{:02d}:{:02d}:{:06.3f}'.format(int(new_start // 3600), + int((new_start % 3600) // 60), + new_start % 60) + new_end_formatted = '{:02d}:{:02d}:{:06.3f}'.format(int(new_end // 3600), + int((new_end % 3600) // 60), + new_end % 60) + + output_lines.append(f"{new_start_formatted} --> {new_end_formatted}") + except ValueError: + output_lines.append(line) + else: + output_lines.append(line) + else: + output_lines.append(line) + + return '\n'.join(output_lines) \ No newline at end of file