Updated Amp to use DNS-SD project and fixed a bug causing repeated status updates...
[stereo.git] / Amp / src / stereo / player / StereoAmp.java
blob7cd31998ed099b981e0a870c87e69544a29c3f45
1 package stereo.player;
3 import interfaces.Constants;
4 import interfaces.Track.TrackFactory;
6 import java.io.ByteArrayInputStream;
7 import java.io.IOException;
8 import java.net.UnknownHostException;
10 import javax.sound.sampled.UnsupportedAudioFileException;
12 import api.Response;
13 import api.nodes.AlbumNode.AlbumFactory;
14 import api.nodes.PlaylistNode.PlaylistFactory;
16 import reader.DACPResponseParser;
18 import util.command.Song;
19 import util.response.ctrlint.PlayStatusUpdate;
21 public class StereoAmp extends Thread {
23 private final String host;
24 private final int port;
25 private final DACPResponseParser parser;
27 private AudioPlayer player;
28 private int current;
30 public StereoAmp(String host, int port) {
32 this.host = host;
33 this.port = port;
35 parser = new AmpResponseParser();
38 public void run() {
40 int revision = -1;
42 while (true) {
44 PlayStatusUpdate response;
45 if (revision > 0) {
46 response = (PlayStatusUpdate)request("/ctrl-int/1/playstatusupdate?revision-number="+revision);
48 else {
49 response = (PlayStatusUpdate)request("/ctrl-int/1/playstatusupdate");
51 revision = response.revision;
53 if (response.state == PlayStatusUpdate.Status.PLAYING) {
55 current = response.active().currentTrackId;
56 Song song = (Song)request("/ctrl-int/1/current");
58 if (song != null && song.song() != null) {
59 try {
60 String name = response.active().trackTitle + " by " + response.active().trackArtist;
61 player = new AudioPlayer(name, new ByteArrayInputStream(song.song()));
62 System.out.println("playing");
63 player.start(); //blocks until stream finishes playing
64 System.out.println("done");
66 if (!player.stopped()) {
67 System.out.println("finished: next song");
68 request("/ctrl-int/1/nextitem?revision-number="+revision);
71 player = null;
72 song = null;
74 catch (IOException ex) {
75 ex.printStackTrace();
76 } catch (UnsupportedAudioFileException e) {
77 e.printStackTrace();
81 if (song != null) {
82 if (player != null) {
83 player.stop();
84 player = null;
87 System.out.println("error: next song");
88 request("/ctrl-int/1/nextitem?revision-number="+revision);
94 public void listen() {
96 int revision = 0;
97 String rev = "";
98 while (true) {
100 if (revision != 0) {
101 rev = "?revision-number="+revision;
103 Response response = request("/ctrl-int/1/playstatusupdate"+rev);
105 if (response == null) break;
107 if (response.type() == Constants.dmcp_status) {
108 PlayStatusUpdate psu = (PlayStatusUpdate)response;
110 revision = psu.revision;
112 switch (psu.state) {
113 case STOPPED:
114 if (player != null && !player.isPlaying()) player.stop();
115 break;
116 case PAUSED:
117 if (player != null && player.isPlaying()) player.pause();
118 break;
119 case PLAYING:
120 if (player != null && !player.isPlaying()) player.play();
121 break;
124 if (psu.active()!=null) {
125 PlayStatusUpdate.Active psua = psu.active();
126 System.out.printf("Playing %s by %s\n", psua.trackTitle, psua.trackArtist);
127 if (current != psua.currentTrackId) {
128 if (player != null) player.stop();
131 else {
132 System.out.println("Stopped");
135 else {
136 System.err.println("Unexpected reponse type: " + response.type().longName);
137 break;
142 private Response request(String request) {
143 try {
144 return parser.request(host, port, request);
145 } catch (UnknownHostException e) {
146 System.err.println("Unable to connect to " + host);
147 e.printStackTrace();
148 } catch (IOException e) {
149 System.err.println("Problem contacting " + host);
150 e.printStackTrace();
153 return null;
156 private class AmpResponseParser extends DACPResponseParser {
158 @Override
159 public AlbumFactory albumFactory() {
160 return null;
163 @Override
164 public PlaylistFactory playlistFactory() {
165 return null;
168 @Override
169 public TrackFactory trackFactory() {
170 return null;