Browse Source

Base scripts create working openworkout file with videos

main
gabriel becker 1 year ago
parent
commit
3313298fa2
  1. 3
      .gitignore
  2. 60
      create_open_workout_database.py
  3. 13
      exercise_config.py
  4. 16
      load_exercises.py
  5. 121
      map_yaml_to_database.py

3
.gitignore vendored

@ -0,0 +1,3 @@
data
**.*mp4
**.*json

60
create_open_workout_database.py

@ -1,4 +1,4 @@
import json
WORKOUT_DATABASE = {
"countFinishedTraining": 0,
@ -11,7 +11,7 @@ WORKOUT_DATABASE = {
}
def create_work_database(name, workout_sessions):
def create_workout_database(name, workout_sessions):
new_db = dict(WORKOUT_DATABASE)
new_content = {
"name": name,
@ -32,10 +32,10 @@ WORKOUT_SESSION = {
}
def create_work_session(workout_items: list):
def create_workout_session(workout_items: list):
new_session = dict(WORKOUT_SESSION)
new_session_content = {
"workoutItems": workout_items
'workoutItems': workout_items
}
new_session.update(new_session_content)
return new_session
@ -43,49 +43,51 @@ def create_work_session(workout_items: list):
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.",
"description": "",
"elapsedTime": 0,
"finished": False,
"imagePath": "jumping_jack.png",
"isImagePathExternal": False,
"isTimeMode": True,
"isVideoMode": True,
"isVideoPathExternal": False,
"isVideoPathExternal": True,
"name": "Jumping Jack",
"orderNr": -1,
"prepTime": 5,
"repetitionCount": 5,
"videoPath": "jumping_jack.mp4",
"videoPath": "",
"workoutItemId": 0,
"workoutSessionId": 1,
"workoutTime": 30
}
def create_item():
def get_item_id():
start = 0
while True:
yield start
start += 1
def create_item(name, workout_time, n_repetitions, description=None, preparation_time=5, video_path=None):
is_video_mode = True if video_path else False
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
"name": name,
'description': description or '',
'elapsedTime': 0,
'imagePath': '',
'isImagePathExternal': False,
'isTimeMode': True,
'isVideoMode': is_video_mode,
'prepTime': preparation_time,
'repetitionCount': n_repetitions,
'videoPath': video_path,
"orderNr": next(get_item_id()),
"workoutItemId": 0,
"workoutSessionId": 1,
'workoutTime': workout_time
}
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()

13
exercise_config.py

@ -0,0 +1,13 @@
from dataclasses import dataclass
@dataclass
class ExerciseConfig:
name: str
video: str
start: int
end: int
@dataclass
class WorkoutConfig:
pass

16
load_exercises.py

@ -1,16 +1,10 @@
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()
@ -18,26 +12,26 @@ def get_video(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)
def load_file_and_media_links(file_path):
file = open(file_path)
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)
return exercises

121
map_yaml_to_database.py

@ -0,0 +1,121 @@
import json
import tempfile
import zipfile
import os
from load_exercises import load_file_and_media_links
from create_open_workout_database import create_workout_session, create_item, create_workout_database
ITEM_KEY_MEDIA_TYPE_MAP = {
'video': 'videoPath',
'image': 'imagePath',
}
def get_all_media_from_db_by_type(db, media_type):
item_key = ITEM_KEY_MEDIA_TYPE_MAP[media_type]
media = list()
for session in db['workoutSessions']:
for workout_item in session['workoutItems']:
media.append(workout_item[item_key])
media = list(set(media))
return media
def map_source_destination(media_files, root_destination):
media_maps = list()
for file_path in media_files:
dest = get_destination_maps(file_path, root_destination)
media_maps.append((file_path, dest))
return media_maps
def get_destination_maps(input_path, relative_destination):
file = os.path.basename(input_path)
destination_file_path = f'{relative_destination}/{file}'
return destination_file_path
def get_remote_formatted_media_path(root_name: str, media_type: str, file_path: str):
actual_file = os.path.basename(file_path)
remote_root = 'file:///data/user/0/com.health.openworkout/files'
new_media_path = f'{remote_root}/{root_name}/{media_type}/{actual_file}'
return new_media_path
def refactor_media_paths_in_db(db):
db_name = db['name']
for session in db['workoutSessions']:
for workout_item in session['workoutItems']:
item_has_video = workout_item['videoPath'] != ''
if item_has_video:
new_formatted_path = get_remote_formatted_media_path(
media_type='video',
root_name=db_name,
file_path=workout_item['videoPath']
)
workout_item['videoPath'] = new_formatted_path
item_has_image = workout_item['imagePath'] != ''
if item_has_image:
new_formatted_path = get_remote_formatted_media_path(
media_type='image',
root_name=db_name,
file_path=workout_item['imagePath']
)
workout_item['imagePath'] = new_formatted_path
return db
def save_workout_file(output_files, db_file, video_files=tuple(), image_files=tuple()):
video_maps = map_source_destination(video_files, 'video')
image_maps = map_source_destination(image_files, 'image')
media_maps = video_maps + image_maps
db_json = tempfile.mktemp()
with open(db_json, 'w') as f:
json.dump(db_file, f)
with zipfile.ZipFile(output_files, 'w') as zip_file:
zip_file.write(db_json, arcname='database.json')
for source, dest in media_maps:
zip_file.write(source, arcname=dest)
def map_config_to_workout_file(config):
items = [
create_item(
name=item['name'],
workout_time=30,
n_repetitions=1,
description=None,
preparation_time=5,
video_path=item['gif_path']
)
for item in config['exercises']
]
sessions = [create_workout_session(items)] * 30
db = create_workout_database(config['name'], sessions)
return db
def process_config_into_workout_file(config, output_file = None):
db = map_config_to_workout_file(config)
videos = get_all_media_from_db_by_type(db, media_type='video')
images = get_all_media_from_db_by_type(db, media_type='image')
db = refactor_media_paths_in_db(db)
output_file_name = output_file or f"{db['name']}.zip"
save_workout_file(
output_files=output_file_name,
db_file=db,
video_files=videos,
)
FILE = 'data/input/samples/exercises.yaml'
if __name__ == '__main__':
config = load_file_and_media_links(FILE)
process_config_into_workout_file(config)
Loading…
Cancel
Save