View Javadoc

1   package org.rpi.providers;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   import java.util.Observable;
6   import java.util.Observer;
7   
8   import org.apache.log4j.Logger;
9   import org.openhome.net.device.DvDevice;
10  import org.openhome.net.device.IDvInvocation;
11  import org.openhome.net.device.providers.DvProviderAvOpenhomeOrgRadio1;
12  import org.rpi.config.Config;
13  import org.rpi.player.PlayManager;
14  import org.rpi.player.events.EventBase;
15  import org.rpi.player.events.EventRadioPlayName;
16  import org.rpi.player.events.EventRadioPlayingTrackID;
17  import org.rpi.player.events.EventRadioStatusChanged;
18  import org.rpi.radio.CustomChannel;
19  import org.rpi.utils.Utils;
20  
21  public class PrvRadio extends DvProviderAvOpenhomeOrgRadio1 implements Observer {
22  
23  	private Logger log = Logger.getLogger(PrvRadio.class);
24  
25  	private byte[] array = new byte[100];
26  
27  	private List<CustomChannel> channels = new ArrayList<CustomChannel>();
28  	private int current_channel = -99;
29  
30  	// "<DIDL-Lite xmlns='urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/'><item id=''><dc:title xmlns:dc='http://purl.org/dc/elements/1.1/'></dc:title><upnp:class xmlns:upnp='urn:schemas-upnp-org:metadata-1-0/upnp/'>object.item.audioItem</upnp:class><res bitrate='6000' nrAudioChannels='2' protocolInfo='http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01'>http://cast.secureradiocast.co.uk:8004/;stream.mp3</res><upnp:albumArtURI xmlns:upnp='urn:schemas-upnp-org:metadata-1-0/upnp/'>http://www.mediauk.com/logos/100/226.png</upnp:albumArtURI></item></DIDL-Lite>";
31  	//private String metaData = "<DIDL-Lite xmlns='urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/'><item id=''><dc:title xmlns:dc='http://purl.org/dc/elements/1.1/'></dc:title><upnp:class xmlns:upnp='urn:schemas-upnp-org:metadata-1-0/upnp/'>object.item.audioItem</upnp:class><res bitrate='' nrAudioChannels='' protocolInfo=''></res><upnp:albumArtURI xmlns:upnp='urn:schemas-upnp-org:metadata-1-0/upnp/'></upnp:albumArtURI></item></DIDL-Lite>";
32  
33  	public PrvRadio(DvDevice iDevice) {
34  		super(iDevice);
35  		log.debug("Creating CustomRadio");
36  
37  		enablePropertyChannelsMax();
38  		enablePropertyId();
39  		enablePropertyIdArray();
40  		enablePropertyMetadata();
41  		enablePropertyProtocolInfo();
42  		enablePropertyTransportState();
43  		enablePropertyUri();
44  
45  		setPropertyChannelsMax(100);
46  		setPropertyId(0);
47  		setPropertyIdArray(array);
48  		setPropertyMetadata("");
49  		setPropertyProtocolInfo(Config.getProtocolInfo());
50  		setPropertyTransportState("Stopped");
51  		setPropertyUri("");
52  
53  		enableActionChannel();
54  		enableActionChannelsMax();
55  		enableActionId();
56  		enableActionIdArray();
57  		enableActionIdArrayChanged();
58  		enableActionRead();
59  		enableActionPause();
60  		enableActionPlay();
61  		enableActionProtocolInfo();
62  		enableActionReadList();
63  		enableActionSeekSecondAbsolute();
64  		enableActionSeekSecondAbsolute();
65  		enableActionSeekSecondRelative();
66  		enableActionSetChannel();
67  		enableActionSetId();
68  		enableActionStop();
69  		enableActionTransportState();
70  		PlayManager.getInstance().observRadioEvents(this);
71  	}
72  
73  	/***
74  	 * Add a list of Radio Channels
75  	 * 
76  	 * @param channels
77  	 */
78  	public void addChannels(List<CustomChannel> channels) {
79  		this.channels = channels;
80  		UpdateIdArray();
81  		propertiesLock();
82  		setPropertyIdArray(array);
83  		setPropertyChannelsMax(channels.size());
84  		propertiesUnlock();
85  		log.debug("Added Channels: " + channels.size());
86  	}
87  
88  
89  	protected Channel channel(IDvInvocation paramIDvInvocation) {
90  		log.debug("Channel" + Utils.getLogText(paramIDvInvocation));
91  		CustomChannel c = channels.get(0);
92  		Channel channel = new Channel(c.getUri(), c.getMetadata());
93  		return channel;
94  	};
95  
96  	@Override
97  	protected long channelsMax(IDvInvocation paramIDvInvocation) {
98  		log.debug("ChannelsMax" + Utils.getLogText(paramIDvInvocation));
99  		return getPropertyChannelsMax();
100 	}
101 
102 	@Override
103 	protected long id(IDvInvocation paramIDvInvocation) {
104 		log.debug("Id" + Utils.getLogText(paramIDvInvocation));
105 		return getPropertyId();
106 	}
107 
108 	@Override
109 	protected boolean idArrayChanged(IDvInvocation paramIDvInvocation, long arg1) {
110 		log.debug("idArrayChanged" + Utils.getLogText(paramIDvInvocation));
111 		return false;
112 	}
113 
114 	protected void pause(IDvInvocation paramIDvInvocation) {
115 		log.debug("Pause" + Utils.getLogText(paramIDvInvocation));
116 	};
117 
118 	protected void play(IDvInvocation paramIDvInvocation) {
119 		log.debug("Play" + Utils.getLogText(paramIDvInvocation));
120 		if (current_channel >= 0) {
121 			log.debug("Play Channel Set: " + current_channel);
122 			getChannelById();
123 		}
124 		else
125 		{
126 			log.debug("Current Channel " + current_channel + " Not Playing..");
127 		}
128 	};
129 
130 	protected String protocolInfo(IDvInvocation paramIDvInvocation) {
131 		log.debug("protocolInfo"  +Utils.getLogText(paramIDvInvocation));
132 		return Config.getProtocolInfo();
133 	};
134 
135 	@Override
136 	protected IdArray idArray(IDvInvocation paramIDvInvocation) {
137 		log.debug("GetIdArray" + Utils.getLogText(paramIDvInvocation));
138 		byte[] array = getPropertyIdArray();
139 		DvProviderAvOpenhomeOrgRadio1.IdArray idArray = new IdArray(0, array);
140 		return idArray;
141 	}
142 
143 	@Override
144 	protected void setChannel(IDvInvocation paramIDvInvocation, String uri, String metadata) {
145 		log.debug("SetChannel"  +Utils.getLogText(paramIDvInvocation));
146 		CustomChannel channel = new CustomChannel(uri, metadata, 2,"");
147 		channels.add(channel);
148 		UpdateIdArray();
149 	}
150 	
151 
152 	@Override
153 	protected String readList(IDvInvocation paramIDvInvocation, String arg1) {
154 		log.debug("ReadList: " + arg1 + Utils.getLogText(paramIDvInvocation));
155 		int i = 0;
156 		log.debug("ReadList");
157 		StringBuilder sb = new StringBuilder();
158 		sb.append("<ChannelList>");
159 		for (CustomChannel c : channels) {
160 			i++;
161 			sb.append(c.getFull_text());
162 		}
163 		sb.append("</ChannelList>");
164 		log.debug("ReadList Contains : " + i);
165 		return sb.toString();
166 	}
167 
168 	@Override
169 	protected String read(IDvInvocation paramIDvInvocation, long id) {
170 		log.debug("Read: " + id  +Utils.getLogText(paramIDvInvocation));
171 		CustomChannel c = channels.get((int) id);
172 		return c.getMetadata();
173 	}
174 
175 	@Override
176 	protected String transportState(IDvInvocation paramIDvInvocation) {
177 		log.debug("TransportState" + Utils.getLogText(paramIDvInvocation));
178 		return getPropertyTransportState();
179 	}
180 
181 	@Override
182 	protected void stop(IDvInvocation paramIDvInvocation) {
183 		log.debug("Stop" + Utils.getLogText(paramIDvInvocation));
184 		PlayManager.getInstance().stop();
185 	}
186 
187 	@Override
188 	protected void seekSecondAbsolute(IDvInvocation paramIDvInvocation, long paramLong) {
189 		log.debug("Seek Absolute" + Utils.getLogText(paramIDvInvocation));
190 		//super.seekSecondAbsolute(paramIDvInvocation, paramLong);
191 	}
192 
193 	@Override
194 	protected void seekSecondRelative(IDvInvocation paramIDvInvocation, int paramInt) {
195 		log.debug("Seek Relative" + Utils.getLogText(paramIDvInvocation));
196 		//super.seekSecondRelative(paramIDvInvocation, paramInt);
197 	}
198 
199 	@Override
200 	protected void setId(IDvInvocation paramIDvInvocation, long id, String uri) {
201 		log.debug("Set ID: " + id + " URI: " + uri + Utils.getLogText(paramIDvInvocation));
202 		current_channel = (int) id;
203 		getChannelById();
204 	}
205 
206 	/**
207 	 * Find the Channel by Id
208 	 */
209 	private void getChannelById() {
210 		if (current_channel > 0) {
211 			for (CustomChannel c : channels) {
212 				if (c.getId() == current_channel) {
213 					playChannel(c);
214 					break;
215 				}
216 			}
217 		}
218 	}
219 	
220 	
221 	/**
222 	 * Find the Channel by Name
223 	 * @param name
224 	 */
225 	private synchronized void getChannelByName(String name) {
226 		for (CustomChannel c :channels)
227 		{
228 			if(c.getName().equalsIgnoreCase(name))
229 			{
230 				playChannel(c);
231 				break ;
232 			}
233 		}
234 	}
235 	
236 	/**
237 	 * Play the Channel
238 	 * @param c
239 	 */
240 	private void playChannel(CustomChannel c)
241 	{
242 		current_channel = c.getId();
243 		log.debug("Play Found the Channel: " + current_channel);
244 		PlayManager.getInstance().playFile(c);
245 	}
246 
247 	/***
248 	 * Iterate all tracks, and create a 32 bit binary number from the track Id.
249 	 * Add the 32 bit binary string to a long string Split the 32 bit binary
250 	 * long string 4 bytes (8bits) And add to a byte array
251 	 */
252 	private void UpdateIdArray() {
253 		int size = channels.size() * 4;
254 		StringBuilder sb = new StringBuilder();
255 		byte[] bytes = new byte[size];
256 		int intValue = 1;
257 		for (CustomChannel c : channels) {
258 			try {
259 				String binValue = Integer.toBinaryString(intValue);
260 				binValue = padLeft(binValue, 32, '0');
261 				sb.append(binValue);
262 			} catch (Exception e) {
263 				log.error(e);
264 			}
265 			intValue++;
266 		}
267 		// Now we have a big long string of binary, chop it up and get the
268 		// bytes for the byte array..
269 		String myBytes = sb.toString();
270 		int numOfBytes = myBytes.length() / 8;
271 		bytes = new byte[numOfBytes];
272 		for (int i = 0; i < numOfBytes; ++i) {
273 			int index = 8 * i;
274 			String sByte = myBytes.substring(index, index + 8);
275 			Integer x = Integer.parseInt(sByte, 2);
276 			Byte sens = (byte) x.intValue();
277 			// byte b = Byte.parseByte(sByte, 2);
278 			bytes[i] = sens;
279 		}
280 		array = bytes;
281 		setPropertyIdArray(bytes);
282 	}
283 
284 	private String padLeft(String str, int length, char padChar) {
285 		StringBuilder sb = new StringBuilder();
286 
287 		for (int toPrepend = length - str.length(); toPrepend > 0; toPrepend--) {
288 			sb.append(padChar);
289 		}
290 		sb.append(str);
291 		return sb.toString();
292 	}
293 
294 	private void playingTrack(int iD) {
295 		setPropertyId(iD);
296 	}
297 
298 	private void setStatus(String status) {
299 		setPropertyTransportState(status);
300 
301 	}
302 
303 	@Override
304 	public void update(Observable o, Object arg) {
305 		EventBase e = (EventBase)arg;
306 		switch(e.getType())
307 		{
308 		case EVENTRADIOSTATUSCHANGED:
309 			EventRadioStatusChanged ers = (EventRadioStatusChanged)e;
310 			setStatus(ers.getStatus());
311 			break;
312 		
313 		case EVENTRADIOPLAYINGTRACKID:
314 			EventRadioPlayingTrackID eri = (EventRadioPlayingTrackID)e;
315 			playingTrack(eri.getId());
316 			break;
317 		case EVENTRADIOPLAYNAME:
318 			EventRadioPlayName ern = (EventRadioPlayName)e;
319 			getChannelByName(ern.getName());
320 		}
321 	}
322 
323 
324 
325 }