0
0
Fork 0
mirror of https://github.com/yt-dlp/yt-dlp.git synced 2024-11-25 02:45:12 +00:00

[utils] Standardize timestamp formatting code

Closes #1285
This commit is contained in:
pukkandan 2021-10-19 22:58:14 +05:30
parent 9fab498fbf
commit aa7785f860
No known key found for this signature in database
GPG key ID: 0F00D95A001F4698
5 changed files with 38 additions and 30 deletions

View file

@ -1390,21 +1390,21 @@ def test_dfxp2srt(self):
</body> </body>
</tt>'''.encode('utf-8') </tt>'''.encode('utf-8')
srt_data = '''1 srt_data = '''1
00:00:02,080 --> 00:00:05,839 00:00:02,080 --> 00:00:05,840
<font color="white" face="sansSerif" size="16">default style<font color="red">custom style</font></font> <font color="white" face="sansSerif" size="16">default style<font color="red">custom style</font></font>
2 2
00:00:02,080 --> 00:00:05,839 00:00:02,080 --> 00:00:05,840
<b><font color="cyan" face="sansSerif" size="16"><font color="lime">part 1 <b><font color="cyan" face="sansSerif" size="16"><font color="lime">part 1
</font>part 2</font></b> </font>part 2</font></b>
3 3
00:00:05,839 --> 00:00:09,560 00:00:05,840 --> 00:00:09,560
<u><font color="lime">line 3 <u><font color="lime">line 3
part 3</font></u> part 3</font></u>
4 4
00:00:09,560 --> 00:00:12,359 00:00:09,560 --> 00:00:12,360
<i><u><font color="yellow"><font color="lime">inner <i><u><font color="yellow"><font color="lime">inner
</font>style</font></u></i> </font>style</font></u></i>

View file

@ -12,6 +12,7 @@
format_bytes, format_bytes,
shell_quote, shell_quote,
timeconvert, timeconvert,
timetuple_from_msec,
) )
from ..minicurses import ( from ..minicurses import (
MultilineLogger, MultilineLogger,
@ -75,14 +76,12 @@ def __init__(self, ydl, params):
@staticmethod @staticmethod
def format_seconds(seconds): def format_seconds(seconds):
(mins, secs) = divmod(seconds, 60) time = timetuple_from_msec(seconds * 1000)
(hours, mins) = divmod(mins, 60) if time.hours > 99:
if hours > 99:
return '--:--:--' return '--:--:--'
if hours == 0: if not time.hours:
return '%02d:%02d' % (mins, secs) return '%02d:%02d' % time[1:-1]
else: return '%02d:%02d:%02d' % time[:-1]
return '%02d:%02d:%02d' % (hours, mins, secs)
@staticmethod @staticmethod
def calc_percent(byte_counter, data_len): def calc_percent(byte_counter, data_len):

View file

@ -15,6 +15,7 @@
compat_ord, compat_ord,
) )
from ..utils import ( from ..utils import (
ass_subtitles_timecode,
bytes_to_intlist, bytes_to_intlist,
bytes_to_long, bytes_to_long,
ExtractorError, ExtractorError,
@ -68,10 +69,6 @@ class ADNIE(InfoExtractor):
'end': 4, 'end': 4,
} }
@staticmethod
def _ass_subtitles_timecode(seconds):
return '%01d:%02d:%02d.%02d' % (seconds / 3600, (seconds % 3600) / 60, seconds % 60, (seconds % 1) * 100)
def _get_subtitles(self, sub_url, video_id): def _get_subtitles(self, sub_url, video_id):
if not sub_url: if not sub_url:
return None return None
@ -117,8 +114,8 @@ def _get_subtitles(self, sub_url, video_id):
continue continue
alignment = self._POS_ALIGN_MAP.get(position_align, 2) + self._LINE_ALIGN_MAP.get(line_align, 0) alignment = self._POS_ALIGN_MAP.get(position_align, 2) + self._LINE_ALIGN_MAP.get(line_align, 0)
ssa += os.linesep + 'Dialogue: Marked=0,%s,%s,Default,,0,0,0,,%s%s' % ( ssa += os.linesep + 'Dialogue: Marked=0,%s,%s,Default,,0,0,0,,%s%s' % (
self._ass_subtitles_timecode(start), ass_subtitles_timecode(start),
self._ass_subtitles_timecode(end), ass_subtitles_timecode(end),
'{\\a%d}' % alignment if alignment != 2 else '', '{\\a%d}' % alignment if alignment != 2 else '',
text.replace('\n', '\\N').replace('<i>', '{\\i1}').replace('</i>', '{\\i0}')) text.replace('\n', '\\N').replace('<i>', '{\\i1}').replace('</i>', '{\\i0}'))

View file

@ -2342,14 +2342,25 @@ def decodeOption(optval):
return optval return optval
_timetuple = collections.namedtuple('Time', ('hours', 'minutes', 'seconds', 'milliseconds'))
def timetuple_from_msec(msec):
secs, msec = divmod(msec, 1000)
mins, secs = divmod(secs, 60)
hrs, mins = divmod(mins, 60)
return _timetuple(hrs, mins, secs, msec)
def formatSeconds(secs, delim=':', msec=False): def formatSeconds(secs, delim=':', msec=False):
if secs > 3600: time = timetuple_from_msec(secs * 1000)
ret = '%d%s%02d%s%02d' % (secs // 3600, delim, (secs % 3600) // 60, delim, secs % 60) if time.hours:
elif secs > 60: ret = '%d%s%02d%s%02d' % (time.hours, delim, time.minutes, delim, time.seconds)
ret = '%d%s%02d' % (secs // 60, delim, secs % 60) elif time.minutes:
ret = '%d%s%02d' % (time.minutes, delim, time.seconds)
else: else:
ret = '%d' % secs ret = '%d' % time.seconds
return '%s.%03d' % (ret, secs % 1) if msec else ret return '%s.%03d' % (ret, time.milliseconds) if msec else ret
def _ssl_load_windows_store_certs(ssl_context, storename): def _ssl_load_windows_store_certs(ssl_context, storename):
@ -4855,7 +4866,12 @@ def parse_dfxp_time_expr(time_expr):
def srt_subtitles_timecode(seconds): def srt_subtitles_timecode(seconds):
return '%02d:%02d:%02d,%03d' % (seconds / 3600, (seconds % 3600) / 60, seconds % 60, (seconds % 1) * 1000) return '%02d:%02d:%02d,%03d' % timetuple_from_msec(seconds * 1000)
def ass_subtitles_timecode(seconds):
time = timetuple_from_msec(seconds * 1000)
return '%01d:%02d:%02d.%02d' % (*time[:-1], time.milliseconds / 10)
def dfxp2srt(dfxp_data): def dfxp2srt(dfxp_data):

View file

@ -13,7 +13,7 @@
import re import re
import io import io
from .utils import int_or_none from .utils import int_or_none, timetuple_from_msec
from .compat import ( from .compat import (
compat_str as str, compat_str as str,
compat_Pattern, compat_Pattern,
@ -124,11 +124,7 @@ def _format_ts(ts):
Convert an MPEG PES timestamp into a WebVTT timestamp. Convert an MPEG PES timestamp into a WebVTT timestamp.
This will lose sub-millisecond precision. This will lose sub-millisecond precision.
""" """
msec = int((ts + 45) // 90) return '%02u:%02u:%02u.%03u' % timetuple_from_msec(int((ts + 45) // 90))
secs, msec = divmod(msec, 1000)
mins, secs = divmod(secs, 60)
hrs, mins = divmod(mins, 60)
return '%02u:%02u:%02u.%03u' % (hrs, mins, secs, msec)
class Block(object): class Block(object):