package com.zaranux.os.client.programs;
import java.util.HashMap;
import java.util.Set;
import com.allen_sauer.gwt.voices.client.Sound;
import com.allen_sauer.gwt.voices.client.SoundController;
import com.allen_sauer.gwt.voices.client.handler.PlaybackCompleteEvent;
import com.allen_sauer.gwt.voices.client.handler.SoundHandler;
import com.allen_sauer.gwt.voices.client.handler.SoundLoadStateChangeEvent;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.user.client.ui.ListBox;
import com.smartgwt.client.widgets.IButton;
import com.smartgwt.client.widgets.Slider;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.events.ValueChangedEvent;
import com.smartgwt.client.widgets.events.ValueChangedHandler;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;
import com.zaranux.client.api.AsyncCallback;
import com.zaranux.os.client.core.Program;
import com.zaranux.os.client.util.Log;
import com.smartgwt.client.widgets.ImgButton;
import com.smartgwt.client.types.SelectionType;
public class MediaPlayer extends Program{
private final static HashMap<String, String> types = new HashMap<String, String>();
private final SoundController soundController = new SoundController();
private ListBox trackList = new ListBox();
private boolean isMuted= false; //to switch between mute/unmute
private int volume = 50; //to save volume value changes when player is mute.
public MediaPlayer(String[] array) {
this.args = array;
}
private void setButtonIcon(IButton button, String icon){
button.setIcon(getIconURL(icon));
}
private void fillTypes() {
types.put("au", Sound.MIME_TYPE_AUDIO_BASIC);
types.put("snd", Sound.MIME_TYPE_AUDIO_BASIC);
types.put("mp3", Sound.MIME_TYPE_AUDIO_MPEG);
types.put("mp2", Sound.MIME_TYPE_AUDIO_MPEG);
types.put("mp1", Sound.MIME_TYPE_AUDIO_MPEG);
types.put("mpeg", Sound.MIME_TYPE_AUDIO_MPEG);
types.put("aif", Sound.MIME_TYPE_AUDIO_X_AIFF);
types.put("midi", Sound.MIME_TYPE_AUDIO_X_MIDI);
types.put("mid", Sound.MIME_TYPE_AUDIO_X_MIDI);
types.put("wav", Sound.MIME_TYPE_AUDIO_X_WAV);
}
public String getMimeType(String ext) {
Set<String> keys = types.keySet();
for (String key : keys) {
if(key.equalsIgnoreCase(ext))
return types.get(key);
}
return Sound.MIME_TYPE_AUDIO_MPEG;
}
String[] files;
int index = 0; // current file
@Override
protected void main(String[] args) {
files = args;
fillTypes();
fillTrackList();
//TODO setHeaderIcon(getIconURL("media.gif"));
final ImgButton play = new ImgButton();
play.setShowRollOver(true);
play.setShowDisabled(true);
play.setShowDown(true);
play.setActionType(SelectionType.BUTTON);
//setButtonIcon(play,"play.PNG");
play.setSrc("player/play.png");
play.setSize(25);
play.setTooltip("Play");
play.addClickHandler(new ClickHandler(){
public void onClick(ClickEvent event) {
activeSound.stop();
int trackNO = trackList.getSelectedIndex();
play(trackNO);
}});
final ImgButton stop = new ImgButton();
stop.setSize(25);
stop.setShowRollOver(true);
stop.setShowDisabled(true);
stop.setShowDown(true);
stop.setSrc("player/stop.png");
//setButtonIcon(stop,"stop.PNG");
stop.setTooltip("Stop");
stop.addClickHandler(new ClickHandler(){
public void onClick(ClickEvent event) {
activeSound.stop();
}
});
final ImgButton next = new ImgButton();
next.setSize(25);
next.setShowRollOver(true);
next.setShowDisabled(true);
next.setShowDown(true);
//setButtonIcon(next,"next.PNG");
next.setSrc("player/next.png");
next.setTooltip("Next");
next.addClickHandler(new ClickHandler(){
public void onClick(ClickEvent event) {
activeSound.stop();
int trackNO = (index + 1 ) % files.length; // point to the next file
play(trackNO);
}
});
final ImgButton previous = new ImgButton();
previous.setSize(25);
previous.setShowRollOver(true);
previous.setShowDisabled(true);
previous.setShowDown(true);
//setButtonIcon(previous,"previous.PNG");
previous.setSrc("player/previous.png");
previous.setTooltip("Previous");
previous.addClickHandler(new ClickHandler(){
public void onClick(ClickEvent event) {
activeSound.stop();
int trackNO = (index - 1 +files.length) % files.length; // point to the previous file
play(trackNO);
}});
final ImgButton mute = new ImgButton();
mute.setSize(25);
mute.setShowRollOver(true);
mute.setShowDisabled(true);
mute.setShowDown(true);
//setButtonIcon(mute,"unmute.PNG");
mute.setSrc("player/unmuted.png");
mute.setTooltip("Mute");
mute.addClickHandler(new ClickHandler(){
public void onClick(ClickEvent event) {
//switch between mute and unmute
if(!isMuted){
volume = activeSound.getVolume();
activeSound.setVolume(0);
//setButtonIcon(mute,"mute.PNG");
mute.setSrc("player/muted.png");
isMuted = true;
}else{
activeSound.setVolume(volume);
//setButtonIcon(mute,"unmute.PNG");
mute.setSrc("player/unmuted.png");
isMuted = false;
}
}});
final Slider volumeSlider = new Slider("");
volumeSlider.setVertical(false);
volumeSlider.setValue(50);
volumeSlider.setShowRange(false);
volumeSlider.setShowTitle(false);
volumeSlider.setShowValue(false);
volumeSlider.setWidth(75);
volumeSlider.addValueChangedHandler(new ValueChangedHandler() {
public void onValueChanged(ValueChangedEvent event) {
volume = event.getValue();
//if user mute the sound,changing volume bar should not affect immidiately.
if(!isMuted)
activeSound.setVolume(volume);
if (volumeSlider.getValue() != volume) {
volumeSlider.setValue(volume);
}
}
});
HLayout hLayout1 = new HLayout();
hLayout1.setMembersMargin(5);
hLayout1.addMember(previous);
hLayout1.addMember(play);
hLayout1.addMember(stop);
hLayout1.addMember(next);
hLayout1.addMember(mute);
VLayout layout = new VLayout();
layout.setAutoHeight();
layout.setMembersMargin(10);
layout.setLayoutMargin(12);
layout.addMember(trackList);
layout.addMember(hLayout1);
//layout.setBorder("15px ridge green");
setWidget(layout, 300,270);
play(0);
hLayout1.addMember(volumeSlider);
}
/*
* Plays the specified track. setting current index to trackNo.
*/
private void play(int trackNo) {
index= trackNo;
trackList.setSelectedIndex(index);
playNext(new AsyncCallback<Boolean>()
{
public void onSuccess(Boolean b)
{
//callback.onSuccess(b);
}
public void onFailure(Throwable t)
{
//callback.onFailure(t);
}
});
}
/*
* fill the listBox with the names of sound files.
* ListBox has fixed size. If number of tracks exceed from the size, the scrollbar will be activated.
*/
private void fillTrackList() {
for (String file : files) {
trackList.addItem(getName(file));
}
trackList.setVisibleItemCount(files.length+1);
trackList.setSize("250", "150");
//When user clicks on track in the tracklist, that track will be played.
trackList.addClickHandler(new com.google.gwt.event.dom.client.ClickHandler(){
public void onClick(com.google.gwt.event.dom.client.ClickEvent arg0) {
activeSound.stop();
int trackNO = trackList.getSelectedIndex();
play(trackNO);
}
});
//to handle Enter key for playing tarck selected in list
trackList.addKeyDownHandler(new KeyDownHandler(){
public void onKeyDown(KeyDownEvent arg0) {
if(arg0.getNativeKeyCode() == 13 ){ //Pressing Enter
{
activeSound.stop();
int trackNO = trackList.getSelectedIndex();
play(trackNO);
}
}
}
});
}
private String getName(String file) {
int lastSlash = file.lastIndexOf("/");
return file.substring(lastSlash+1);
}
private String getIconURL(String icon) {
return GWT.getModuleBaseURL() + "images/player/" +icon;
}
Sound activeSound ;
public void playNext(final AsyncCallback<Boolean> callback)
{
if(index >= files.length) callback.onSuccess(true); // done ; stop condition for recursive operation
else
{
final String ext = files[index].substring(files[index].lastIndexOf(".")+1);
systemcall.delegate(null, "zaranux.com", null, -1, new AsyncCallback<String>()
{
public void onSuccess(String token)
{
//String url = "/@" + files[index] + "?" +"identity=" + systemcall.userid() + "&identityAssertion=" + token;
String path = files[index];
String url = (path.startsWith("@") || path.startsWith("/@")) ? path : ("/@" + path); // + "?" +"identity=" + systemcall.userid() + "&identityAssertion=" + token;
String identity = systemcall.userid();
if(identity != null && !identity.equals(""))
{
url += "?" +"identity=" + systemcall.userid() + "&identityAssertion=" + token;
}
//Mashlet mashlet = new Mashlet(url);
//mashlet.setWidth("500px");
//mashlet.setPixelSize(500, 400);
//setWidget(mashlet);
String mimeType = getMimeType(ext);
activeSound = soundController.createSound(mimeType,url,true);
// add a sound handler so we know when the sound has loaded/completed
activeSound.addEventHandler(new SoundHandler()
{
public void onPlaybackComplete(PlaybackCompleteEvent event) {
int trackNO = (index + 1 ) % files.length; // point to the next file
play(trackNO);
}
public void onSoundLoadStateChange(SoundLoadStateChangeEvent event) {
}
});
activeSound.play();
if(isMuted)
activeSound.setVolume(0);
else
activeSound.setVolume(volume);
setStatus(getName(path) + " is playing now...");
}
public void onFailure(Throwable caught)
{
setStatus("" + caught);
}
}
);
}
}
// to be overriden by programs
protected void finalize()
{
activeSound.stop();
}
}