diff options
| author | Jules Laplace <julescarbon@gmail.com> | 2020-07-05 16:16:00 +0200 |
|---|---|---|
| committer | Jules Laplace <julescarbon@gmail.com> | 2020-07-05 16:16:00 +0200 |
| commit | bc1515b965e02641cab2a984410a3cb5cfae891c (patch) | |
| tree | fbf30bf725b83a96574012616de9fd92057d7749 /animism-align | |
| parent | c74b743b5cb3be00611d24b58603dc2b52436e7c (diff) | |
more ui stuff
Diffstat (limited to 'animism-align')
9 files changed, 63 insertions, 25 deletions
diff --git a/animism-align/README.md b/animism-align/README.md index e08c35a..0e41ed4 100644 --- a/animism-align/README.md +++ b/animism-align/README.md @@ -2,7 +2,7 @@ Align a text to an audio file. -## installation +## Installation First, install miniconda and node. @@ -11,7 +11,7 @@ conda create env -f environment.yml npm install ``` -## running the site +## Running the site Before running the commands, enter the client directory, load the Conda environment, and make sure the database is current: @@ -31,7 +31,7 @@ npm run build The server will be running on http://0.0.0.0:5000/ -## development +## Development Monitor the Javascript for changes (run in another window): diff --git a/animism-align/cli/commands/peaks/parse.py b/animism-align/cli/commands/peaks/parse.py index dc9a0a2..117ecfd 100644 --- a/animism-align/cli/commands/peaks/parse.py +++ b/animism-align/cli/commands/peaks/parse.py @@ -4,8 +4,6 @@ Extract peaks from an MP3 file. import click -from app.site.builder import build_site, build_file - @click.command() @click.option('-i', '--input', 'fp_in', required=False, help='Input file') @@ -24,16 +22,17 @@ def cli(ctx, fp_in): print(f"Loading {fp_in}") y, sr = librosa.load(fp_in, sr=None) - sr_10 = math.floor(sr / 10) - steps = math.floor(y.shape[0] / sr_10) + sr_10 = math.ceil(sr / 10) + steps = math.ceil(y.shape[0] / sr_10) - peaks = numpy.ndarray(steps * 2) + peaks = numpy.ndarray(steps) for i in range(steps): offset = i * sr_10 slice = y[offset:offset + sr_10] - peaks[i * 2] = float('%.3f' % slice.min()) - peaks[i * 2 + 1] = float('%.3f' % slice.max()) + peak = max(abs(slice.min()), slice.max()) + peaks[i] = float('%.3f' % peak) + # peaks[i * 2 + 1] = float('%.3f' % slice.max()) with open(os.path.join(app_cfg.DIR_DATA_STORE, 'peaks.json'), 'w') as fp_out: json.dump(peaks.tolist(), fp_out, separators=(',', ':')) diff --git a/animism-align/environment.yml b/animism-align/environment.yml index af838e2..3a28790 100644 --- a/animism-align/environment.yml +++ b/animism-align/environment.yml @@ -18,12 +18,15 @@ dependencies: - tk=8.6.8=ha441bb4_0 - wheel=0.33.4=py37_0 - xz=5.2.4=h1de35cc_4 + - zlib=1.2.11=h1de35cc_3 - pip: - alembic==1.2.1 - amqp==2.5.0 - async-timeout==3.0.1 + - audioread==2.1.8 - billiard==3.6.0.0 - celery==4.3.0 + - cffi==1.14.0 - chardet==3.0.4 - click==7.0 - colorlog==4.0.2 @@ -35,6 +38,7 @@ dependencies: - flask-classful==0.14.2 - flask-sqlalchemy==2.4.0 - flask-wtf==0.14.2 + - idna==2.8 - imageio==2.5.0 - imutils==0.5.2 - infinity==1.4 @@ -42,35 +46,50 @@ dependencies: - itsdangerous==1.1.0 - jinja2==2.10.1 - joblib==0.13.2 + - kiwisolver==1.2.0 - kombu==4.6.3 + - librosa==0.7.2 + - llvmlite==0.32.1 - mako==1.1.0 - markdown==3.1.1 - markupsafe==1.1.1 - matplotlib==3.1.1 - monotonic==1.5 + - networkx==2.4 + - numba==0.43.0 + - numpy==1.19.0 - pbr==5.4.3 - pdoc==0.3.2 - pillow==6.1.0 + - pycparser==2.20 + - pyparsing==2.4.7 - python-dateutil==2.8.0 - python-dotenv==0.10.3 + - python-editor==1.0.4 - pytz==2019.2 + - pywavelets==1.1.1 - pyyaml==5.1.2 - requests==2.22.0 + - resampy==0.2.2 - scikit-image==0.15.0 + - scikit-learn==0.23.1 - scipy==1.3.0 - simplejson==3.16.0 - six==1.12.0 + - soundfile==0.10.3.post1 - sqlalchemy==1.3.6 - sqlalchemy-utc==0.10.0 - sqlalchemy-utils==0.34.1 - sqlparse==0.3.0 - tempita==0.5.2 + - threadpoolctl==2.1.0 - tqdm==4.32.2 - urllib3==1.25.3 - validators==0.13.0 + - vine==1.3.0 - werkzeug==0.15.5 - wtforms==2.2.1 - wtforms-alchemy==0.16.9 - wtforms-components==0.10.4 -prefix: /Users/user/anaconda/envs/swimmer +prefix: /Users/user/miniconda3/envs/animism diff --git a/animism-align/frontend/api/crud.reducer.js b/animism-align/frontend/api/crud.reducer.js index 04ade91..38aa4f8 100644 --- a/animism-align/frontend/api/crud.reducer.js +++ b/animism-align/frontend/api/crud.reducer.js @@ -114,6 +114,7 @@ export const crudReducer = (type) => { return { ...state, update: action.data, + index: addToIndex(state.index, action.data.res, state.options.sort), } case crud_type.index_error: return { diff --git a/animism-align/frontend/views/align/align.css b/animism-align/frontend/views/align/align.css index a956b79..799693c 100644 --- a/animism-align/frontend/views/align/align.css +++ b/animism-align/frontend/views/align/align.css @@ -116,12 +116,12 @@ canvas { .annotationIndex { width: 405px; } -.annotation { +.annotationIndex .annotation { position: absolute; left: 5px; max-width: 450px; padding: 0.25rem 0.375rem; - box-shadow: 2px 2px 4px rgba(0,0,0,0.5); + box-shadow: 0px 0px 4px rgba(0,0,0,0.7); border-radius: 2px; font-size: 12px; cursor: pointer; diff --git a/animism-align/frontend/views/align/components/annotations/annotation.form.js b/animism-align/frontend/views/align/components/annotations/annotation.form.js index b62c36e..6972f93 100644 --- a/animism-align/frontend/views/align/components/annotations/annotation.form.js +++ b/animism-align/frontend/views/align/components/annotations/annotation.form.js @@ -22,6 +22,12 @@ class AnnotationForm extends Component { this.handleSelect = this.handleSelect.bind(this) this.handleKeyDown = this.handleKeyDown.bind(this) this.handleSubmit = this.handleSubmit.bind(this) + this.textareaRef = React.createRef() + } + componentDidMount() { + if (this.textareaRef && this.textareaRef.current) { + this.textareaRef.current.focus() + } } handleKeyDown(e) { if (e.keyCode === 27) { // escape @@ -111,6 +117,7 @@ class AnnotationForm extends Component { value={annotation.text} onKeyDown={this.handleKeyDown} onChange={this.handleChange} + ref={this.textareaRef} /> </div> ) diff --git a/animism-align/frontend/views/align/components/annotations/annotation.index.js b/animism-align/frontend/views/align/components/annotations/annotation.index.js index 7b562c2..09cb255 100644 --- a/animism-align/frontend/views/align/components/annotations/annotation.index.js +++ b/animism-align/frontend/views/align/components/annotations/annotation.index.js @@ -38,7 +38,7 @@ class AnnotationIndex extends Component { const items = order.filter(id => { const { start_ts: ts } = lookup[id] return (timeMin < ts && ts < timeMax) - }).map(id => lookup[id]) + }).map(id => lookup[id]).reverse() this.setState({ items }) } handleClick(annotation) { diff --git a/animism-align/frontend/views/align/components/timeline/waveform.component.js b/animism-align/frontend/views/align/components/timeline/waveform.component.js index 128204a..0a118cf 100644 --- a/animism-align/frontend/views/align/components/timeline/waveform.component.js +++ b/animism-align/frontend/views/align/components/timeline/waveform.component.js @@ -45,7 +45,6 @@ class Waveform extends Component { let secondsPerPixel = ZOOM_STEPS[zoom] * 0.1 // 0.1 sec / step let stepsPerPixel = ZOOM_STEPS[zoom] // 0.1 sec / step - let indexesPerPixel = stepsPerPixel * 2 let widthTimeDuration = h * secondsPerPixel // secs per pixel @@ -53,7 +52,7 @@ class Waveform extends Component { let timeMax = Math.min(start_ts + widthTimeDuration, duration) let timeWidth = timeMax - timeMin - let stepMin = Math.floor(timeMin * 10 * 2) + let stepMin = Math.floor(timeMin * 10) let pixelWidth = Math.ceil(timeWidth / secondsPerPixel) let i = 0 @@ -62,17 +61,17 @@ class Waveform extends Component { let origin = (1 - peaks[step]) * waveformPeak let y let peak - // console.log(0 * indexesPerPixel + stepMin, pixelWidth * indexesPerPixel + stepMin) + // console.log(stepMin, pixelWidth * stepsPerPixel + stepMin) ctx.beginPath() ctx.moveTo(origin, 0) for (i = 0; i < pixelWidth; i++) { - step = i * indexesPerPixel + stepMin + step = i * stepsPerPixel + stepMin peak = peaks[step] y = (1 - peak) * waveformPeak ctx.lineTo(y, i) } for (i = pixelWidth - 1; i > 0; i--) { - step = i * indexesPerPixel + stepMin + step = i * stepsPerPixel + stepMin peak = peaks[step] y = (1 + peak) * waveformPeak ctx.lineTo(y, i) diff --git a/animism-align/frontend/views/align/containers/timeline.container.js b/animism-align/frontend/views/align/containers/timeline.container.js index 23b9435..ceb9012 100644 --- a/animism-align/frontend/views/align/containers/timeline.container.js +++ b/animism-align/frontend/views/align/containers/timeline.container.js @@ -31,6 +31,12 @@ class Timeline extends Component { componentWillUnmount() { this.unbind() } + shouldComponentUpdate(nextProps) { + return ( + nextProps.timeline !== this.props.timeline || + nextProps.annotation !== this.props.annotation + ) + } bind() { document.addEventListener('keydown', this.handleKeydown) } @@ -41,6 +47,7 @@ class Timeline extends Component { if (document.activeElement !== document.body) { return } + // console.log(e.keyCode) if (e.shiftKey) { switch (e.keyCode) { case 187: // plus @@ -56,6 +63,10 @@ class Timeline extends Component { case 27: // escape actions.align.hideAnnotationForm() break + case 65: // A - add + e.preventDefault() + actions.align.showNewAnnotationForm(this.props.audio.play_ts, this.props.text) + break case 32: // spacebar actions.audio.toggle() break @@ -70,12 +81,13 @@ class Timeline extends Component { } handleWheel(e) { let { start_ts, zoom, duration } = this.props.timeline + let { deltaY } = e let secondsPerPixel = ZOOM_STEPS[zoom] * 0.1 // 0.1 sec / step let widthTimeDuration = window.innerHeight * secondsPerPixel // secs per pixel - - start_ts = clamp(start_ts + e.deltaY * ZOOM_STEPS[zoom], 0, Math.max(0, duration - widthTimeDuration / 2)) + start_ts += (deltaY / 2) * ZOOM_STEPS[zoom] + start_ts = clamp(start_ts, 0, Math.max(0, duration - widthTimeDuration / 2)) if (e.shiftKey) { - if (Math.abs(e.deltaY) < 2) return + if (Math.abs(deltaY) < 2) return if (e.deltaY > 0) { actions.align.throttledSetZoom(this.props.timeline.zoom + 1) } else { @@ -93,10 +105,10 @@ class Timeline extends Component { } handleClick(e) { const play_ts = positionToTime(e.pageY, this.props.timeline) - if (e.pageX > WAVEFORM_SIZE * 0.67) { - actions.align.showNewAnnotationForm(play_ts, this.props.text) - } else { + if (e.pageX < WAVEFORM_SIZE * 0.67) { actions.audio.seek(play_ts) + } else { + actions.align.showNewAnnotationForm(play_ts, this.props.text) } } render() { @@ -122,6 +134,7 @@ class Timeline extends Component { const mapStateToProps = state => ({ timeline: state.align.timeline, annotation: state.align.annotation, + audio: state.audio, text: state.site.text, }) |
