From 09fba55de794c425cdce0e87f98b56b539b19858 Mon Sep 17 00:00:00 2001 From: Radium Date: Mon, 13 Jul 2020 14:17:48 +0800 Subject: [PATCH] feat(ui): basic TTS UI (#412) #272 Co-authored-by: Aliang --- web/src/app/app.module.ts | 4 +- .../audio-player/audio-player.component.html | 5 ++ .../audio-player/audio-player.component.scss | 0 .../audio-player.component.spec.ts | 22 +++++++ .../audio-player/audio-player.component.ts | 64 +++++++++++++++++++ .../details-feng/details-feng.component.html | 4 +- .../details-feng/details-feng.component.ts | 8 +++ 7 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 web/src/app/audio-player/audio-player.component.html create mode 100644 web/src/app/audio-player/audio-player.component.scss create mode 100644 web/src/app/audio-player/audio-player.component.spec.ts create mode 100644 web/src/app/audio-player/audio-player.component.ts diff --git a/web/src/app/app.module.ts b/web/src/app/app.module.ts index 98c22909a..85a3a4d99 100644 --- a/web/src/app/app.module.ts +++ b/web/src/app/app.module.ts @@ -14,6 +14,7 @@ import {MaterialModule} from '../material/material.module'; import {AdvancedSearchLandingComponent} from './advanced-search-landing/advanced-search-landing.component'; import {AppRoutingModule} from './app-routing.module'; import {AppComponent} from './app.component'; +import {AudioPlayerComponent} from './audio-player/audio-player.component'; import {CommonToolbarComponent} from './common-toolbar/common-toolbar.component'; import {DebugInfoComponent} from './debug-info/debug-info.component'; import {DetailsFengComponent} from './details-feng/details-feng.component'; @@ -49,7 +50,8 @@ import {YngpingHelpDialogComponent} from './yngping-help-dialog/yngping-help-dia CommonToolbarComponent, DebugInfoComponent, YngpingHelpDialogComponent, - SimplificationToolComponent + SimplificationToolComponent, + AudioPlayerComponent ], imports: [ AppRoutingModule, diff --git a/web/src/app/audio-player/audio-player.component.html b/web/src/app/audio-player/audio-player.component.html new file mode 100644 index 000000000..202038d57 --- /dev/null +++ b/web/src/app/audio-player/audio-player.component.html @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/web/src/app/audio-player/audio-player.component.scss b/web/src/app/audio-player/audio-player.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/web/src/app/audio-player/audio-player.component.spec.ts b/web/src/app/audio-player/audio-player.component.spec.ts new file mode 100644 index 000000000..f4c38fd27 --- /dev/null +++ b/web/src/app/audio-player/audio-player.component.spec.ts @@ -0,0 +1,22 @@ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {AudioPlayerComponent} from './audio-player.component'; + +describe('AudioPlayerComponent', () => { + let component: AudioPlayerComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({declarations: [AudioPlayerComponent]}).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AudioPlayerComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/web/src/app/audio-player/audio-player.component.ts b/web/src/app/audio-player/audio-player.component.ts new file mode 100644 index 000000000..b755207f1 --- /dev/null +++ b/web/src/app/audio-player/audio-player.component.ts @@ -0,0 +1,64 @@ +import {Component, Input, OnInit} from '@angular/core'; + +@Component({ + selector: 'app-audio-player', + templateUrl: './audio-player.component.html', + styleUrls: ['./audio-player.component.scss'] +}) +export class AudioPlayerComponent implements OnInit { + public PlayerStateEnum = PlayerState; + + @Input('audioUrl') audioUrl: string; + state: PlayerState = PlayerState.Idle; + private currentAudio: HTMLAudioElement = null; + + constructor() {} + + ngOnInit(): void {} + + onClicked() { + switch (this.state) { + case PlayerState.Idle: + console.log('playing + ' + this.audioUrl); + this.currentAudio = new Audio(this.audioUrl); + this.state = PlayerState.Loading; + this.currentAudio.onended = () => { + this.state = PlayerState.Idle; + this.currentAudio = null; + }; + this.currentAudio.oncanplaythrough = () => { + this.state = PlayerState.Playing; + this.currentAudio.play(); + }; + this.currentAudio.onerror = (e) => { + let mediaError = this.currentAudio.error; + this.currentAudio = null; + if (mediaError.message.indexOf('404') >= 0) { + console.log('404 encountered. Disabling audio player for ' + this.audioUrl); + this.state = PlayerState.Disabled; + } else { + this.state = PlayerState.Idle; + } + }; + break; + case PlayerState.Playing: + if (this.currentAudio != null) { + } + break; + case PlayerState.Loading: + case PlayerState.Disabled: + console.log('Do nothing'); + break; + } + } +} + + +enum PlayerState { + // Initial State. + Idle, + Loading, + Playing, + // When a 404 is encountered. Prevents further attempts. + Disabled +} diff --git a/web/src/app/details-feng/details-feng.component.html b/web/src/app/details-feng/details-feng.component.html index 54924aa0a..9311358cf 100644 --- a/web/src/app/details-feng/details-feng.component.html +++ b/web/src/app/details-feng/details-feng.component.html @@ -6,6 +6,7 @@
{{ shouldShowSandhi ? "市区单字": "福州市区"}} {{ fengDoc.getYngpingUnderlying() }} +
市区连读 - {{ fengDoc.getYngpingCanonical() }} + {{ fengDoc.getYngpingCanonical() }} +
diff --git a/web/src/app/details-feng/details-feng.component.ts b/web/src/app/details-feng/details-feng.component.ts index 5c18c556e..83b17162f 100644 --- a/web/src/app/details-feng/details-feng.component.ts +++ b/web/src/app/details-feng/details-feng.component.ts @@ -47,6 +47,14 @@ export class DetailsFengComponent implements OnInit, OnDestroy { return this.fengDoc.getYngpingUnderlying() !== this.fengDoc.getYngpingCanonical(); } + get audioUrlUnderlying() { + return this.environment.serverUrl + '/tts/' + this.fengDoc.getYngpingUnderlying() + } + + get audioUrlSandhi() { + return this.environment.serverUrl + '/tts/' + this.fengDoc.getYngpingCanonical() + } + constructor( @Inject(YNGDIENG_ENVIRONMENT) private environment: IYngdiengEnvironment, private route: ActivatedRoute,