Edit: v2 with rudimentary break detection. Any gaps larger than 4 seconds by default are treated as a break. Pass in an integer as the second argument (i.e. python script.py cockherowhatever.funscript 3) and it'll use that as the number of seconds instead.
Code: Select all
import json
import sys
with open(sys.argv[1]) as f:
json_string = ','.join(f.readlines())
if len(sys.argv) > 2:
break_secs = int(sys.argv[2])
else:
break_secs = 4
funscript = json.loads(json_string)
actions = funscript['actions']
assert len(set([x['pos'] for x in actions])) == 2
bottom_val = max([x['pos'] for x in actions])
top_val = min([x['pos'] for x in actions])
new_actions = []
for idx in range(len(actions) - 1):
if actions[idx]['pos'] == actions[idx + 1]['pos']:
# Definitely a break
actions[idx]['pos'] = bottom_val
new_actions.append(actions[idx])
continue
if actions[idx+1]['at'] - actions[idx]['at'] > break_secs * 1000:
# Long pause between beats, probably a break
actions[idx]['pos'] = bottom_val
new_actions.append(actions[idx])
continue
midframe = int((actions[idx]['at'] + actions[idx+1]['at']) / 2)
midframe_action = {
'pos': top_val,
'at': midframe
}
actions[idx]['pos'] = bottom_val
new_actions.append(actions[idx])
new_actions.append(midframe_action)
new_actions.append(actions[-1])
new_funscript = {
'version': funscript['version'],
'inverted': funscript['inverted'],
'range': funscript['range'],
'actions': new_actions
}
new_filename = sys.argv[1].split('.')
new_filename = '.'.join(new_filename[:-1]) + '.new.' + str(new_filename[-1])
with open(new_filename, 'w') as f:
f.write(json.dumps(new_funscript))


