Skip to content

Commit

Permalink
Issue-1: Update able to reflect slider
Browse files Browse the repository at this point in the history
  • Loading branch information
Danil Ko committed Sep 2, 2019
1 parent e710591 commit e2abb1a
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,16 @@ void play() {

Mixer.Info[] mixerInfos = AudioSystem.getMixerInfo();

long totalFrames = audioInputStream.getFrameLength();

musicPlayerState.setFrameSize(audioFormat.getFrameSize());
// from https://stackoverflow.com/questions/35822296/how-to-keep-track-of-audio-playback-position
musicPlayerState.setBufferSize(audioFormat.getFrameSize() * 1024);
musicPlayerState.setTotalFrames(audioInputStream.getFrameLength());
musicPlayerState.setTotalFrames(totalFrames);
musicPlayerState.setSampleRate(audioFormat.getSampleRate());

double targetElapsePerecentage = musicPlayerRepository.getTargetElapsedPercentage();

Mixer.Info targetMixerInfo = null;


Expand All @@ -131,6 +135,7 @@ void play() {

DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);

long newFramePosition = 0;

if (targetMixerInfo != null)
{
Expand All @@ -149,9 +154,15 @@ void play() {
boolean nextMusic = true;

while ((byteRead = audioInputStream.read(byteBuffer)) != -1) {
sourceDataLine.write(byteBuffer, 0, byteRead);
musicPlayerState.setFramePosition( musicPlayerState.getFramePosition() + (byteRead / musicPlayerState.getFrameSize()));
newFramePosition = newFramePosition + (byteRead / musicPlayerState.getFrameSize());

musicPlayerState.setFramePosition(newFramePosition);

musicPlayerRepository.setMusicPlayerState(musicPlayerState);
if(targetElapsePerecentage == 0 || ((int) Math.round((double) newFramePosition / (double) totalFrames * 100)) >= targetElapsePerecentage)
{
sourceDataLine.write(byteBuffer, 0, byteRead);
}

if ( musicPlayerRepository.getMusicPlayerSetting().getPlay() == false) {

Expand All @@ -170,6 +181,8 @@ void play() {
musicPlayerState.setErrorMessage("cannot find target mixer");
}

// Reset music setting to 0
musicPlayerRepository.setTargetElapsedPercentage(0);

}
catch(Exception exception)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ public class MusicPlayerRepository {

private int currentMusicFileIndex;

private double targetElapsedPercentage;

public MusicPlayerRepository()
{
targetElapsedPercentage = -1;

ObjectMapper mapper = new ObjectMapper();

String path = System.getenv("MUSIC_UTILITY_LOCATION");
Expand Down Expand Up @@ -73,12 +77,14 @@ public MusicPlayerSetting getMusicPlayerSetting() {
return musicPlayerSetting;
}

public MusicPlayerSetting save(MusicPlayerSetting musicPlayerSetting)
public MusicPlayerSetting save(MusicPlayerSetting musicPlayerSetting, boolean filePersistence)
{

this.musicPlayerSetting = musicPlayerSetting;

saveConfiguration();
if(filePersistence) {
saveConfiguration();
}

return musicPlayerSetting;
}
Expand Down Expand Up @@ -148,6 +154,17 @@ public MusicPlayerState getMusicPlayerState() {
return musicPlayerState;
}

public double getTargetElapsedPercentage()
{
return targetElapsedPercentage;
}

public void setTargetElapsedPercentage(double targetElapsedPercentage) {
synchronized(this) {
this.targetElapsedPercentage = targetElapsedPercentage;
}
}

public void setMusicPlayerState(MusicPlayerState musicPlayerState) {
synchronized(this) {
this.musicPlayerState.setFramePosition(musicPlayerState.getFramePosition());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class MusicPlayerController {

@PutMapping("/setting")
@ResponseStatus(HttpStatus.OK)
public MusicPlayerSetting create(@RequestBody MusicPlayerSetting musicPlayerSetting) {
public MusicPlayerSetting create(@RequestBody MusicPlayerSetting musicPlayerSetting, @RequestParam("elapsedpercentage") String elapsedPercentage) {

MusicPlayerSetting newMusicPlayerSetting = new MusicPlayerSetting();

Expand Down Expand Up @@ -71,13 +71,35 @@ public MusicPlayerSetting create(@RequestBody MusicPlayerSetting musicPlayerSett

newMusicPlayerSetting.setCurrentMusicMixer(currentMusicMixer);

double targetElapsedPercentage = 0;

musicPlayerRepository.save(newMusicPlayerSetting);
if(newMusicPlayerSetting.getPlay() && elapsedPercentage != null)
{
try{
targetElapsedPercentage = Double.parseDouble(elapsedPercentage);

if(targetElapsedPercentage < 0 || targetElapsedPercentage >= 100)
{
targetElapsedPercentage = 0;
}
}
catch (Exception exception)
{
targetElapsedPercentage = 0;
}

}

musicPlayerRepository.setTargetElapsedPercentage(targetElapsedPercentage);


musicPlayerRepository.save(newMusicPlayerSetting, true);

return newMusicPlayerSetting;
}



@GetMapping("/setting")
@ResponseStatus(HttpStatus.OK)
public MusicPlayerSetting getCurrentMusicPlayerSetting() {
Expand Down
5 changes: 4 additions & 1 deletion controller-web/src/main/web/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
MusicFileInfoDialog,
MusicMixerInfoDialog,
LoadingDialog,
ErrorDialog,
} from "../dialog/dialog-component";


Expand All @@ -47,6 +48,7 @@ import { MusicPlayerService } from "../service/musicplayer.service";
MusicFileInfoDialog,
MusicMixerInfoDialog,
LoadingDialog,
ErrorDialog,
MusicListComponent,
MusicStreamingComponent,
MusicRemoteComponent
Expand Down Expand Up @@ -77,7 +79,8 @@ import { MusicPlayerService } from "../service/musicplayer.service";
DeleteMusicListDialog,
MusicFileInfoDialog,
MusicMixerInfoDialog,
LoadingDialog
LoadingDialog,
ErrorDialog
]
})
export class AppModule { }
16 changes: 16 additions & 0 deletions controller-web/src/main/web/src/dialog/dialog-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,19 @@ export class LoadingDialog {
}

}

@Component({
selector: 'error-dialog',
templateUrl: '../dialog/error-dialog.html',
})
export class ErrorDialog {

constructor(
public dialogRef: MatDialogRef<ErrorDialog>,
@Inject(MAT_DIALOG_DATA) public data: String) {
}

onNoClick(): void {
this.dialogRef.close();
}
}
7 changes: 7 additions & 0 deletions controller-web/src/main/web/src/dialog/error-dialog.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<h1 mat-dialog-title> <span style="color:red;font-weight:bold">Error</span></h1>
<div mat-dialog-content>
<p>{{data}}</p>
</div>
<div mat-dialog-actions>
<button mat-button (click)="onNoClick()">Close</button>
</div>
18 changes: 9 additions & 9 deletions controller-web/src/main/web/src/model/musicplayerstate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import {MusicPlayerSetting} from "./musicplayersetting";

export class MusicPlayerState{
musicPlayerSetting: MusicPlayerSetting;
frameSize: bigint;
totalFrames: bigint;
sampleRate: bigint;
bufferSize: bigint;
framePosition: bigint;
elaspsedTime: string;
elapsedPercentage: string;
errorMessage: string;
playing: boolean;
frameSize: number;
totalFrames: number;
sampleRate: number;
bufferSize: number;
framePosition: number;
elaspsedTime: number;
elapsedPercentage: number;
errorMessage: number;
playing: number;

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,22 @@ <h2>Music Remote Control</h2>
[min]=0
[step]=1
[thumbLabel]=true
[(ngModel)]="currentMusicPlayerState.elapsedPercentage">
[(ngModel)]="currentMusicPlayerState.elapsedPercentage"
(input)="updateMusicPlayerSetting(currentMusicPlayerState.musicPlayerSetting.currentMusicList, currentMusicPlayerState.musicPlayerSetting.currentMusicFile, currentMusicPlayerState.musicPlayerSetting.currentMusicMixer, true, $event.value)">
</mat-slider>

<div>{{currentMusicPlayerState.elaspsedTime}} ({{currentMusicPlayerState.elapsedPercentage}}.00%)</div>

<button mat-icon-button aria-label="Play" *ngIf="currentMusicPlayerState.playing == false" (click)="updateMusicPlayerSetting(currentMusicFile, currentMusicMixer, true)">
<button mat-icon-button aria-label="Play" *ngIf="currentMusicPlayerState.playing == false" (click)="updateMusicPlayerSetting(currentMusicPlayerState.musicPlayerSetting.currentMusicList, currentMusicPlayerState.musicPlayerSetting.currentMusicFile, currentMusicPlayerState.musicPlayerSetting.currentMusicMixer, true, currentMusicPlayerState.elapsedPercentage)">
<mat-icon>play_arrow</mat-icon>
</button>
<button mat-icon-button aria-label="Stop" *ngIf="currentMusicPlayerState.playing == true" (click)="updateMusicPlayerSetting(currentMusicFile, currentMusicMixer, false)">
<button mat-icon-button aria-label="Stop" *ngIf="currentMusicPlayerState.playing == true" (click)="updateMusicPlayerSetting(currentMusicPlayerState.musicPlayerSetting.currentMusicList, currentMusicPlayerState.musicPlayerSetting.currentMusicFile, currentMusicPlayerState.musicPlayerSetting.currentMusicMixer, false, currentMusicPlayerState.elapsedPercentage)">
<mat-icon>pause</mat-icon>
</button>

<h4>Current Playing: {{currentMusicPlayerState.musicPlayerSetting.currentMusicFile.label}}</h4>
<div>Music List: {{currentMusicPlayerState.musicPlayerSetting.currentMusicList.label}}</div>
<div>Mixer: {{currentMusicPlayerState.musicPlayerSetting.currentMusicMixer.name}}</div>
<div> Elapsed Percentage: {{currentMusicPlayerState.elapsedPercentage}}</div>
<div>Current Play State: {{currentMusicPlayerState.playing}}</div>
<div *ngIf="currentMusicPlayerState.errorMessage" >Error Message: {{currentMusicPlayerState.errorMessage}}</div>
</div>
Expand All @@ -44,11 +45,12 @@ <h4>Current Playing: {{currentMusicPlayerState.musicPlayerSetting.currentMusicFi

<br>


<mat-list *ngIf="currentMusicList.label" class="musicutiltiy-mat-full-width">
<h3 mat-subheader>Current Music Files in List</h3>
<mat-list-item *ngFor="let musicfile of currentMusicList.musicFiles">
<mat-icon mat-list-icon *ngIf="currentMusicFile.id == musicfile.id && (currentMusicPlayerState.musicPlayerSetting.currentMusicList && currentMusicPlayerState.musicPlayerSetting.currentMusicList.id == currentMusicList.id)">play_arrow</mat-icon>
<mat-icon mat-list-icon *ngIf="currentMusicFile.id != musicfile.id || (!currentMusicPlayerState.musicPlayerSetting.currentMusicList || currentMusicPlayerState.musicPlayerSetting.currentMusicList.id != currentMusicList.id)">music_video</mat-icon>
<mat-icon mat-list-icon *ngIf="currentMusicFile != null && currentMusicFile.id == musicfile.id && currentMusicPlayerState.musicPlayerSetting.currentMusicList != null && currentMusicPlayerState.musicPlayerSetting.currentMusicList.id == currentMusicList.id">play_arrow</mat-icon>
<mat-icon mat-list-icon *ngIf="currentMusicFile == null || currentMusicFile.id != musicfile.id || currentMusicPlayerState.musicPlayerSetting.currentMusicList == null || currentMusicPlayerState.musicPlayerSetting.currentMusicList.id != currentMusicList.id">music_video</mat-icon>
<h4 mat-line>{{musicfile.label}}</h4>
<p mat-line> {{musicfile.path}} </p>
<button mat-icon-button [matMenuTriggerFor]="menu" aria-label="Example icon-button with a menu">
Expand All @@ -59,7 +61,7 @@ <h4 mat-line>{{musicfile.label}}</h4>
<mat-icon>info</mat-icon>
<span>Info</span>
</button>
<button mat-menu-item (click)="updateMusicPlayerSetting(musicfile, currentMusicMixer, true)" *ngIf="currentMusicFile.id != musicfile.id || (!currentMusicPlayerState.musicPlayerSetting.currentMusicList || currentMusicPlayerState.musicPlayerSetting.currentMusicList.id != currentMusicList.id)">
<button mat-menu-item (click)="updateMusicPlayerSetting(currentMusicList, musicfile, currentMusicMixer, true, 0)" *ngIf="currentMusicFile == null || currentMusicFile.id != musicfile.id || currentMusicPlayerState.musicPlayerSetting.currentMusicList == null || currentMusicPlayerState.musicPlayerSetting.currentMusicList.id != currentMusicList.id">
<mat-icon>play_arrow</mat-icon>
<span>Play</span>
</button>
Expand All @@ -83,7 +85,7 @@ <h4 mat-line>{{musicmixer.name}}</h4>
<mat-icon>info</mat-icon>
<span>Info</span>
</button>
<button mat-menu-item (click)="updateMusicPlayerSetting(currentMusicFile, musicmixer, true)" *ngIf="currentMusicMixer.name != musicmixer.name">
<button mat-menu-item (click)="updateMusicPlayerSetting(currentMusicPlayerState.musicPlayerSetting.currentMusicList, currentMusicPlayerState.musicPlayerSetting.currentMusicFile, musicmixer, true, 0)" *ngIf="currentMusicMixer.name != musicmixer.name">
<mat-icon>play_arrow</mat-icon>
<span>Play</span>
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import {MusicMixerService} from '../service/musicmixer.service';
import {
LoadingDialog,
MusicFileInfoDialog,
MusicMixerInfoDialog
MusicMixerInfoDialog,
ErrorDialog
} from "../dialog/dialog-component";
import {MusicPlayerState} from "../model/musicplayerstate";
import {MusicPlayerService} from "../service/musicplayer.service";
Expand Down Expand Up @@ -44,6 +45,7 @@ export class MusicRemoteComponent implements OnInit, OnDestroy {
this.currentMusicFile = new MusicFile();
this.currentMusicMixer = new MusicMixer();
this.currentPlaySetting = false;

}


Expand All @@ -67,28 +69,44 @@ export class MusicRemoteComponent implements OnInit, OnDestroy {
this.currentMusicFile = new MusicFile();
}

updateMusicPlayerSetting(musicfile: MusicFile, musicmixer : MusicMixer, play:boolean) {
updateMusicPlayerSetting(musiclist: MusicList, musicfile: MusicFile, musicmixer : MusicMixer, play : boolean, elapsedTargetPercentage : number) {
let updateMusicPlayerSetting = new MusicPlayerSetting();
updateMusicPlayerSetting.currentMusicList = this.currentMusicList;
updateMusicPlayerSetting.currentMusicMixer = musicmixer;
updateMusicPlayerSetting.play = play;

if(musicfile.id == null || musicfile.id == "")
{
updateMusicPlayerSetting.currentMusicFile = updateMusicPlayerSetting.currentMusicList[0];
if(musiclist == null) {
const dialogRef = this.dialog.open(ErrorDialog, {
width: "80%",
data: "Music Mixer cannot be modified unless first play a music file in a music list"
});

return;
}
else
{
updateMusicPlayerSetting.currentMusicFile = musicfile;
updateMusicPlayerSetting.currentMusicList = musiclist;



if(musicfile == null) {
updateMusicPlayerSetting.currentMusicFile = updateMusicPlayerSetting.currentMusicList[0];
}
else
{
updateMusicPlayerSetting.currentMusicFile = musicfile;
}

if(musicmixer == null) {
updateMusicPlayerSetting.currentMusicMixer = this.currentMusicPlayerState.musicPlayerSetting.currentMusicMixer;
}
else {
updateMusicPlayerSetting.currentMusicMixer = musicmixer;
}

updateMusicPlayerSetting.play = play;

const loadingDialogRef = this.dialog.open(LoadingDialog, {
width: "80%",
data: ""
});

this.musicplayerService.updateMusicPlayerSetting(updateMusicPlayerSetting).subscribe( data => {
this.musicplayerService.updateMusicPlayerSetting(updateMusicPlayerSetting, elapsedTargetPercentage).subscribe( data => {
this.getMusicPlayerState();
loadingDialogRef.close();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export class MusicPlayerService {
this.serviceUrl = '/api/musicplayer'
}

updateMusicPlayerSetting(musicPlayerSetting : MusicPlayerSetting): Observable<any>{
return this.http.put<MusicPlayerSetting>(this.serviceUrl + "/setting", musicPlayerSetting);
updateMusicPlayerSetting(musicPlayerSetting : MusicPlayerSetting, elapsedTargetPercentage : number): Observable<any>{
return this.http.put<MusicPlayerSetting>(this.serviceUrl + "/setting?elapsedpercentage=" + elapsedTargetPercentage, musicPlayerSetting);
}

getMusicPlayerState(): Observable<MusicPlayerState>{
Expand Down

0 comments on commit e2abb1a

Please sign in to comment.