Merge tag 'v10.79' into develop
mini video view
This commit is contained in:
4
app.py
4
app.py
@@ -1,8 +1,10 @@
|
||||
#!/usr/bin/env python
|
||||
#!/srv/bin/venv python3.6
|
||||
import os
|
||||
import sys
|
||||
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "rowsandall_app.settings")
|
||||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
application = get_wsgi_application()
|
||||
|
||||
#execute_from_command_line(sys.argv)
|
||||
|
||||
@@ -40,6 +40,10 @@
|
||||
$(this).removeAttr('disabled');
|
||||
});
|
||||
});
|
||||
document.getElementById("smallscreen").style.display = "none";
|
||||
if ($(window).width() <= 950) {
|
||||
$("#smallscreen").show()
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
@@ -104,6 +108,12 @@ function copyText() {
|
||||
{% language 'en' %}
|
||||
<h1>Video Analysis for {{ workout.name }}</h1>
|
||||
<ul class="main-content">
|
||||
<li class="grid_4" id="smallscreen">
|
||||
<p>Your screen is too small to show the full functionality. Click
|
||||
<a href="/rowers/video/{{ analysis.id|encode }}/m">here</a>
|
||||
to get to a version that is better suited for small screens.
|
||||
</p>
|
||||
</li>
|
||||
{% if user.is_authenticated and user == workout.user.user and not locked %}
|
||||
<li class="grid_2">
|
||||
<p>Paste link to you tube video below</p>
|
||||
|
||||
682
rowers/templates/embedded_video_mini.html
Normal file
682
rowers/templates/embedded_video_mini.html
Normal file
@@ -0,0 +1,682 @@
|
||||
{% extends "newbase.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load rowerfilters %}
|
||||
{% load i18n %}
|
||||
{% load leaflet_tags %}
|
||||
|
||||
|
||||
|
||||
{% block title %}Workout Video{% endblock %}
|
||||
{% block og_title %}{{ analysis.name }}{% endblock %}
|
||||
{% block description %}Rowing Video Analysis:{{ analysis.name }}{% endblock %}
|
||||
{% block og_description %}Rowing Video Analysis:{{ analysis.name }}{% endblock %}
|
||||
{% block og_image %}
|
||||
{% if analysis %}
|
||||
<meta property="og:image" content="https://img.youtube.com/vi/{{ analysis.video_id }}/hqdefault.jpg" />
|
||||
<meta property="og:image:secure_url" content="https://img.youtube.com/vi/{{ analysis.video_id }}/hqdefault.jpg" />
|
||||
{% else %}
|
||||
<meta property="og:image" content="http://rowsandall.com/static/img/logo_r.png" />
|
||||
<meta property="og:image:secure_url" content="https://rowsandall.com/static/img/logo_r.png" />
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% if analysis %}
|
||||
{% block image_src %}
|
||||
<link rel="image_src" href="https://img.youtube.com/vi/{{ analysis.video_id }}/hqdefault.jpg" />
|
||||
{% endblock %}
|
||||
{% endif %}
|
||||
|
||||
{% block meta %}
|
||||
{% leaflet_js %}
|
||||
{% leaflet_css %}
|
||||
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
|
||||
<script type="text/javascript" src="{% static 'js/videogauges.js' %}"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.js"></script>
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('form').submit(function(e) {
|
||||
$(':disabled').each(function(e) {
|
||||
$(this).removeAttr('disabled');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
function copyText() {
|
||||
var tempInput = document.createElement("input");
|
||||
tempInput.style = "position: absolute; left: -1000px; top: -1000px";
|
||||
tempInput.value = "{{ siteurl }}/rowers/video/{{ analysis.id|encode }}/";
|
||||
document.body.appendChild(tempInput);
|
||||
tempInput.select();
|
||||
document.execCommand("copy");
|
||||
alert("Copied to clipboard: " + tempInput.value);
|
||||
document.body.removeChild(tempInput);
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
|
||||
<style>
|
||||
.slidecontainer {
|
||||
width: 100%; /* Width of the outside container */
|
||||
}
|
||||
|
||||
.bold { font-weight: bold; }
|
||||
|
||||
/* The slider itself */
|
||||
.slider {
|
||||
-webkit-appearance: none; /* Override default CSS styles */
|
||||
appearance: none;
|
||||
width: 100%; /* Full-width */
|
||||
height: 25px; /* Specified height */
|
||||
background: #d3d3d3; /* Grey background */
|
||||
outline: none; /* Remove outline */
|
||||
opacity: 0.7; /* Set transparency (for mouse-over effects on hover) */
|
||||
-webkit-transition: .2s; /* 0.2 seconds transition on hover */
|
||||
transition: opacity .2s;
|
||||
}
|
||||
|
||||
/* Mouse-over effects */
|
||||
.slider:hover {
|
||||
opacity: 1; /* Fully shown on mouse-over */
|
||||
}
|
||||
|
||||
/* The slider handle (use -webkit- (Chrome, Opera, Safari, Edge) and -moz- (Firefox) to override default look) */
|
||||
.slider::-webkit-slider-thumb {
|
||||
-webkit-appearance: none; /* Override default look */
|
||||
appearance: none;
|
||||
width: 25px; /* Set a specific slider handle width */
|
||||
height: 25px; /* Slider handle height */
|
||||
background: #4CAF50; /* Green background */
|
||||
cursor: pointer; /* Cursor on hover */
|
||||
}
|
||||
|
||||
.slider::-moz-range-thumb {
|
||||
width: 25px; /* Set a specific slider handle width */
|
||||
height: 25px; /* Slider handle height */
|
||||
background: #4CAF50; /* Green background */
|
||||
cursor: pointer; /* Cursor on hover */
|
||||
}
|
||||
</style>
|
||||
|
||||
{% language 'en' %}
|
||||
<h1>Video Analysis for {{ workout.name }}</h1>
|
||||
<ul class="main-content">
|
||||
<li class="grid_4">
|
||||
<p>Playing the video will advance the data in synchronization. Use the regular
|
||||
YouTube controls to move around in the video and play it.</p>
|
||||
</li>
|
||||
<li class="grid_4">
|
||||
<span class="fb-share-button" style="height:20px; vertical-align: top;"
|
||||
data-href="{{ siteurl }}/rowers/video/{{ analysis.id|encode }}"
|
||||
data-layout="button" data-size="small" data-mobile-iframe="false">
|
||||
<a class="fb-xfbml-parse-ignore" target="_blank"
|
||||
href="https://www.facebook.com/sharer/sharer.php?u=https://rowsandall.com/rowers/video/{{ analysis.id|encode }}/">
|
||||
Share</a>
|
||||
</span>
|
||||
<span>
|
||||
<a class="twitter-share-button"
|
||||
href="https://twitter.com/intent/tweet"
|
||||
data-url="{{ siteurl }}/rowers/video/{{ analysis.id|encode }}/"
|
||||
data-text="@rowsandall #rowingdata">Tweet</a>
|
||||
</span>
|
||||
<span>
|
||||
<button title="Copy Shareable Link" onclick="copyText()"
|
||||
style="color:#1c75bc;background:none;border:0;"><i class="fas fa-copy"></i></button>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="main-content">
|
||||
<li class="grid_3">
|
||||
<div id="theplot" class="flexplot mapdiv">
|
||||
{{ mapdiv | safe}}
|
||||
|
||||
</div>
|
||||
<div class="slidecontainer">
|
||||
<input type="range" min="0" max="{{ maxtime }}" value="{{ analysis.delay }}"
|
||||
id="myRange">
|
||||
</div>
|
||||
<div id="dataplay"></div>
|
||||
<!-- <div id="datastop"></div> -->
|
||||
</li>
|
||||
<li class="grid_4">
|
||||
<div id="player"></div>
|
||||
<script>
|
||||
// 1. Code for the map
|
||||
{{ mapscript | safe }}
|
||||
|
||||
|
||||
// 2. This code loads the IFrame Player API code asynchronously.
|
||||
var tag = document.createElement('script');
|
||||
|
||||
tag.src = "https://www.youtube.com/iframe_api";
|
||||
var firstScriptTag = document.getElementsByTagName('script')[0];
|
||||
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
|
||||
|
||||
// 3. This function creates an <iframe> (and YouTube player)
|
||||
// after the API code downloads.
|
||||
var player;
|
||||
var playing = false;
|
||||
var dataplaying = false;
|
||||
|
||||
var videotime = 0;
|
||||
var data = JSON.parse('{{ data|safe }}');
|
||||
{% for id, metric in metrics.items %}
|
||||
var {{ id }}_values = data["{{ id }}"];
|
||||
// console.log("{{ id }}_values",{{ id }}_values);
|
||||
{% endfor %}
|
||||
// var boatspeed = data["boatspeed"];
|
||||
var latitude = data["latitude"];
|
||||
var longitude = data["longitude"];
|
||||
// var spm = data["spm"];
|
||||
// var ctch = data["catch"];
|
||||
|
||||
function onYouTubeIframeAPIReady() {
|
||||
player = new YT.Player('player', {
|
||||
height: '315',
|
||||
width: '560',
|
||||
modestbranding: '1',
|
||||
videoId: '{{ video_id }}',
|
||||
events: {
|
||||
'onReady': onPlayerReady,
|
||||
'onStateChange': onPlayerStateChange
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 4. The API will call this function when the video player is ready.
|
||||
function onPlayerReady(event) {
|
||||
// event.target.playVideo();
|
||||
|
||||
|
||||
}
|
||||
|
||||
function updateTime() {
|
||||
var oldTime = videotime;
|
||||
var slider = document.getElementById("myRange");
|
||||
var lock = document.getElementById("lock");
|
||||
if(player && player.getCurrentTime) {
|
||||
videotime = player.getCurrentTime();
|
||||
var delay = document.getElementById("id_delay").value;
|
||||
if (lock.checked) {
|
||||
sliderpos = Math.round(videotime) + Math.round(delay);
|
||||
slider.value = sliderpos;
|
||||
}
|
||||
|
||||
|
||||
// gauge.set(catch_now);
|
||||
|
||||
}
|
||||
if(videotime !== oldTime) {
|
||||
onProgress(videotime);
|
||||
}
|
||||
}
|
||||
|
||||
timeupdater = setInterval(updateTime, 1000);
|
||||
|
||||
// when the time changes, this will be called.
|
||||
function onProgress(currentTime) {
|
||||
var slider = document.getElementById("myRange");
|
||||
var lock = document.getElementById("lock");
|
||||
videotime = player.getCurrentTime();
|
||||
var delay = document.getElementById("id_delay").value;
|
||||
var output = document.getElementById("id_delay");
|
||||
datatime = slider.value;
|
||||
|
||||
if (lock.checked) {
|
||||
if (!dataplaying) { // set data values
|
||||
sliderpos = Math.round(videotime) + Math.round(delay);
|
||||
slider.value = sliderpos;
|
||||
|
||||
// Setting Data
|
||||
// velo = boatspeed[Math.round(datatime)];
|
||||
lat = latitude[Math.round(datatime)];
|
||||
lon = longitude[Math.round(datatime)];
|
||||
// strokerate = spm[Math.round(datatime)];
|
||||
// catchangle = ctch[Math.round(datatime)];
|
||||
{% for id, metric in metrics.items %}
|
||||
{{ id }}_now = {{ id }}_values[Math.round(datatime)];
|
||||
// console.log(datatime,{{ id }},{{ id }}_now, "{{ metric.name }}")
|
||||
{% endfor %}
|
||||
|
||||
{% for group in metricsgroups %}
|
||||
try {
|
||||
set_{{ group }}();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
{% endfor %}
|
||||
try {
|
||||
var newLatLng = new L.LatLng(lat, lon);
|
||||
// console.log(newLatLng);
|
||||
marker.setLatLng(newLatLng);
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!dataplaying) {
|
||||
output.value = Math.round(datatime)-Math.round(videotime);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function stopVideo() {
|
||||
player.pauseVideo();
|
||||
playing = false;
|
||||
}
|
||||
|
||||
// call this function when player state changes
|
||||
function onPlayerStateChange(event) {
|
||||
if (event.data == YT.PlayerState.PLAYING && lock.checked) {
|
||||
var dataplay = document.getElementById("dataplay").childNodes[0];
|
||||
dataplay.value = String.fromCharCode(10074,10074);
|
||||
} else if (lock.checked) {
|
||||
var dataplay = document.getElementById("dataplay").childNodes[0];
|
||||
dataplay.value = String.fromCharCode(9658);
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
</li>
|
||||
<li class="grid_4">
|
||||
<input type="hidden" name="lock" id="lock" value="Lock">
|
||||
</li>
|
||||
</ul>
|
||||
<p> </p>
|
||||
<form enctype="multipart/form-data" action="" method="post">
|
||||
<ul class="main-content">
|
||||
<li class="grid_4">
|
||||
<input type="hidden" id="id_delay" value="{{ analysis.delay }}">
|
||||
</li>
|
||||
|
||||
<li class="grid_4" >
|
||||
<ul class="main-content">
|
||||
{% if 'basic' in metricsgroups %}
|
||||
<li class="grid_1">
|
||||
<div id="basic_spm"></div>
|
||||
</li>
|
||||
<li class="grid_1">
|
||||
<div id="basic_boatspeed"></div>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if 'forcepower' in metricsgroups %}
|
||||
<li class="grid_1">
|
||||
<div id="forcepower_power"></div>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if 'athlete' in metricsgroups %}
|
||||
<li class="grid_1">
|
||||
<div id="athlete_hr"></div>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if 'stroke' in metricsgroups %}
|
||||
{% if workout.workouttype == 'water' %}
|
||||
<li class="grid_1" style="height:500px">
|
||||
<div style="width:100%;height:70%;" id="stroke_angles"></div>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</form>
|
||||
<p> </p>
|
||||
|
||||
<script>
|
||||
$(document).ready( function() {
|
||||
$(window).load(function() {
|
||||
// initialize data fields
|
||||
console.log('initializing first value of data');
|
||||
{% for id, metric in metrics.items %}
|
||||
{{ id }}_now = {{ id }}_values[0];
|
||||
|
||||
{% endfor %}
|
||||
|
||||
var slider = document.getElementById("myRange");
|
||||
|
||||
|
||||
// gauge settings
|
||||
{% if workout.workouttype != 'water' %}
|
||||
speedoptions.max = 7;
|
||||
speedoptions.redTo = 7;
|
||||
speedoptions.majorTicks = ['0','1','2','3','4','5','6','7'];
|
||||
{% endif %}
|
||||
|
||||
{% if 'basic' in metricsgroups %}
|
||||
spm_now = spm_values[0];
|
||||
boatspeed_now = boatspeed_values[0];
|
||||
set_basic();
|
||||
{% endif %}
|
||||
{% if 'forcepower' in metricsgroups %}
|
||||
poweroptions.max = {{ workout.user.pw_an|add:100|round100 }};
|
||||
poweroptions.greenFrom = {{ workout.user.pw_ut2 }};
|
||||
poweroptions.greenTo = {{ workout.user.pw_at }};
|
||||
poweroptions.yellowFrom = {{ workout.user.pw_at }};
|
||||
poweroptions.yellowTo = {{ workout.user.pw_an }};
|
||||
poweroptions.redFrom = {{ workout.user.pw_an }};
|
||||
poweroptions.redTo = {{ workout.user.pw_an|add:100|round100 }};
|
||||
poweroptions.majorTicks = {{ workout.user.pw_an|add:100|round100|majorticks }};
|
||||
{% if workout.workouttype == 'water' %}
|
||||
poweroptions.max = {{ workout.user.pw_an|waterpower:workout.user|add:100|round100 }}
|
||||
poweroptions.greenFrom = {{ workout.user.pw_ut2|waterpower:workout.user }};
|
||||
poweroptions.greenTo = {{ workout.user.pw_at|waterpower:workout.user }};
|
||||
poweroptions.yellowFrom = {{ workout.user.pw_at|waterpower:workout.user }};
|
||||
poweroptions.yellowTo = {{ workout.user.pw_an|waterpower:workout.user }};
|
||||
poweroptions.redFrom = {{ workout.user.pw_an|waterpower:workout.user }};
|
||||
poweroptions.redTo = {{ workout.user.pw_an|waterpower:workout.user|add:100|round100 }};
|
||||
poweroptions.majorTicks = {{ workout.user.pw_an|waterpower:workout.user|add:100|round100|majorticks }};
|
||||
{% endif %}
|
||||
power_now = power_values[0];
|
||||
set_forcepower();
|
||||
{% endif %}
|
||||
{% if 'athlete' in metricsgroups %}
|
||||
hroptions.max = {{ workout.user.max|round20 }}
|
||||
hroptions.greenFrom = {{ workout.user.ut2 }}
|
||||
hroptions.greenTo = {{ workout.user.at }}
|
||||
hroptions.yellowFrom = {{ workout.user.at }}
|
||||
hroptions.yellowTo = {{ workout.user.an }}
|
||||
hroptions.redFrom = {{ workout.user.an }}
|
||||
hroptions.redTo = {{ workout.user.max }}
|
||||
hroptions.majorTicks = {{ workout.user.max|round20|hrmajorticks:workout.user.rest }}
|
||||
hr_now = hr_values[0];
|
||||
set_athlete();
|
||||
{% endif %}
|
||||
{% if 'stroke' in metricsgroups %}
|
||||
{% if workout.workouttype == 'water' %}
|
||||
anglesoptions.PieStartAngle = 90+catch_now;
|
||||
set_stroke();
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
// cookie reader
|
||||
function createCookie(name,value,days) {
|
||||
if (days) {
|
||||
var date = new Date();
|
||||
date.setTime(date.getTime()+(days*24*60*60*1000));
|
||||
var expires = "; expires="+date.toGMTString();
|
||||
}
|
||||
else var expires = "";
|
||||
document.cookie = name+"="+value+expires+"; path=/";
|
||||
}
|
||||
function readCookie(name) {
|
||||
var nameEQ = name + "=";
|
||||
var ca = document.cookie.split(';');
|
||||
for(var i=0;i < ca.length;i++) {
|
||||
var c = ca[i];
|
||||
while (c.charAt(0)==' ') c = c.substring(1,c.length);
|
||||
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
// lock
|
||||
var lock = document.getElementById("lock");
|
||||
var output = document.getElementById("id_delay");
|
||||
var cookie = readCookie("lock{{ workout.id }}");
|
||||
var delay = output.value;
|
||||
if (cookie=="true") {
|
||||
lock.checked = true;
|
||||
output.disabled = true;
|
||||
}
|
||||
|
||||
// lock.onchange nog doen
|
||||
|
||||
{% if locked %}
|
||||
lock.checked = true;
|
||||
output.disabled = true;
|
||||
{% endif %}
|
||||
|
||||
|
||||
// slider
|
||||
var slider = document.getElementById("myRange");
|
||||
{% if user.is_authenticated and user == workout.user.user %}
|
||||
document.getElementById("myRange").style.display = "block";
|
||||
{% else %}
|
||||
document.getElementById("myRange").style.display = "none";
|
||||
{% endif %}
|
||||
var output = document.getElementById("id_delay");
|
||||
|
||||
// Update the current slider value (each time you drag the slider handle)
|
||||
slider.oninput = function() {
|
||||
if (!lock.checked) {
|
||||
try {
|
||||
|
||||
delay = Math.round(slider.value)-Math.round(player.getCurrentTime());
|
||||
output.value = Math.round(slider.value)-Math.round(player.getCurrentTime()); // Display the default slider value
|
||||
}
|
||||
catch(err) {
|
||||
output.value = Math.round(slider.value);
|
||||
delay = Math.round(slider.value);
|
||||
}
|
||||
}
|
||||
clearInterval(timeupdater);
|
||||
var datatime = this.value
|
||||
var videotime = Math.round(player.getCurrentTime());
|
||||
if (lock.checked) {
|
||||
if (this.value-output.value > 0) {
|
||||
player.seekTo(this.value-output.value);
|
||||
videotime = this.value-output.value;
|
||||
} else {
|
||||
if (playing && !dataplaying) {
|
||||
player.seekTo(0);
|
||||
player.playVideo();
|
||||
}
|
||||
else if (!playing && !dataplaying) {
|
||||
player.seekTo(0);
|
||||
player.pauseVideo();
|
||||
playing = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// console.log('changing, not checked');
|
||||
output.value = this.value-Math.round(player.getCurrentTime());
|
||||
}
|
||||
|
||||
// Setting Data
|
||||
// velo = boatspeed[Math.round(datatime)];
|
||||
lat = latitude[Math.round(datatime)];
|
||||
lon = longitude[Math.round(datatime)];
|
||||
// strokerate = spm[Math.round(datatime)];
|
||||
// catchangle = ctch[Math.round(datatime)];
|
||||
{% for id, metric in metrics.items %}
|
||||
{{ id }}_now = {{ id }}_values[Math.round(datatime)];
|
||||
// console.log(datatime,{{ id }}_now, "{{ metric.name }}")
|
||||
{% endfor %}
|
||||
|
||||
{% for group in metricsgroups %}
|
||||
try {
|
||||
set_{{ group }}();
|
||||
} catch (e) {
|
||||
}
|
||||
{% endfor %}
|
||||
try {
|
||||
var newLatLng = new L.LatLng(lat, lon);
|
||||
// console.log(newLatLng);
|
||||
marker.setLatLng(newLatLng);
|
||||
} catch (e) {
|
||||
}
|
||||
timeupdater = setInterval(updateTime, 1000);
|
||||
}
|
||||
|
||||
output.oninput = function() {
|
||||
slider.value = this.value+Math.round(player.getCurrentTime());
|
||||
}
|
||||
|
||||
|
||||
// Update the current slider value (each time the slider is changed)
|
||||
slider.onchange = function() {
|
||||
clearInterval(timeupdater)
|
||||
if (lock.checked) {
|
||||
if (this.value-output.value > 0) {
|
||||
player.seekTo(this.value-output.value);
|
||||
if (playing) {
|
||||
player.playVideo();
|
||||
} else {
|
||||
player.pauseVideo();
|
||||
}
|
||||
} else {
|
||||
if (playing) {
|
||||
player.seekTo(0);
|
||||
player.playVideo();
|
||||
}
|
||||
else {
|
||||
player.seekTo(0);
|
||||
player.pauseVideo();
|
||||
playing = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
output.value = this.value-Math.round(player.getCurrentTime());
|
||||
}
|
||||
var datatime = this.value
|
||||
var videotime = Math.round(player.getCurrentTime());
|
||||
//
|
||||
// Setting Data
|
||||
// velo = boatspeed[Math.round(datatime)];
|
||||
lat = latitude[Math.round(datatime)];
|
||||
lon = longitude[Math.round(datatime)];
|
||||
// strokerate = spm[Math.round(datatime)];
|
||||
// catchangle = ctch[Math.round(datatime)];
|
||||
{% for id, metric in metrics.items %}
|
||||
{{ id }}_now = {{ id }}_values[Math.round(datatime)];
|
||||
// console.log(datatime,{{ id }}_now, "{{ metric.name }}")
|
||||
{% endfor %}
|
||||
|
||||
{% for group in metricsgroups %}
|
||||
try {
|
||||
set_{{ group }}();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
{% endfor %}
|
||||
try {
|
||||
var newLatLng = new L.LatLng(lat, lon);
|
||||
// console.log(newLatLng);
|
||||
marker.setLatLng(newLatLng);
|
||||
} catch (e) {
|
||||
console.log('error')
|
||||
}
|
||||
console.log('changed all')
|
||||
timeupdater = setInterval(updateTime, 1000);
|
||||
}
|
||||
|
||||
output.oninput = function() {
|
||||
slider.value = this.value+Math.round(player.getCurrentTime());
|
||||
}
|
||||
|
||||
// lock delay form field if checkbox checked
|
||||
lock.oninput = function() {
|
||||
if (this.checked) {
|
||||
output.disabled = true;
|
||||
createCookie("lock{{ workout.id}}","true",0);
|
||||
} else {
|
||||
output.disabled = false;
|
||||
createCookie("lock{{ workout.id }}","false",0);
|
||||
}
|
||||
}
|
||||
// Slider start stop
|
||||
// moet de buttons pas hieronder definieren en dan in de html
|
||||
// pluggen
|
||||
var timer;
|
||||
|
||||
|
||||
function clock() {
|
||||
timer = setInterval(myClock, 1000);
|
||||
var c = parseInt(slider.value,10);
|
||||
console.log('starting clock');
|
||||
|
||||
function myClock() {
|
||||
c = c+1;
|
||||
slider.value = c;
|
||||
|
||||
// update data fields
|
||||
lat = latitude[Math.round(c)];
|
||||
lon = longitude[Math.round(c)];
|
||||
{% for id, metric in metrics.items %}
|
||||
{{ id }}_now = {{ id }}_values[Math.round(c)];
|
||||
// console.log(datatime,{{ id }}_now, "{{ metric.name }}")
|
||||
{% endfor %}
|
||||
|
||||
|
||||
{% for group in metricsgroups %}
|
||||
try {
|
||||
set_{{ group }}();
|
||||
} catch (e) {}
|
||||
{% endfor %}
|
||||
try {
|
||||
var newLatLng = new L.LatLng(lat, lon);
|
||||
// console.log(newLatLng);
|
||||
marker.setLatLng(newLatLng);
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
if (lock.checked) {
|
||||
player.seekTo(c+parseInt(output.value));
|
||||
} else {
|
||||
delay = Math.round(slider.value)-Math.round(player.getCurrentTime());
|
||||
output.value = Math.round(slider.value)-Math.round(player.getCurrentTime());
|
||||
}
|
||||
|
||||
if (c == latitude.length) {
|
||||
clearInterval(timer);
|
||||
c = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// onderstaande alleen als lock.checked
|
||||
var dataplay = document.createElement("input");
|
||||
dataplay.type = "button";
|
||||
dataplay.value = String.fromCharCode(9658);
|
||||
document.getElementById("dataplay").appendChild(dataplay);
|
||||
|
||||
// var datastop = document.createElement("input");
|
||||
// datastop.type = "button";
|
||||
// datastop.value = "Stop";
|
||||
// document.getElementById("datastop").appendChild(datastop)
|
||||
|
||||
|
||||
|
||||
dataplay.onclick = function() {
|
||||
if (lock.checked) {
|
||||
dataplaying = false;
|
||||
if (playing == false) {
|
||||
player.playVideo();
|
||||
dataplay.value = String.fromCharCode(10074,10074);
|
||||
playing = true;
|
||||
} else {
|
||||
player.pauseVideo();
|
||||
dataplay.value = String.fromCharCode(9658);
|
||||
playing = false;
|
||||
}
|
||||
} else {
|
||||
if (!dataplaying) {
|
||||
clock();
|
||||
dataplay.value = String.fromCharCode(10074,10074);
|
||||
dataplaying = true;
|
||||
if (lock.checked) {
|
||||
playing = true;
|
||||
}
|
||||
} else {
|
||||
clearInterval(timer);
|
||||
dataplay.value = String.fromCharCode(9658);
|
||||
dataplaying = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
{% endlanguage %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
{% include 'menu_workout.html' %}
|
||||
{% endblock %}
|
||||
@@ -346,6 +346,8 @@ urlpatterns = [
|
||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/video/$',views.workout_video_create_view,
|
||||
name='workout_video_create_view'),
|
||||
re_path(r'^video/(?P<pk>\d+)/delete/$',views.VideoDelete.as_view(),name='video_delete'),
|
||||
re_path(r'^video/(?P<id>\w.+)/m/$',views.workout_video_view_mini,
|
||||
name='workout_video_view_mini'),
|
||||
re_path(r'^video/(?P<id>\w.+)/$',views.workout_video_view,
|
||||
name='workout_video_view'),
|
||||
re_path(r'^videos/',views.list_videos,name='list_videos'),
|
||||
|
||||
@@ -48,6 +48,116 @@ def get_video_id(url):
|
||||
else:
|
||||
raise ValueError
|
||||
|
||||
# Show a video compared with data
|
||||
def workout_video_view_mini(request,id=''):
|
||||
try:
|
||||
id = encoder.decode_hex(id)
|
||||
analysis = VideoAnalysis.objects.get(id=id)
|
||||
except VideoAnalysis.DoesNotExist:
|
||||
raise Http404("Video Analysis does not exist")
|
||||
|
||||
w = analysis.workout
|
||||
delay = analysis.delay
|
||||
|
||||
if w.workouttype in mytypes.otwtypes:
|
||||
mode = 'water'
|
||||
else:
|
||||
mode = 'erg'
|
||||
|
||||
if request.user.is_authenticated:
|
||||
mayedit = checkworkoutuser(request.user,w) and isprorower(request.user.rower)
|
||||
rower = request.user.rower
|
||||
else:
|
||||
mayedit = False
|
||||
rower = None
|
||||
|
||||
# get video ID and offset
|
||||
if mayedit and request.method == 'POST':
|
||||
form = VideoAnalysisCreateForm(request.POST)
|
||||
metricsform = VideoAnalysisMetricsForm(request.POST,mode=mode)
|
||||
if form.is_valid() and metricsform.is_valid():
|
||||
video_id = form.cleaned_data['url']
|
||||
try:
|
||||
video_id = get_video_id(form.cleaned_data['url'])
|
||||
except (TypeError,ValueError):
|
||||
pass
|
||||
delay = form.cleaned_data['delay']
|
||||
metricsgroups = metricsform.cleaned_data['groups']
|
||||
if 'save_button' in request.POST:
|
||||
analysis.name = form.cleaned_data['name']
|
||||
analysis.video_id = video_id
|
||||
analysis.delay = delay
|
||||
analysis.metricsgroups = metricsgroups
|
||||
analysis.save()
|
||||
else:
|
||||
video_id = id
|
||||
delay = 0
|
||||
elif mayedit:
|
||||
form = VideoAnalysisCreateForm(
|
||||
initial = {
|
||||
'name':analysis.name,
|
||||
'delay': analysis.delay,
|
||||
'url': analysis.video_id,
|
||||
}
|
||||
)
|
||||
metricsform = VideoAnalysisMetricsForm(initial={'groups':analysis.metricsgroups},
|
||||
mode=mode)
|
||||
metricsgroups = analysis.metricsgroups
|
||||
video_id = analysis.video_id
|
||||
else:
|
||||
form = None
|
||||
metricsform = None
|
||||
metricsgroups = analysis.metricsgroups
|
||||
|
||||
data, metrics, maxtime = dataprep.get_video_data(w,groups=metricsgroups,mode=mode)
|
||||
hascoordinates = pd.Series(data['latitude']).std() > 0
|
||||
# create map
|
||||
if hascoordinates:
|
||||
mapscript, mapdiv = leaflet_chart_video(data['latitude'],data['longitude'],
|
||||
w.name)
|
||||
else:
|
||||
mapscript, mapdiv = interactive_chart_video(data)
|
||||
data['longitude'] = data['spm']
|
||||
data['latitude'] = list(range(len(data['spm'])))
|
||||
|
||||
|
||||
breadcrumbs = [
|
||||
{
|
||||
'url':'/rowers/list-workouts/',
|
||||
'name':'Workouts'
|
||||
},
|
||||
{
|
||||
'url':get_workout_default_page(request,encoder.encode_hex(w.id)),
|
||||
'name': w.name
|
||||
},
|
||||
{
|
||||
'url':reverse('workout_video_view',kwargs={'id':encoder.encode_hex(analysis.id)}),
|
||||
'name': 'Video Analysis'
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
|
||||
return render(request,
|
||||
'embedded_video_mini.html',
|
||||
{
|
||||
'workout':w,
|
||||
'rower':rower,
|
||||
'data': json.dumps(data,default=default),
|
||||
'mapscript': mapscript,
|
||||
'mapdiv': mapdiv,
|
||||
'video_id': analysis.video_id,
|
||||
'form':form,
|
||||
'breadcrumbs':breadcrumbs,
|
||||
'analysis':analysis,
|
||||
'maxtime':maxtime,
|
||||
'metrics':metrics,
|
||||
'locked': True,
|
||||
'metricsform':metricsform,
|
||||
'metricsgroups': metricsgroups,
|
||||
'siteurl': settings.SITE_URL,
|
||||
})
|
||||
|
||||
|
||||
# Show a video compared with data
|
||||
def workout_video_view(request,id=''):
|
||||
|
||||
Reference in New Issue
Block a user