Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.127.0 (Custom GPX data + misc. improvements) #213

Open
wants to merge 32 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
4490c2f
transit v1
CyrilSLi Apr 8, 2024
38ce2ac
Generalized addition of custom_fields (for each GPX point) and custom…
CyrilSLi Apr 8, 2024
c10040f
Allow custom index "pace", fix error msg
CyrilSLi Apr 8, 2024
73ca32b
change custom format
CyrilSLi Apr 8, 2024
f8d8bff
Allow custom fields in charts
CyrilSLi Apr 8, 2024
50281af
rename custom unit to 'custom.float'
CyrilSLi Apr 8, 2024
5221677
simple bugfixes
CyrilSLi Apr 8, 2024
dc1b84c
custom data docs
CyrilSLi Apr 9, 2024
349a152
grammar edit
CyrilSLi Apr 9, 2024
7221735
Add support for empty custom tags
CyrilSLi Apr 16, 2024
6f584eb
Add metadata references
CyrilSLi Apr 19, 2024
dc3912a
remove dedundant try-except
CyrilSLi Apr 23, 2024
8214e6a
bump gpxpy
CyrilSLi Apr 24, 2024
4505c91
Expand icon features
CyrilSLi Jun 2, 2024
372e8ce
Draw waypoints, style customizations
CyrilSLi Jun 18, 2024
d5820fa
update pint
CyrilSLi Aug 9, 2024
e5a4a1e
update pint
CyrilSLi Aug 9, 2024
20d63d2
update docs on new features
CyrilSLi Aug 10, 2024
eae66f2
docs
CyrilSLi Aug 10, 2024
3207f96
bump version
CyrilSLi Aug 11, 2024
e951ddf
Add 'overlay' profile
CyrilSLi Aug 11, 2024
76422f3
typo
CyrilSLi Aug 11, 2024
8c96372
allow non-RGBA icons
CyrilSLi Aug 12, 2024
54e5eb2
search for icons in the layout file's dir
CyrilSLi Aug 15, 2024
9afcedf
add pcenter-aligned rogress bar to "bar"
CyrilSLi Aug 19, 2024
16a6ce4
update docs on bar
CyrilSLi Aug 21, 2024
45c1bb0
Merge branch 'main' into merge
CyrilSLi Sep 18, 2024
a503bda
Merge pull request #1 from CyrilSLi/merge
CyrilSLi Sep 18, 2024
d98daed
docs
CyrilSLi Sep 18, 2024
a636c22
different map layers in one video, fixed rounded_corners
CyrilSLi Sep 22, 2024
2f75ee7
docs on per-component map style
CyrilSLi Sep 22, 2024
f1c291c
Removed unneeded indentation only.
CyrilSLi Sep 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.126.0
current_version = 0.127.0

[bumpversion:file:setup.py]

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ https://github.com/JuanIrache/gopro-telemetry
## Latest Changes

If you find any issues with new releases, please discuss in [GitHub Discussions](https://github.com/time4tea/gopro-dashboard-overlay/discussions)
- 0.127.0 [Enhancement] Inserting custom data through a GPX file, custom colors for the journey map, non-square icon support
- 0.126.0 [Enhancement] New Motorspeed widgets - "msi" & "msi2" - See examples [docs/xml/examples/07-motor-speed-indicator/README.md](docs/xml/examples/07-motor-speed-indicator/README.md) - Thanks to [@JimmyS83](https://github.com/JimmyS83) for contributing.
- New metric `accel` which is computed from speed deltas, rather than gopro accelerometer. Thanks also to [@JimmyS83](https://github.com/JimmyS83)
- [Breaking] Ordering of fields in gopro-to-csv has changed, with addition of `accel` field
Expand Down
190 changes: 96 additions & 94 deletions bin/gopro-dashboard.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
import datetime
import sys
import sys, os
from importlib import metadata
from importlib.metadata import PackageNotFoundError
from pathlib import Path
Expand Down Expand Up @@ -72,7 +72,7 @@ def create_desired_layout(dimensions, layout, layout_xml: Path, include, exclude
elif layout == "xml":
return layout_from_xml(
load_xml_layout(layout_xml), renderer, timeseries, font, privacy_zone, include=accepter,
decorator=profiler, converters=converters
decorator=profiler, converters=converters, xml_path=os.path.abspath(layout_xml)
)
else:
raise ValueError(f"Unsupported layout {args.layout_creator}")
Expand Down Expand Up @@ -272,6 +272,8 @@ def fmtdt(dt: datetime.datetime):
frame_meta.process(timeseries_process.process_kalman("speed", lambda e: e.speed))
frame_meta.process(timeseries_process.filter_locked())

frame_meta.process(timeseries_process.custom_passthrough())

# privacy zone applies everywhere, not just at start, so might not always be suitable...
if args.privacy:
lat, lon, km = args.privacy.split(",")
Expand All @@ -282,115 +284,115 @@ def fmtdt(dt: datetime.datetime):
else:
privacy_zone = NoPrivacyZone()

with MapRenderer(
renderer = MapRenderer(
cache_dir=cache_dir,
styler=MapStyler(
api_key_finder=api_key_finder(config_loader, args)
)
).open(args.map_style) as renderer:
))
renderer.default_style = args.map_style

if args.profiler:
profiler = WidgetProfiler()
else:
profiler = None
if args.profiler:
profiler = WidgetProfiler()
else:
profiler = None

if args.profile:
ffmpeg_options = load_ffmpeg_profile(config_loader, args.profile)
else:
ffmpeg_options = None
if args.profile:
ffmpeg_options = load_ffmpeg_profile(config_loader, args.profile)
else:
ffmpeg_options = None

if args.show_ffmpeg:
redirect = None
else:
redirect = temp_file_name(suffix=".txt")
log(f"FFMPEG Output is in {redirect}")

execution = InProcessExecution(redirect=redirect)

output: Path = args.output

if generate == "none":
ffmpeg = FFMPEGNull()
elif generate == "overlay":
output.unlink(missing_ok=True)
ffmpeg = FFMPEGOverlay(
ffmpeg=ffmpeg_exe,
output=output,
options=ffmpeg_options,
overlay_size=dimensions,
execution=execution,
creation_time=frame_meta.date_at(frame_meta.min)
)
else:
output.unlink(missing_ok=True)
ffmpeg = FFMPEGOverlayVideo(
ffmpeg=ffmpeg_exe,
input=inputpath,
output=output,
options=ffmpeg_options,
overlay_size=dimensions,
execution=execution,
creation_time=frame_meta.date_at(frame_meta.min)
)
if args.show_ffmpeg:
redirect = None
else:
redirect = temp_file_name(suffix=".txt")
log(f"FFMPEG Output is in {redirect}")

execution = InProcessExecution(redirect=redirect)

output: Path = args.output

if generate == "none":
ffmpeg = FFMPEGNull()
elif generate == "overlay":
output.unlink(missing_ok=True)
ffmpeg = FFMPEGOverlay(
ffmpeg=ffmpeg_exe,
output=output,
options=ffmpeg_options,
overlay_size=dimensions,
execution=execution,
creation_time=frame_meta.date_at(frame_meta.min)
)
else:
output.unlink(missing_ok=True)
ffmpeg = FFMPEGOverlayVideo(
ffmpeg=ffmpeg_exe,
input=inputpath,
output=output,
options=ffmpeg_options,
overlay_size=dimensions,
execution=execution,
creation_time=frame_meta.date_at(frame_meta.min)
)

draw_timer = PoorTimer("drawing frames")
draw_timer = PoorTimer("drawing frames")

# Draw an overlay frame every 0.1 seconds of video
timelapse_correction = frame_meta.duration() / video_duration
log(f"Timelapse Factor = {timelapse_correction:.3f}")
stepper = frame_meta.stepper(timeunits(seconds=0.1 * timelapse_correction))
progress = ProgressBarProgress("Render")
# Draw an overlay frame every 0.1 seconds of video
timelapse_correction = frame_meta.duration() / video_duration
log(f"Timelapse Factor = {timelapse_correction:.3f}")
stepper = frame_meta.stepper(timeunits(seconds=0.1 * timelapse_correction))
progress = ProgressBarProgress("Render")

unit_converters = Converters(
speed_unit=args.units_speed,
distance_unit=args.units_distance,
altitude_unit=args.units_altitude,
temperature_unit=args.units_temperature,
)
unit_converters = Converters(
speed_unit=args.units_speed,
distance_unit=args.units_distance,
altitude_unit=args.units_altitude,
temperature_unit=args.units_temperature,
)

layout_creator = create_desired_layout(
layout=args.layout,
layout_xml=args.layout_xml,
dimensions=dimensions,
include=args.include,
exclude=args.exclude,
renderer=renderer,
timeseries=frame_meta,
font=font,
privacy_zone=privacy_zone,
profiler=profiler,
converters=unit_converters
)
layout_creator = create_desired_layout(
layout=args.layout,
layout_xml=args.layout_xml,
dimensions=dimensions,
include=args.include,
exclude=args.exclude,
renderer=renderer,
timeseries=frame_meta,
font=font,
privacy_zone=privacy_zone,
profiler=profiler,
converters=unit_converters
)

overlay = Overlay(framemeta=frame_meta, create_widgets=layout_creator)
overlay = Overlay(framemeta=frame_meta, create_widgets=layout_creator)

try:
progress.start(len(stepper))
with ffmpeg.generate() as writer:
try:
progress.start(len(stepper))
with ffmpeg.generate() as writer:

if args.double_buffer:
log("*** NOTE: Double Buffer mode is experimental. It is believed to work fine on Linux. "
"Please raise issues if you see it working or not-working. Thanks ***")
buffer = DoubleBuffer(dimensions, args.bg, writer)
else:
buffer = SingleBuffer(dimensions, args.bg, writer)
if args.double_buffer:
log("*** NOTE: Double Buffer mode is experimental. It is believed to work fine on Linux. "
"Please raise issues if you see it working or not-working. Thanks ***")
buffer = DoubleBuffer(dimensions, args.bg, writer)
else:
buffer = SingleBuffer(dimensions, args.bg, writer)

with buffer:
for index, dt in enumerate(stepper.steps()):
progress.update(index)
draw_timer.time(lambda: buffer.draw(lambda frame: overlay.draw(dt, frame)))
with buffer:
for index, dt in enumerate(stepper.steps()):
progress.update(index)
draw_timer.time(lambda: buffer.draw(lambda frame: overlay.draw(dt, frame)))

log("Finished drawing frames. waiting for ffmpeg to catch up")
progress.complete()
log("Finished drawing frames. waiting for ffmpeg to catch up")
progress.complete()

finally:
for t in [draw_timer]:
log(t)
finally:
for t in [draw_timer]:
log(t)

if profiler:
log("\n\n*** Widget Timings ***")
profiler.print()
log("***\n\n")
if profiler:
log("\n\n*** Widget Timings ***")
profiler.print()
log("***\n\n")

except KeyboardInterrupt:
log("User interrupted...")
6 changes: 5 additions & 1 deletion build-scripts/examples/02-icons.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

# Icons

Icons are *square* images that can be placed anywhere.
Icons are *square* images that can be placed anywhere. Custom icons must be in `RGB` or `RGBA` format.

## Built-In

Expand All @@ -25,6 +25,10 @@ To rescale the icon use `size`

{{ <component type="icon" file="bicycle.png" invert="false" size="128"/> }}

*If `size` is 0, the icon will be rendered at its original size. This also allows for non-square icons to be rendered at their original aspect ratio.*

***Make sure `invert="false"` is used if you want to display the original icon.***

## Positioning

This component supports positioning with `x` and `y`.
Expand Down
3 changes: 1 addition & 2 deletions build-scripts/examples/05-moving-map.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,8 @@ Map rotation can be turned off with `rotate`.
## Map Provider & Styles

The map provider, and the map style, can be selected using the command line arguments when running the dashboard program.
Currently, it's not possible to have multiple different map styles and providers in the same dashboard.

It is possible to have multiple moving maps, though
It is possible to have multiple maps in the same video:

{{
<component type="moving_map" size="128" zoom="4" />
Expand Down
4 changes: 4 additions & 0 deletions build-scripts/examples/06-journey-map.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ Use `x` and `y` to set the position on screen

{{ <component type="journey_map" x="64" y="64" size="64" /> }}

## Colours

Refer to the [Moving Journey Map docs](06-moving-journey-map.md#colours) for details on setting colours and sizes for the current position, path, and waypoints.

## Opacity

Set the opacity using `opacity`. It defaults to 1.0 which is completely opaque. 0.0 would be completely transparent.
Expand Down
8 changes: 8 additions & 0 deletions build-scripts/examples/06-moving-journey-map.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ The zoom can be set with `zoom` - Very high levels of zoom might not work reliab
{{ <component type="moving_journey_map" size="256" zoom="11" /> }}
{{ <component type="moving_journey_map" size="256" zoom="14" /> }}

## Colours

The `pos_rgb`, `pos_size`, `path_rgb`, `path_size`, `wpt_rgb`, and `wpt_size` attributes can be used to set the colour and size/thickness of the current position, the path, and waypoints respectively.

The default values are blue/size 6 for the current position, red/size 4 for the path, and green/size 6 for waypoints.

{{ <component type="moving_journey_map" zoom="15" pos_rgb="255,128,0" pos_size="12" path_rgb="0,128,0" path_width="2" wpt_rgb="0,0,0" wpt_size="20" /> }}

## Positioning, Transparency and Corners

The component should be placed in a `translate` to move it around the screen
Expand Down
4 changes: 4 additions & 0 deletions build-scripts/examples/07-bar.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ Use `max` and `min` to control the max and min values that the bar will display

{{ <component type="bar" metric="accl.y" units="m/s^2" max="10" min="0" /> }}

## Centered bar

Use `align_center="true"` to center the bar around zero (the middle). This can be useful for progress bars or similar. The `h-neg` and `h-pos` properties are not used or displayed in this mode. **Tip:** set color properties to `0,0,0,0` to hide them. You will probably want to hide `fill`, `outline`, and `zero` for a progress bar.


## Example Composite Bar Component

Expand Down
7 changes: 7 additions & 0 deletions build-scripts/map-styles.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ The providers are:
- OSM/OpenStreetmap
- ThunderForest
- Geoapify
- TianDiTu/天地图

# Selecting the Map Style

Expand All @@ -16,6 +17,12 @@ Example:

`--map-style tf-cycle `

# (NEW) Per-Component Map Style

Since v0.127.0

It is now possible to set the map provider and style on a per-component basis. This can be done on the `moving_map`, `journey_map`, and `moving_journey_map` components by using the `map_style` attribute. If blank or omitted, the global map style (set with `--map-style`) will be used. Transparent map styles can be overlaid by using multiple components with different `map_style` attributes.

# API Keys

There are three ways that the API key can be supplied for the map. You'll need to sign up with the map provider.
Expand Down
3 changes: 2 additions & 1 deletion docs/bin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,14 @@ Each `profile` can control the input, output, and optionally, the filter argumen

### Built-in profiles

Since v0.121.0
Since v0.127.0

- `nvgpu` - Use NVIDIA GPU for decoding the GoPro MPEG file, and for encoding the output.
- `nnvgpu` - Use NVIDIA GPU for as much of the process as possible - only supported on in newer versions of ffmpeg, and for certain drivers.
- `mov` - Use PNG images inside a MOV container - allows an alpha channel in a movie, useful when using another video processing system. Note: Use an output filename extension of `.mov`
- `vp9` - Create a vp9 webm movie. Note: use an output filename extension of `.webm`
- `vp8` - Create a vp8 webm movie. Note: use an output filename extension of `.webm`
- `overlay` Use the `qtrle` codec to create a movie with an alpha channel which is much smaller than PNG images. Note: use an output filename extension of `.mov`

## User-defined profiles

Expand Down
7 changes: 7 additions & 0 deletions docs/maps/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ The providers are:
- OSM/OpenStreetmap
- ThunderForest
- Geoapify
- TianDiTu/天地图

# Selecting the Map Style

Expand All @@ -21,6 +22,12 @@ Example:

`--map-style tf-cycle `

# (NEW) Per-Component Map Style

Since v0.127.0

It is now possible to set the map provider and style on a per-component basis. This can be done on the `moving_map`, `journey_map`, and `moving_journey_map` components by using the `map_style` attribute. If blank or omitted, the global map style (set with `--map-style`) will be used. Transparent map styles can be overlaid by using multiple components with different `map_style` attributes.

# API Keys

There are three ways that the API key can be supplied for the map. You'll need to sign up with the map provider.
Expand Down
Loading