/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package net.angusi.sw.minidisc.audioobjects;
import javafx.beans.property.*;
import javafx.scene.media.MediaPlayer;
import javafx.util.Duration;
import net.angusi.sw.minidisc.exceptions.ValueOutOfBoundsException;
import javafx.scene.media.Media;
import java.io.File;
public class Clip {
private final StringProperty cueNumber = new SimpleStringProperty();
private final StringProperty description = new SimpleStringProperty();
private final DoubleProperty length = new SimpleDoubleProperty();
private Media media;
private MediaPlayer mediaPlayer;
private final FloatProperty startTime = new SimpleFloatProperty();
private final FloatProperty endTime = new SimpleFloatProperty();
private final DoubleProperty initialGainLevel = new SimpleDoubleProperty();
private final DoubleProperty fadeBeginTime = new SimpleDoubleProperty();
private final BooleanProperty isPlaying = new SimpleBooleanProperty();
private final DoubleProperty timeRemaining = new SimpleDoubleProperty();
public Clip(File sourceFile) {
setClipLocation(sourceFile);
}
public void setClipLocation(File sourceFile) {
media = new Media(sourceFile.toURI().toString());
mediaPlayer = new MediaPlayer(media);
if(media.getDuration() == Duration.UNKNOWN) {
media.durationProperty().addListener((observable, oldValue, newValue) -> {
length.set(media.getDuration().toMillis());
fadeBeginTime.set(media.getDuration().toMillis());
timeRemaining.set(media.getDuration().toMillis() - mediaPlayer.getCurrentTime().toMillis());
});
} else {
length.set(media.getDuration().toMillis());
fadeBeginTime.set(media.getDuration().toMillis());
}
description.set(sourceFile.getName());
if(mediaPlayer.volumeProperty() == null) {
mediaPlayer.volumeProperty().addListener((observable, oldValue, newValue) -> initialGainLevel.set(mediaPlayer.getVolume()));
} else {
initialGainLevel.set(mediaPlayer.getVolume());
}
mediaPlayer.currentTimeProperty().addListener((observable, oldValue, newValue) -> timeRemaining.set(media.getDuration().toMillis() - mediaPlayer.getCurrentTime().toMillis()));
mediaPlayer.statusProperty().addListener((observable, oldValue, newValue) -> {
if(newValue.equals(MediaPlayer.Status.PLAYING)) {
isPlaying.set(true);
} else {
isPlaying.set(false);
}
});
isPlaying.set(false);
}
public void setClipStartTime(float startTime) throws ValueOutOfBoundsException {
if(startTime<0 || startTime>=endTime.get()) {
throw new ValueOutOfBoundsException();
}
this.startTime.set(startTime);
}
public void setClipEndTime(float endTime) throws ValueOutOfBoundsException {
if(endTime<=startTime.get() || endTime>length.get()) {
throw new ValueOutOfBoundsException();
}
this.endTime.set(endTime);
}
public StringProperty cueNumberProperty() {
return cueNumber;
}
public String getCueNumber() {
return cueNumber.get();
}
public StringProperty descriptionProperty() {
return description;
}
public String getDescription() {
return description.get();
}
public DoubleProperty lengthProperty() {
return length;
}
public Double getLength() {
return length.get();
}
public FloatProperty startTimeProperty() {
return startTime;
}
public Float getStartTime() {
return startTime.get();
}
public FloatProperty endTimeProperty() {
return endTime;
}
public Float getEndTime() {
return endTime.get();
}
public double getTimeRemaining() {
return timeRemaining.get();
}
public DoubleProperty timeRemainingProperty() {
return timeRemaining;
}
public DoubleProperty gainLevelProperty() {
return initialGainLevel;
}
public Double getGainLevel() {
return initialGainLevel.get();
}
public DoubleProperty fadeBeginTimeProperty() {
return fadeBeginTime;
}
public Double getFadeBeginTime() {
return fadeBeginTime.get();
}
public void playClip() {
mediaPlayer.setVolume(initialGainLevel.get());
mediaPlayer.play();
}
public void stopClip() {
mediaPlayer.stop();
}
public void fadeClip() {
double interval = mediaPlayer.getVolume() / 2000; //Todo: Make fade-time a preference
for(int i = 0; i < 2000; i++) {
mediaPlayer.setVolume(mediaPlayer.getVolume() - interval);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
mediaPlayer.stop();
}
public BooleanProperty isPlayingProperty() {
return isPlaying;
}
public Boolean isPlaying() {
return isPlaying.get();
}
}