Package tk.baumi.jaraco

Source Code of tk.baumi.jaraco.JaracoPlayer$PlayingChangeListener

package tk.baumi.jaraco;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.util.ArrayList;

import javax.swing.DefaultListModel;

import javazoom.jl.decoder.Header;
import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.player.AudioDevice;
import javazoom.jl.player.advanced.AdvancedPlayer;
import javazoom.jl.player.advanced.PlaybackEvent;
import javazoom.jl.player.advanced.PlaybackListener;
import javazoom.jl.player.advanced.AdvancedPlayer.AmplitudeListener;

/**
* <p>
* The player is the complete class that provides all methods to play mp3-files.<br/>
* It also hosts the playlist, which is edited by the gui and the network.<br/>
* Moreover the player can exactly show and edit the current position.</p>
* @author Manuel Baumgartner
*
*/
public class JaracoPlayer{
  private AdvancedPlayer p1;
  private DefaultListModel<MusicFile> files = new DefaultListModel<MusicFile>();
  private int currFile = 0, currPosition = 0;
  private boolean repeat = false, playing = false;
  private AudioDevice audio;
  private File fCurrent;
  private FileInputStream fisAudioFile;
  private PlayingChangeListener playChange;
  private PlayingChangeNetworkListener playChangeNetwork;
  private OnPlayingListener playingListener;
  private PlaylistChange playlistChange;
  private OnAmplitudeChangeListener ampChange;
  /**
   * The complete length of the mp3-file.
   * The maximum is given for supporing VBR.
   */
  private int max_frames;
  private float vol1 = 1;//, vol2 = 1;
  /**
   * The player runs in its own thread, also the slider.
   */
  private Thread thPlay, thSlide;
  private byte memAmp = -1;
  public boolean isPlaying() {
    return playing;
  }
  public void setVolume(float vol) {
    vol1 = vol;
    p1.setVolume(vol);
  }
  public interface PlayingChangeListener
  {
    /**
     * Sends the current file to the GUI.
     * @param currFile The current-file number of the list.
     * @param filename The file-path.
     * @param playing true if playback is running.
     */
     public void changePlay(int currFile, String filename, boolean playing);
  }
  public interface PlayingChangeNetworkListener
  {
    public void changePlay(int currFile, String filename, boolean playing, int pos, int max);
  }
  public interface OnPlayingListener
  {
    /**
     * Notifies the GUI when the position of the file has been changed.
     * @param position The current position in frames
     * @param max The maximum-amount of frames.
     */
    public void onPlaying(int position, int max);
  }
  public interface PlaylistChange {
    /**
     * Gets the current playlist in a string-arraylist.
     * @param playlist The playlist.
     */
    public void getPlaylist(ArrayList<String> playlist);
  }
  public interface OnAmplitudeChangeListener{
    /**
     * Gets the amplitude of the current frame
     * @param value The value between 0 and 5
     */
    public void amplitudeChange(byte value);
  }
  /**
   * The method for running playback on the sound-card.
   */
  Runnable player =  new Runnable() {
    @Override
    public void run() {
      try {
        p1.setVolume(vol1);
        p1.play(currPosition, Integer.MAX_VALUE);
       
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  };
  /**
   * The method for setting the current position each second.
   */
  Runnable slide = new Runnable() {
    @Override
    public void run() {
      try {
        while(playing && playingListener != null) {
         
          playingListener.onPlaying(p1.getFramePosition(), max_frames);
         
          Thread.sleep(1000);
        }
      } catch(Exception e) {
       
      }
    }
  };
  /**
   * The playback-listener tells the player if the current song has been
   * finished and also if the playback has
   */
  PlaybackListener playback = new PlaybackListener() {
    /**
     * When the playback starts it calculates the maximum number of frames.
     */
    @Override
    public void playbackStarted(PlaybackEvent evt){
      ////System.out.println("START");
      Header h;
      try {
        h = p1.bitstream.readFrame();
        max_frames = (int)h.max_number_of_frames((int)fCurrent.length());
        //System.out.println(max_frames);
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    /**
     * When the playback has been finished it jumps to the next songs.
     */
    @Override
    public void playbackFinished(PlaybackEvent evt) {
      try {
        if(playing) {
          currPosition = 0;
          playNext();
        }
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  };
 
  public void addFile(String file) {
    addMusicFile(new MusicFile(file));
  }
  /**
   * Adds a music file to the playlist.
   * @param file The file must be an Music-file with an .mp3-ending.
   */
  public void addMusicFile(MusicFile file) {
    if(file.getExtension().equals("mp3")) {
      files.addElement(file);
      if(playlistChange != null) {
        playlistChange.getPlaylist(playListToString());
      }
    } else {
      /*
      try {
        String cmd = "ffmpeg -i \"" + file.getFilename() + "\" \"" + file.getFilename() + ".mp3\" -y";
        System.out.println(cmd);
        Process p = Runtime.getRuntime().exec(cmd);
        p.waitFor();
        if(p.exitValue() == 1) {
          System.out.println(p.exitValue());
          files.addElement(new MusicFile(file.getFilename() + ".mp3"));
        }
      } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }*/
    }
  }
  /**
   * Removes a file from the playlist.
   * @param index of the file to delete.
   */
  public void removeFile(int index) {
    if(index > currFile) {
      files.remove(index);
    } else if(index < currFile) {
      files.remove(index);
      currFile--;
    } else if(index == currFile) {
      stop();
      files.remove(index);
    }
    if(files.size() > 0) {
      playChange.changePlay(currFile, files.get(currFile).getFilename(),playing);
      if(playChangeNetwork != null) {
        playChangeNetwork.changePlay(currFile, files.get(currFile).getFilename(), playing, currPosition, 0);
      }
    }
    if(playlistChange != null) {
      playlistChange.getPlaylist(playListToString());
    }
  }
  /**
   * Swaps two files in the playlist.
   * @param index1 The index of the first file.
   * @param index2 The index of the second file.
   */
  public void changePosition(int index1, int index2) {
    MusicFile help = files.get(index1);
    files.set(index1, files.get(index2));
    files.set(index2, help);
    if(index1 == currFile) {
      currFile = index2;
    }else if(index2 == currFile) {
      currFile = index1;
    }
    playChange.changePlay(currFile, files.get(currFile).getFilename(),playing);
    if(playChangeNetwork != null) {
      playChangeNetwork.changePlay(currFile, files.get(currFile).getFilename(), playing, currPosition, max_frames);
    }
    if(playlistChange != null) {
      playlistChange.getPlaylist(playListToString());
    }
  }
 
  public void resetPosition() {
    currPosition = 0;
  }
  /**
   * Gets an the values of the current file.
   * @return <p>
   *       An string-array of the following elements:
   *       <ul>
   *       <li>The index in the playlist of the current file.</li>
   *       <li>The complete path to the file</li>
   *       <li>t if playing, f if playing</li>
   *       </ul>
   *       </p>
   */
  public String[] getCurrentFile() {
    if(files.size() == 0) {
      return null;
    } else {
      return new String[] {
          String.valueOf(currFile),
          files.get(currFile).getFilename(),
          playing ? "t" : "f"
      };
    }
  }
  /**
   * Starts the playback of the playerInstance.
   * @return true if the playback has stopped, false if playing again.
   * @throws IOException File can't be read.
   * @throws JavaLayerException Music is e.g. not an valid mp3-file.
   */
  public boolean play() throws IOException, JavaLayerException{
    if(playing) {
      playing = false;
      currPosition = p1.getFramePosition();
      p1.stop();
      thPlay.interrupt();
      thPlay = null;
      thSlide.interrupt();
      thSlide = null;
      playChange.changePlay(currFile,files.get(currFile).getFilename() ,playing);
      if(playChangeNetwork != null) {
        playChangeNetwork.changePlay(currFile, files.get(currFile).getFilename(),
            playing, currPosition, max_frames);
      }
      return true;
    } else {
      if(currFile < files.size() && currFile >= 0) {
        playFile(currFile);
        return false;
      } else {
        return true;
      }
    }
  }
  /**
   * Plays the next file in the ArrayList file
   * @return if the playlist is finished, true will be returned.
   * @throws IOException
   * @throws JavaLayerException
   */
  public boolean playNext() throws IOException, JavaLayerException{
    if(currFile >= files.size() - 1 && repeat) {
      currFile = 0;
      currPosition = 0;
      playFile(currFile);
      return false;
    } else if(currFile >= files.size() - 1) {
      playing = false;
      currPosition = 0;
      playChange.changePlay(currFile,files.get(currFile).getFilename(),playing);
      if(playChangeNetwork != null) {
        playChangeNetwork.changePlay(currFile, files.get(currFile).getFilename(),
            playing, currPosition, max_frames);
      }
      return true;
    } else {
      currPosition = 0;
      currFile++;
      playFile(currFile);
      return false;
   
   
  }
  /**
   * Plays the song before the current in the list.
   * @return if you have reached the upper end, true will be returned.
   * @throws IOException
   * @throws JavaLayerException
   */
  public boolean playBefore() throws IOException, JavaLayerException{
    if(currFile > 0) {
      currFile--;
      playFile(currFile);
      return false;
    } else {
      return true;
    }
  }
   
  /**
   * Plays a specific File from the playlist.
   * @param i The number of the playlist
   * @return The name of the played file
   * @throws IOException
   * @throws JavaLayerException
   */
  public String playFile(int i) throws IOException, JavaLayerException{
    if(p1 != null) p1.close();
    if(fisAudioFile != null) {
      try {
        fisAudioFile.close();
      } catch (Exception ex) {}
      fisAudioFile = null;
    }
    if(i < files.size()) {
      fCurrent = new File(files.get(i).getFilename());
      fisAudioFile = new FileInputStream(fCurrent);
      playing = true;
      p1 = new AdvancedPlayer(fisAudioFile);
      p1.setVolume(1);
      p1.setPlayBackListener(playback);
      p1.setAmplitudeListener(new AmplitudeListener() {
       
        @Override
        public void getAmplitude(short amplitude) {
          byte bamp = 0;
          if(amplitude < 10 && amplitude >= 0) {
            bamp = 0;
          } else if(amplitude < 6400) {
            bamp = 1;
          } else if(amplitude < 12800) {
            bamp = 2;
          } else if(amplitude < 19200) {
            bamp = 3;
          } else if(amplitude < 25600) {
            bamp = 4;
          } else if(amplitude < 32000) {
            bamp = 5;
          } else {
            bamp = 6;
          }
          if(bamp != memAmp) {
            if(ampChange != null) {
              ampChange.amplitudeChange(bamp);
            }
            memAmp = bamp;
          }
        }
      });
      thPlay = new Thread(player);
      thPlay.start();
     
      thSlide = new Thread(slide);
      thSlide.start();
      if(i != currFile) {
        currFile = i;
      }
      if(playChange != null) {
        playChange.changePlay(i, files.get(currFile).getFilename() ,true);
      }
      if(playChangeNetwork != null) {
        playChangeNetwork.changePlay(currFile, files.get(currFile).getFilename(), true,
            currPosition, max_frames);
      }
      return files.get(i).getFilename();
    } else if(repeat == true) {
      currFile = 0;
      fCurrent = new File(files.get(i).getFilename());
      FileInputStream fis = new FileInputStream(fCurrent);
      playing = true;
      p1 = new AdvancedPlayer(fis, audio);
      p1.setPlayBackListener(playback);
      thPlay = new Thread(player);
      thPlay.start();
      thSlide = new Thread(slide);
      thSlide.start();
      if(playChange != null) {
        playChange.changePlay(currFile, files.get(currFile).getFilename() ,true);
      }
      if(playChangeNetwork != null) {
        playChangeNetwork.changePlay(currFile, files.get(currFile).getFilename(), true,
            currPosition, max_frames);
      }
      return files.get(currFile).getFilename();
    } else {
      return null;
    }
  }
  /**
   * Sets the position of playback<br/>
   * normally called from the JSlider of the GUI.
   * @param pos The position, normally the frame.
   * @throws IOException IO-errors from playback.
   * @throws JavaLayerException mp3-errors from playback.
   */
  public void setPosition(int pos) throws IOException, JavaLayerException {
    boolean cont = false;
    if(playing) {
      play();
      cont = true;
    }
    currPosition = pos;
    if(cont) {
      try {
        play();
      } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      } catch (JavaLayerException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
  }
  /**
   * Stops the playback and sets the position back to zero.
   */
  public void stop() {
    if(playing) {
      playing = false;
      currPosition = 0;
      ////System.out.println(currPosition);
      p1.stop();
      thPlay.interrupt();
      thPlay = null;
      thSlide.interrupt();
      thSlide = null;
      playChange.changePlay(currFile, files.get(currFile).getFilename() ,playing);
      if(playChangeNetwork != null) {
        playChangeNetwork.changePlay(currFile, files.get(currFile).getFilename(), playing,
            currPosition, max_frames);
      }
    }
  }
 
  public boolean isInitialized() {
    if(p1 == null) {
      return false;
    } else {
      return true;
    }
  }
 
  public void setRepeat(boolean repeat) {
    this.repeat = repeat;
  }
 
  public DefaultListModel<MusicFile> getList() {
    return files;
  }
 
  public void setPlayingChangeNetworkListener(PlayingChangeNetworkListener playChangeNetwork) {
    this.playChangeNetwork = playChangeNetwork;
  }
 
  public void setPlayingChangeListener(PlayingChangeListener playChange) {
    this.playChange = playChange;
  }
 
  public void setOnPlayingListener(OnPlayingListener playingListener) {
    this.playingListener = playingListener;
  }
 
  public void setPlaylistchange(PlaylistChange playlistchange) {
    this.playlistChange = playlistchange;
  }
  /**
   * Adds a vote to an song.
   * @param songId The index in the playlist.
   * @param client The IP-address of the client.
   */
  public void voteSong(int songId, InetAddress client) {
    if(songId < files.size()) {
      files.get(songId).addVote(client);
      voteInvalidate();
    }
  }
  /**
   * Calls the sort for the playlist and sends the new playlist to each user.
   */
  public void voteInvalidate() {
    int currSong = currFile;
    if(currSong < files.size() - 1) {
      sort(files, currSong + 1, files.size() - 1);
      if(playlistChange != null) {
        playlistChange.getPlaylist(playListToString());
      }
    }
  }
  /**
   * A merge-sort implementation for sorting the playlist.
   * @param songs The DefaultListModel for the playlist.
   * @param start The starting-point (important for mergesort)
   * @param end The ending-point (important for mergesort)
   */
  public void sort(DefaultListModel<MusicFile> songs, int start, int end) {
    if(start < end) {
      int middle = (end + start) / 2;
      sort(songs, start, middle);
      sort(songs, middle + 1, end);
     
      int i = start, j = middle + 1, k = start;
      MusicFile[] help = new MusicFile[songs.size()];
      for(; i <= end; i++) {
        help[i] = songs.get(i);
      }
      i = start;
      while(i <= middle && j <= end) {
        if(help[i].compareTo(help[j]) >= 0) {
          songs.set(k++, help[i++]);
        } else {
          songs.set(k++, help[j++]);
        }
      }
      while(i <= middle) {
        songs.set(k++, help[i++]);
      }
    }
  }
  /**
   * Gets an array-list of string-representations of the playlist.
   * @return ArrayList of the whole playlist.
   */
  public ArrayList<String> playListToString() {
    ArrayList<String> arPlaylist = new ArrayList<String>();
    for(int i = 0; i < files.size(); i++) {
      arPlaylist.add(files.get(i).getName() + "(" + files.get(i).getVotes() +")");
    }
    return arPlaylist;
  }
 
  public void setAmplitudeChangeListener(OnAmplitudeChangeListener ampChange) {
    this.ampChange = ampChange;
  }

}
TOP

Related Classes of tk.baumi.jaraco.JaracoPlayer$PlayingChangeListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
', 'auto'); ga('send', 'pageview');