source: josm/trunk/src/org/openstreetmap/josm/io/audio/JavaFxMediaPlayer.java@ 12413

Last change on this file since 12413 was 12413, checked in by Don-vip, 8 years ago

fix some SonarQube issues

File size: 4.0 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.io.audio;
3
4import java.io.File;
5import java.io.FileNotFoundException;
6import java.io.IOException;
7import java.net.URISyntaxException;
8import java.net.URL;
9import java.util.concurrent.CountDownLatch;
10
11import org.openstreetmap.josm.io.audio.AudioPlayer.Execute;
12import org.openstreetmap.josm.io.audio.AudioPlayer.State;
13import org.openstreetmap.josm.tools.ListenerList;
14
15import com.sun.javafx.application.PlatformImpl;
16
17import javafx.scene.media.Media;
18import javafx.scene.media.MediaException;
19import javafx.scene.media.MediaPlayer;
20import javafx.scene.media.MediaPlayer.Status;
21import javafx.util.Duration;
22
23/**
24 * Default sound player based on the Java FX Media API.
25 * Used on platforms where Java FX is available. It supports the following audio codecs:<ul>
26 * <li>MP3</li>
27 * <li>AIFF containing uncompressed PCM</li>
28 * <li>WAV containing uncompressed PCM</li>
29 * <li>MPEG-4 multimedia container with Advanced Audio Coding (AAC) audio</li>
30 * </ul>
31 * @since 12328
32 */
33class JavaFxMediaPlayer implements SoundPlayer {
34
35 private final ListenerList<AudioListener> listeners = ListenerList.create();
36
37 private URL url;
38 private MediaPlayer mediaPlayer;
39
40 JavaFxMediaPlayer() throws InterruptedException {
41 initFxPlatform();
42 }
43
44 /**
45 * Initializes the JavaFX platform runtime.
46 * @throws InterruptedException if the current thread is interrupted while waiting
47 */
48 public static void initFxPlatform() throws InterruptedException {
49 final CountDownLatch startupLatch = new CountDownLatch(1);
50
51 // Note, this method is called on the FX Application Thread
52 PlatformImpl.startup(() -> startupLatch.countDown());
53
54 // Wait for FX platform to start
55 startupLatch.await();
56 }
57
58 @Override
59 public void play(Execute command, State stateChange, URL playingUrl) throws AudioException, IOException {
60 try {
61 url = command.url();
62 if (playingUrl != url) {
63 if (mediaPlayer != null) {
64 mediaPlayer.stop();
65 }
66 // Fail fast in case of invalid local URI (JavaFX Media locator retries 5 times with a 1 second delay)
67 if ("file".equals(url.getProtocol()) && !new File(url.toURI()).exists()) {
68 throw new FileNotFoundException(url.toString());
69 }
70 mediaPlayer = new MediaPlayer(new Media(url.toString()));
71 mediaPlayer.setOnPlaying(() -> {
72 listeners.fireEvent(l -> l.playing(url));
73 });
74 }
75 mediaPlayer.setRate(command.speed());
76 if (Status.PLAYING == mediaPlayer.getStatus()) {
77 Duration seekTime = Duration.seconds(command.offset());
78 if (!seekTime.equals(mediaPlayer.getCurrentTime())) {
79 mediaPlayer.seek(seekTime);
80 }
81 }
82 mediaPlayer.play();
83 } catch (MediaException | URISyntaxException e) {
84 throw new AudioException(e);
85 }
86 }
87
88 @Override
89 public void pause(Execute command, State stateChange, URL playingUrl) throws AudioException, IOException {
90 if (mediaPlayer != null) {
91 try {
92 mediaPlayer.pause();
93 } catch (MediaException e) {
94 throw new AudioException(e);
95 }
96 }
97 }
98
99 @Override
100 public boolean playing(Execute command) throws AudioException, IOException, InterruptedException {
101 // Not used: JavaFX handles the low-level audio playback
102 return false;
103 }
104
105 @Override
106 public double position() {
107 return mediaPlayer.getCurrentTime().toSeconds();
108 }
109
110 @Override
111 public double speed() {
112 return mediaPlayer.getCurrentRate();
113 }
114
115 @Override
116 public void addAudioListener(AudioListener listener) {
117 listeners.addWeakListener(listener);
118 }
119}
Note: See TracBrowser for help on using the repository browser.