From bb2233cb876c12c40eaba8bedaf298fb8ded1c1f Mon Sep 17 00:00:00 2001 From: Valerio Bozzolan Date: Mon, 7 Jun 2021 11:18:36 +0200 Subject: [PATCH 1/2] add support to time format like mm:ss --- README.md | 18 +++++++++++--- make-xges.py | 69 +++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 78 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 5b3fd15..421d6e7 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,6 @@ This project provides some scripts to download the assets for a recorded presentation, and assemble them into a single video suitable for archive or upload to other video hosting sites. - ## Prerequisites The scripts are written in Python, and rely on the GStreamer Editing @@ -51,7 +50,7 @@ Editing Services project. It takes the following optional parameters to influence the project: -* `--start=SECONDS` and `--end=SECONDS` can be used to trim footage from the start or end of the recording. This can be helpful if the recording was started early, or you want to split the recoridng into multiple projects. +* `--start=TIME` and `--end=TIME` can be used to trim footage from the start or end of the recording. This can be helpful if the recording was started early, or you want to split the recoridng into multiple projects. * `--width=WIDTH` and `--height=HEIGHT` control the dimensions of the video. The default resolution is 1920x1080. * `--webcam-size=PERCENT` controls how much of the frame width will be devoted to the webcam footage. This defaults to 20%. * `--stretch-webcam` stretches the webcam footage by 33%. This was added to correct the camera aspect ratio in some of our recordings. @@ -59,6 +58,12 @@ It takes the following optional parameters to influence the project: * `--opening-credits=FILE[:DURATION]` and `--closing-credits=FILE[:DURATION]` will add credits to project. These can either be videos or still images (which will default to 3 seconds duration). These options can be repeated to add multiple credits. * `--annotations` will include whiteboard annotations and red dot cursor to slides. +Some accepted `TIME` formats: + +* `ss` seconds (example: 1500 or 1500.3) +* `mm:ss` minutes and seconds +* `hh:mm:ss` hours minutes and seconds +* `dd:hh:mm:ss` days, hours, minutes and seconds Currently the project includes the following aspects of the BBB recording: @@ -82,7 +87,6 @@ ges-launch-1.0 --load presentation.xges It can also be loaded in Pitivi if you want to tweak the project before rendering. - ## Render Video If everything looks good, the project can be rendered to a video. The @@ -98,3 +102,11 @@ Or alternatively, it can be rendered as WebM: ges-launch-1.0 --load presentation.xges -o presentation.webm \ --format 'video/webm:video/x-vp8:audio/x-vorbis' ``` + +## License + +Copyright (c) 2020-2021 [James Henstridge](https://github.com/jhenstridge) and contributors + +The project is Free as in freedom software, released under the terms of the MIT License. + +See the LICENSE file. diff --git a/make-xges.py b/make-xges.py index feda92e..2ac178e 100755 --- a/make-xges.py +++ b/make-xges.py @@ -27,11 +27,68 @@ def file_to_uri(path): path = os.path.realpath(path) return 'file://' + path +# +# Try to parse a tring like: +# ss (seconds) +# ss.dd (seconds with decimals) +# mm:ss (minutes and seconds) +# mm:ss.dd (minutes and seconds with decimals) +# hh:mm:ss (hours, minutes and seconds) +# hh:mm:ss.dd (hours, minutes and seconds with decimals) +# dd:hh:mm:ss (days,hours, minutes and seconds) +# dd:hh:mm:ss.dd (days,hours, minutes and seconds with decimals) +# +def parse_time(raw_time): + + # total amount of seconds + seconds = 0.0 + + if raw_time is None: + + seconds = None + + else: + + # allow an empty value + if raw_time == '': + raw_time = '0' + + # seconds should be always 0 + # minutes should be always 1 ecc. + parts = raw_time.split(':') + parts.reverse() + n = len(parts) + + # seconds (ss) - also float is fine here + if( n > 0 ): + seconds = float( parts[0] ) + + # minutes (mm:ss) + if( n > 1 ): + seconds += float( parts[1] ) * 60.0 + + # hours (hh:mm:ss) + if( n > 2 ): + seconds += float( parts[2] ) * 3600.0 + + # days (dd:hh:mm:ss) + if( n > 3 ): + seconds += float( parts[3] ) * 86400.0 + + # what? + if( n > 4 ): + raise ValueError('The provided time does not respect the supported formats: SS, MM:SS, HH:MM:SS, DD:HH:MM:SS.') + + return seconds class Presentation: def __init__(self, opts): self.opts = opts + + self.start = parse_time( opts.start ) + self.end = parse_time( opts.end ) + self.cam_width = round(opts.width * opts.webcam_size / 100) self.slides_width = opts.width - self.cam_width @@ -131,11 +188,11 @@ def set_track_caps(self): audio_info.get_sample_rate(), audio_info.get_channels())) # Set start and end time from options - self.start_time = round(self.opts.start * Gst.SECOND) - if self.opts.end is None: + self.start_time = round(self.start * Gst.SECOND) + if self.end is None: self.end_time = asset.props.duration else: - self.end_time = round(self.opts.end * Gst.SECOND) + self.end_time = round(self.end * Gst.SECOND) # Offset for the opening credits self.opening_length = 0 @@ -390,9 +447,9 @@ def save(self): def main(argv): parser = argparse.ArgumentParser(description='convert a BigBlueButton presentation into a GES project') - parser.add_argument('--start', metavar='SECONDS', type=float, default=0, - help='Seconds to skip from the start of the recording') - parser.add_argument('--end', metavar='SECONDS', type=float, default=None, + parser.add_argument('--start', metavar='TIME', type=str, default='0', + help='Start point in the recording (seconds, or mm:ss, hh:mm:ss, dd:hh:mm:ss)') + parser.add_argument('--end', metavar='TIME', type=str, default=None, help='End point in the recording') parser.add_argument('--width', metavar='WIDTH', type=int, default=1920, help='Video width') From 339ce2c30e9d38ecf78eff623fc066f62eec05a1 Mon Sep 17 00:00:00 2001 From: James Henstridge Date: Wed, 9 Jun 2021 20:42:18 +0800 Subject: [PATCH 2/2] make-xges: convert time values to seconds in the argument parser --- make-xges.py | 108 ++++++++++++++++++++++----------------------------- 1 file changed, 46 insertions(+), 62 deletions(-) diff --git a/make-xges.py b/make-xges.py index 2ac178e..977d639 100755 --- a/make-xges.py +++ b/make-xges.py @@ -27,68 +27,11 @@ def file_to_uri(path): path = os.path.realpath(path) return 'file://' + path -# -# Try to parse a tring like: -# ss (seconds) -# ss.dd (seconds with decimals) -# mm:ss (minutes and seconds) -# mm:ss.dd (minutes and seconds with decimals) -# hh:mm:ss (hours, minutes and seconds) -# hh:mm:ss.dd (hours, minutes and seconds with decimals) -# dd:hh:mm:ss (days,hours, minutes and seconds) -# dd:hh:mm:ss.dd (days,hours, minutes and seconds with decimals) -# -def parse_time(raw_time): - - # total amount of seconds - seconds = 0.0 - - if raw_time is None: - - seconds = None - - else: - - # allow an empty value - if raw_time == '': - raw_time = '0' - - # seconds should be always 0 - # minutes should be always 1 ecc. - parts = raw_time.split(':') - parts.reverse() - n = len(parts) - - # seconds (ss) - also float is fine here - if( n > 0 ): - seconds = float( parts[0] ) - - # minutes (mm:ss) - if( n > 1 ): - seconds += float( parts[1] ) * 60.0 - - # hours (hh:mm:ss) - if( n > 2 ): - seconds += float( parts[2] ) * 3600.0 - - # days (dd:hh:mm:ss) - if( n > 3 ): - seconds += float( parts[3] ) * 86400.0 - - # what? - if( n > 4 ): - raise ValueError('The provided time does not respect the supported formats: SS, MM:SS, HH:MM:SS, DD:HH:MM:SS.') - - return seconds class Presentation: def __init__(self, opts): self.opts = opts - - self.start = parse_time( opts.start ) - self.end = parse_time( opts.end ) - self.cam_width = round(opts.width * opts.webcam_size / 100) self.slides_width = opts.width - self.cam_width @@ -188,11 +131,11 @@ def set_track_caps(self): audio_info.get_sample_rate(), audio_info.get_channels())) # Set start and end time from options - self.start_time = round(self.start * Gst.SECOND) - if self.end is None: + self.start_time = round(self.opts.start * Gst.SECOND) + if self.opts.end is None: self.end_time = asset.props.duration else: - self.end_time = round(self.end * Gst.SECOND) + self.end_time = round(self.opts.end * Gst.SECOND) # Offset for the opening credits self.opening_length = 0 @@ -445,11 +388,52 @@ def save(self): self.timeline.save_to_uri(file_to_uri(self.opts.project), None, True) +def parse_time(value): + """Parse a time interval string into a floating point seconds value. + + Supported formats include: + ss (seconds) + ss.dd (seconds with decimals) + mm:ss (minutes and seconds) + mm:ss.dd (minutes and seconds with decimals) + hh:mm:ss (hours, minutes and seconds) + hh:mm:ss.dd (hours, minutes and seconds with decimals) + dd:hh:mm:ss (days,hours, minutes and seconds) + dd:hh:mm:ss.dd (days,hours, minutes and seconds with decimals) + """ + # allow an empty value + if value == '': + return 0 + + # seconds should be always 0 + # minutes should be always 1 ecc. + parts = value.split(':') + if len(parts) > 4: + raise ValueError('The provided time does not respect the supported formats: SS, MM:SS, HH:MM:SS, DD:HH:MM:SS.') + + parts.reverse() + seconds = float(parts[0]) + + # minutes (mm:ss) + if len(parts) > 1: + seconds += int(parts[1]) * 60 + + # hours (hh:mm:ss) + if len(parts) > 2: + seconds += float(parts[2]) * 3600 + + # days (dd:hh:mm:ss) + if len(parts) > 3: + seconds += float(parts[3]) * 86400 + + return seconds + + def main(argv): parser = argparse.ArgumentParser(description='convert a BigBlueButton presentation into a GES project') - parser.add_argument('--start', metavar='TIME', type=str, default='0', + parser.add_argument('--start', metavar='TIME', type=parse_time, default=0, help='Start point in the recording (seconds, or mm:ss, hh:mm:ss, dd:hh:mm:ss)') - parser.add_argument('--end', metavar='TIME', type=str, default=None, + parser.add_argument('--end', metavar='TIME', type=parse_time, default=None, help='End point in the recording') parser.add_argument('--width', metavar='WIDTH', type=int, default=1920, help='Video width')