comparison web/light9-vidref-replay.js @ 2376:4556eebe5d73

topdir reorgs; let pdm have its src/ dir; separate vite area from light9/
author drewp@bigasterisk.com
date Sun, 12 May 2024 19:02:10 -0700
parents light9/web/light9-vidref-replay.js@b64a4db527e2
children
comparison
equal deleted inserted replaced
2375:623836db99af 2376:4556eebe5d73
1 import { LitElement, TemplateResult, html, css } from '/node_modules/lit-element/lit-element.js';
2 import debug from '/lib/debug/debug-build-es6.js';
3 import _ from '/lib/underscore/underscore-min-es6.js';
4 import { rounding } from '/node_modules/significant-rounding/index.js';
5
6 const log = debug('replay');
7
8 class Light9VidrefReplay extends LitElement {
9
10 static get properties() {
11 return {
12 uri: { type: String },
13 videoUrl: { type: String },
14 songToVideo: { type: Object },
15 videoTime: { type: Number },
16 outVideoCurrentTime: { type: Number },
17 timeErr: { type: Number },
18 playRate: { type: Number },
19 size: { type: String, attribute: true }
20 };
21 }
22
23 estimateRate() {
24 const n = this.songToVideo.length;
25 const x0 = Math.round(n * .3);
26 const x1 = Math.round(n * .6);
27 const pt0 = this.songToVideo[x0];
28 const pt1 = this.songToVideo[x1];
29 return (pt1[1] - pt0[1]) / (pt1[0] - pt0[0]);
30 }
31
32 setVideoTimeFromSongTime(songTime, isPlaying) {
33 if (!this.songToVideo || !this.outVideo || this.outVideo.readyState < 1) {
34 return;
35 }
36 const i = _.sortedIndex(this.songToVideo, [songTime],
37 (row) => { return row[0]; });
38 if (i == 0 || i > this.songToVideo.length - 1) {
39 isPlaying = false;
40 }
41
42 this.videoTime = this.songToVideo[Math.max(0, i - 1)][1];
43
44 this.outVideoCurrentTime = this.outVideo.currentTime;
45
46 if (isPlaying) {
47 if (this.outVideo.paused) {
48 this.outVideo.play();
49 this.setRate(this.estimateRate());
50 }
51 const err = this.outVideo.currentTime - this.videoTime;
52 this.timeErr = err;
53
54 if (Math.abs(err) > window.thresh) {
55 this.outVideo.currentTime = this.videoTime;
56 const p = window.p;
57 if (err > 0) {
58 this.setRate(this.playRate - err * p);
59 } else {
60 this.setRate(this.playRate - err * p);
61 }
62 }
63 } else {
64 this.outVideo.pause();
65 this.outVideoCurrentTime = this.outVideo.currentTime = this.videoTime;
66 this.timeErr = 0;
67 }
68 }
69
70 setRate(r) {
71 this.playRate = Math.max(.1, Math.min(4, r));
72 this.outVideo.playbackRate = this.playRate;
73 }
74
75 firstUpdated() {
76 this.outVideo = this.shadowRoot.querySelector('#replay');
77 this.playRate = this.outVideo.playbackRate = 1.0;
78 }
79
80 onDelete() {
81 const u = new URL(window.location.href);
82 u.pathname = '/vidref/clips'
83 u.searchParams.set('uri', this.uri);
84 fetch(u.toString(), {method: 'DELETE'}).then((resp) => {
85 let event = new CustomEvent('clips-changed', {detail: {}});
86 this.dispatchEvent(event);
87 });
88 }
89
90 static get styles() {
91 return css`
92 :host {
93 border: 2px solid #46a79f;
94 display: flex;
95 flex-direction: column;
96 }
97 div {
98 padding: 5px;
99 }
100 .num {
101 display: inline-block;
102 width: 4em;
103 color: #29ffa0;
104 }
105 a {
106 color: rgb(97, 97, 255);
107 }
108 video {
109 width: 100%;
110 }
111 `;
112 }
113
114 render() {
115 let details = '';
116 if (this.size != 'small') {
117 details = html`
118 <div>
119 take is <a href="${this.uri}">${this.uri}</a>
120 (${Object.keys(this.songToVideo).length} frames)
121 <button @click="${this.onDelete}">Delete</button>
122 </div>
123 <!-- here, put a little canvas showing what coverage we have with the
124 actual/goal time cursors -->
125 <div>
126 video time should be <span class="num">${this.videoTime} </span>
127 actual = <span class="num">${rounding(this.outVideoCurrentTime, 3, 3, true)}</span>,
128 err = <span class="num">${rounding(this.timeErr, 3, 4, true)}</span>
129 rate = <span class="num">${rounding(this.playRate, 3, 3, true)}</span>
130 </div>
131 `;
132 }
133 return html`
134 <video id="replay" class="size-${this.size}" src="${this.videoUrl}"></video>
135 ${details}
136 `;
137
138 }
139 }
140 customElements.define('light9-vidref-replay', Light9VidrefReplay);
141 window.thresh=.3
142 window.p=.3