1

I am seeking python 3.x code that can take a user-provided value in ffmpeg's time duration format and provide a float for the number of seconds represented by that duration. It would parse both formats described in the documentation and handle the s/ms/us prefix for the second format. The only thing I would not need is the optional negative. I mostly need this so I can provide the correct 'start_time' (seconds) for the fade and afade filters.

Please note, I am not asking how to get the duration of an input file. These are string values provided by the user.

dgasaway
  • 66
  • 6
  • fade filter `start_time` (and `duration`) can accept a value either in seconds or formatted as `01:23:45.00`. So far I see no need to perform any conversion. Only problem is that you will have to escape the `:`. – llogan Feb 28 '21 at 19:24
  • Pardon? From the [fade documentation](https://ffmpeg.org/ffmpeg-filters.html#fade), "Specify the timestamp (in seconds) of the frame to start to apply the fade effect." – dgasaway Feb 28 '21 at 19:27
  • I tried it before commenting. The documentation should say, *"Specify the timestamp of the frame to start to apply the fade effect. See [(ffmpeg-utils)the Time duration section in the ffmpeg-utils(1) manual](https://ffmpeg.org/ffmpeg-utils.html#time-duration-syntax) for the accepted syntax."* – llogan Feb 28 '21 at 19:36
  • 1
    Regardless, it doesn't entirely solve my problem. The user could specify, as an example, an ending timestamp and a fade out duration in seconds. I would need to take that ending timestamp and subtract the fade duration to get the start of the fade out. The easiest path is to get the ending timestamp in seconds and subtract. Besides, I have other uses for this -- it's only mostly for fade/afade. – dgasaway Feb 28 '21 at 21:32
  • Possible duplicate of [How to convert an H:MM:SS time string to seconds in Python?](https://stackoverflow.com/questions/6402812/how-to-convert-an-hmmss-time-string-to-seconds-in-python) – llogan Feb 28 '21 at 22:25
  • Not a duplicate, because I also want to support both fractional seconds, the second format supported by ffmpeg. – dgasaway Feb 28 '21 at 22:54

1 Answers1

0

I came up with the following code. It's not perfect, as it would probably accept some strings that ffmpeg would not, but it should be close enough for my immediate needs.

def duration_to_seconds(duration):
    """
    Converts an ffmpeg duration string into a decimal representing the number of seconds
    represented by the duration string; None if the string is not parsable.
    """
    pattern = r'^((((?P<hms_grp1>\d*):)?((?P<hms_grp2>\d*):)?((?P<hms_secs>\d+([.]\d*)?)))|' \
              '((?P<smu_value>\d+([.]\d*)?)(?P<smu_units>s|ms|us)))$'
    match = re.match(pattern, duration)
    if match:
        groups = match.groupdict()
        if groups['hms_secs'] is not None:
            value = float(groups['hms_secs'])
            if groups['hms_grp2'] is not None:
                value += int(groups['hms_grp1']) * 60 * 60 + int(groups['hms_grp2']) * 60
            elif groups['hms_grp1'] is not None:
                value += int(groups['hms_grp1']) * 60
        else:
            value = float(groups['smu_value'])
            units = groups['smu_units']
            if units == 'ms':
                value /= 1000.0
            elif units == 'us':
                value /= 1000000.0
        return value
    else:
        return None
dgasaway
  • 66
  • 6