gabriel becker
1 year ago
commit
9235669ba5
6 changed files with 288 additions and 0 deletions
@ -0,0 +1,91 @@
|
||||
import json |
||||
|
||||
WORKOUT_DATABASE = { |
||||
"countFinishedTraining": 0, |
||||
"imagePath": "defaultTraining.png", |
||||
"isImagePathExternal": False, |
||||
"name": "lol2", |
||||
"orderNr": -1, |
||||
"trainingPlanId": 0, |
||||
"workoutSessions": [] |
||||
} |
||||
|
||||
|
||||
def create_work_database(name, workout_sessions): |
||||
new_db = dict(WORKOUT_DATABASE) |
||||
new_content = { |
||||
"name": name, |
||||
"workoutSessions": workout_sessions |
||||
} |
||||
|
||||
new_db.update(new_content) |
||||
return new_db |
||||
|
||||
|
||||
WORKOUT_SESSION = { |
||||
"finished": False, |
||||
"name": "1. day", |
||||
"orderNr": -1, |
||||
"trainingPlanId": 13, |
||||
"workoutItems": [], |
||||
"workoutSessionId": 0 |
||||
} |
||||
|
||||
|
||||
def create_work_session(workout_items: list): |
||||
new_session = dict(WORKOUT_SESSION) |
||||
new_session_content = { |
||||
"workoutItems": workout_items |
||||
} |
||||
new_session.update(new_session_content) |
||||
return new_session |
||||
|
||||
|
||||
WOPRKOUT_ITEM = { |
||||
"breakTime": 2, |
||||
"description": "Stand up with your legs spread and your hands touching overhead. Then as you jump, bring your legs back together and put your arms to your sides. You can speed these up or slow them down to suit your fitness level.", |
||||
"elapsedTime": 0, |
||||
"finished": False, |
||||
"imagePath": "jumping_jack.png", |
||||
"isImagePathExternal": False, |
||||
"isTimeMode": True, |
||||
"isVideoMode": True, |
||||
"isVideoPathExternal": False, |
||||
"name": "Jumping Jack", |
||||
"orderNr": -1, |
||||
"prepTime": 5, |
||||
"repetitionCount": 5, |
||||
"videoPath": "jumping_jack.mp4", |
||||
"workoutItemId": 0, |
||||
"workoutSessionId": 1, |
||||
"workoutTime": 30 |
||||
} |
||||
|
||||
|
||||
def create_item(): |
||||
new_item = dict(WOPRKOUT_ITEM) |
||||
new_item_content = { |
||||
"description": "Stand up with your legs spread and your hands touching overhead. Then as you jump, bring your legs back together and put your arms to your sides. You can speed these up or slow them down to suit your fitness level.", |
||||
"elapsedTime": 0, |
||||
"imagePath": "jumping_jack.png", |
||||
"isImagePathExternal": False, |
||||
"isTimeMode": True, |
||||
"isVideoMode": True, |
||||
"prepTime": 5, |
||||
"repetitionCount": 5, |
||||
"videoPath": "jumping_jack.mp4", |
||||
"workoutTime": 30 |
||||
} |
||||
new_item.update(new_item_content) |
||||
return new_item |
||||
|
||||
|
||||
def lasdikfsh(): |
||||
items = [create_item()] |
||||
sessions = [create_work_session(items)] |
||||
db = create_work_database('urdur', sessions) |
||||
with open("your_json_file.json", "w") as fp: |
||||
json.dump(db , fp) |
||||
|
||||
if __name__ == '__main__': |
||||
lasdikfsh() |
@ -0,0 +1,108 @@
|
||||
{ |
||||
"type": "object", |
||||
"required": [], |
||||
"properties": { |
||||
"countFinishedTraining": { |
||||
"type": "string" |
||||
}, |
||||
"imagePath": { |
||||
"type": "string" |
||||
}, |
||||
"isImagePathExternal": { |
||||
"type": "string" |
||||
}, |
||||
"name": { |
||||
"type": "string" |
||||
}, |
||||
"orderNr": { |
||||
"type": "number" |
||||
}, |
||||
"trainingPlanId": { |
||||
"type": "string" |
||||
}, |
||||
"workoutSessions": { |
||||
"type": "array", |
||||
"items": { |
||||
"type": "object", |
||||
"required": [], |
||||
"properties": { |
||||
"finished": { |
||||
"type": "boolean" |
||||
}, |
||||
"name": { |
||||
"type": "string" |
||||
}, |
||||
"orderNr": { |
||||
"type": "string" |
||||
}, |
||||
"trainingPlanId": { |
||||
"type": "number" |
||||
}, |
||||
"workoutItems": { |
||||
"type": "array", |
||||
"items": { |
||||
"type": "object", |
||||
"required": [], |
||||
"properties": { |
||||
"breakTime": { |
||||
"type": "number" |
||||
}, |
||||
"description": { |
||||
"type": "string" |
||||
}, |
||||
"elapsedTime": { |
||||
"type": "number" |
||||
}, |
||||
"finished": { |
||||
"type": "boolean" |
||||
}, |
||||
"imagePath": { |
||||
"type": "string" |
||||
}, |
||||
"isImagePathExternal": { |
||||
"type": "string" |
||||
}, |
||||
"isTimeMode": { |
||||
"type": "boolean" |
||||
}, |
||||
"isVideoMode": { |
||||
"type": "boolean" |
||||
}, |
||||
"isVideoPathExternal": { |
||||
"type": "string" |
||||
}, |
||||
"name": { |
||||
"type": "string" |
||||
}, |
||||
"orderNr": { |
||||
"type": "string" |
||||
}, |
||||
"prepTime": { |
||||
"type": "number" |
||||
}, |
||||
"repetitionCount": { |
||||
"type": "number" |
||||
}, |
||||
"videoPath": { |
||||
"type": "string" |
||||
}, |
||||
"workoutItemId": { |
||||
"type": "string" |
||||
}, |
||||
"workoutSessionId": { |
||||
"type": "number" |
||||
}, |
||||
"workoutTime": { |
||||
"type": "number" |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"workoutSessionId": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,25 @@
|
||||
exercises: |
||||
- name: nomoney |
||||
video: "https://www.youtube.com/watch?v=etAwQ4jzyNY" |
||||
start: 74 |
||||
end: 80 |
||||
- name: plank shoulder tap |
||||
video: "https://www.youtube.com/watch?v=etAwQ4jzyNY" |
||||
start: 113 |
||||
end: 116 |
||||
- name: standing ws |
||||
video: "https://www.youtube.com/watch?v=etAwQ4jzyNY" |
||||
start: 243 |
||||
end: 248 |
||||
- name: side plank |
||||
video: "https://www.youtube.com/watch?v=etAwQ4jzyNY" |
||||
start: 277 |
||||
end: 280 |
||||
- name: face pulls |
||||
video: "https://www.youtube.com/watch?v=etAwQ4jzyNY" |
||||
start: 413 |
||||
end: 417 |
||||
- name: recruitment pulls |
||||
video: "https://www.youtube.com/watch?v=etAwQ4jzyNY" |
||||
start: 541 |
||||
end: 548 |
@ -0,0 +1,43 @@
|
||||
import yaml |
||||
import pytube |
||||
import tempfile |
||||
import imageio |
||||
|
||||
from pathlib import Path |
||||
from functools import lru_cache |
||||
import moviepy.editor as mpy |
||||
|
||||
|
||||
FILE = 'data/input/samples/exercises.yaml' |
||||
|
||||
|
||||
@lru_cache(5) |
||||
def get_video(url): |
||||
output_dir = tempfile.mktemp() |
||||
video = pytube.YouTube(url) |
||||
video.streams.filter(res="360p").first().download(filename=output_dir) |
||||
return output_dir |
||||
|
||||
def create_gif_from_video_and_timestamps(video_path, start, end): |
||||
video = mpy.VideoFileClip(video_path) |
||||
clip: mpy.VideoFileClip = video.subclip(start, end) |
||||
output_dir = tempfile.mktemp() + '.mp4' |
||||
clip.set_fps(2) |
||||
clip.without_audio().write_videofile(output_dir) |
||||
return output_dir |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
file = open(FILE) |
||||
exercises = yaml.safe_load(file) |
||||
for ex in exercises['exercises']: |
||||
name = ex['name'] |
||||
video_url = ex['video'] |
||||
start = ex['start'] |
||||
end = ex['end'] |
||||
|
||||
video_path = get_video(video_url) |
||||
gif = create_gif_from_video_and_timestamps(video_path, start, end) |
||||
ex['gif_path'] = gif |
||||
|
||||
print(gif) |
@ -0,0 +1,17 @@
|
||||
# Cli-Coach |
||||
Creates a workout plan form an yaml file that can be imported to <img src="https://github.com/oliexdev/openWorkout/raw/master/fastlane/metadata/android/en-GB/images/icon.png" width="50"/> [openWorkout](https://github.com/oliexdev/openWorkout) android app. |
||||
|
||||
Inputs can be of format |
||||
```yaml |
||||
exercises: |
||||
- name: nomoney |
||||
video: "https://www.youtube.com/watch?v=etAwQ4jzyNY" |
||||
start: 74 |
||||
end: 80 |
||||
- name: plank shoulder tap |
||||
video: "https://www.youtube.com/watch?v=etAwQ4jzyNY" |
||||
start: 113 |
||||
end: 116 |
||||
``` |
||||
|
||||
The script will download the video and create short clips. |
Loading…
Reference in new issue