/* * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is the Kowari Metadata Store. * * The Initial Developer of the Original Code is Plugged In Software Pty * Ltd (http://www.pisoftware.com, mailto:info@pisoftware.com). Portions * created by Plugged In Software Pty Ltd are Copyright (C) 2001,2002 * Plugged In Software Pty Ltd. All Rights Reserved. * * Contributor(s): N/A. * * [NOTE: The text of this Exhibit A may differ slightly from the text * of the notices in the Source Code files of the Original Code. You * should use the text of this Exhibit A rather than the text found in the * Original Code Source Code for Your Modifications.] * */ package org.mulgara.demo.mp3.playback; // Java 2 standard packages import java.util.*; // Logging import org.apache.log4j.Logger; // JRDF import org.jrdf.graph.*; // Local packages import org.mulgara.demo.mp3.*; /** * Used to play, pause, resume, skip and stop playback of Mp3/Audio files. * * @created 2004-12-10 * * @author <a href="mailto:robert.turner@tucanatech.com">Robert Turner</a> * * @version $Revision: 1.3 $ * * @modified $Date: 2005/01/05 04:58:06 $ * * @maintenanceAuthor $Author: newmana $ * * @company <A href="mailto:info@PIsoftware.com">Plugged In Software</A> * * @copyright ©2001 <a href="http://www.pisoftware.com/">Plugged In * Software Pty Ltd</a> * * @licence <a href="{@docRoot}/../../LICENCE">Mozilla Public License v1.1</a> */ public class Mp3Player extends PlaybackThreadListener { /** * Logger. This is named after the class. */ private final static Logger log = Logger.getLogger(Mp3Player.class. getName()); /** Indicates a playing state */ public final static int PLAYING = 0; /** Indicates a paused state */ public final static int PAUSED = 1; /** Indicates a stopped state */ public final static int STOPPED = 2; /** Current state */ private int state = STOPPED; /** Mp3 to be played */ private Mp3File mp3 = null; /** CurrentThread being run */ private PlaylistThread playThread = null; /** Receives events/exceptions during playback */ private PlaybackThreadListener listener = null; /** * Default constructor */ public Mp3Player() { } /** * Begins playback. * @throws Exception */ public synchronized void play() throws Exception { newPlaybackThread(getMp3File()).start(); } /** * Plays all Mp3s in the array until stop is called. * * @throws Exception * @param mp3s Mp3File[] */ public synchronized void playFiles(Mp3File[] mp3s) throws Exception { if ((mp3s == null) || (mp3s.length <= 0)) { return; } //play each file (unless stopped) newPlaybackThread(mp3s).start(); } /** * Plays all Mp3s in the array until stop is called. * * @throws Exception * @param mp3s Mp3File[] */ public synchronized void playFiles(Iterator mp3s) throws Exception { if (mp3s == null) { return; } //play each file (unless stopped) newPlaybackThread(mp3s).start(); } /** * Pauses platback. * @throws Exception */ public synchronized void pausePlayback() throws Exception { if ((getState() != PLAYING) || (playThread == null)) { throw new IllegalStateException("Cannot pause. Mp3Player is not playing"); } playThread.pausePlayback(); setState(PAUSED); } /** * Resumes playback from where it was last paused * @throws Exception */ public synchronized void resumePlayback() throws Exception { if (getState() != PAUSED) { throw new IllegalStateException("Cannot resume. Mp3Player has not " + "been paused."); } if (playThread == null) { throw new IllegalStateException("Cannot resume. Cannot determine mp3 " + "to resume."); } playThread.resumePlayback(); setState(PLAYING); } /** * Stops playback * @throws Exception */ public synchronized void stopPlayback() throws Exception { killPlaybackThread(); } /** * Skips the currently playing track. * @throws Exception */ public synchronized void skipTrack() throws Exception { if (playThread == null) { throw new IllegalStateException("No Mp3s are playing"); } playThread.skip(); } /** * Sets the Mp3 to be played. * @param mp3 Mp3File * @throws IllegalArgumentException */ public synchronized void setMp3File(Mp3File mp3) throws IllegalArgumentException { if (mp3 == null) { throw new IllegalArgumentException("Mp3File is null"); } this.mp3 = mp3; } /** * Returns the Mp3 set by setMp3File. * * @throws IllegalStateException * @return Mp3File */ public synchronized Mp3File getMp3File() throws IllegalStateException { if (mp3 == null) { throw new IllegalStateException("Mp3File has not been set."); } return mp3; } /** * Returns the current state of the Player. * @return int */ public int getState() { return state; } /** * Sets the current state of the player to be one of: * <ul> * <li>PLAYING</li> * <li>PAUSED</li> * <li>STOPPED</li> * </ul> * @param state int * @throws IllegalArgumentException */ private void setState(int state) throws IllegalArgumentException { if ((state > 2) || (state < 0)) { throw new IllegalArgumentException("Unknown state."); } this.state = state; } /** * Returns a String that represents the specific state. * @param state int * @throws IllegalArgumentException * @return String */ private String stateString(int state) throws IllegalArgumentException { switch (state) { case (PLAYING) : return "PLAYING"; case (PAUSED) : return "PAUSED"; case (STOPPED) : return "STOPPED"; default: throw new IllegalArgumentException("Unknown state"); } } /** * Sets the Listener to recieve playback events/errors. * @param listener PlaybackListener */ public synchronized void setPlaybackListener(PlaybackThreadListener listener) { this.listener = listener; } /** * Kills any currently executing threads and creates a new one for the mp3. * <p>Returns the current/new PlaybackThread (playThread). * @param file Mp3File * @throws Exception * @return PlaybackThread */ private synchronized PlaybackThread newPlaybackThread(Mp3File file) throws Exception { killPlaybackThread(); PlaybackThread thread = new PlaybackThreadImpl(file, this); Iterator iter = Collections.singletonList(thread).iterator(); playThread = new PlaylistThreadImpl(iter, this); return playThread; } /** * Kills any currently executing threads and creates a new one that will play * all mp3s in the array. * * <p>Returns the current/new PlaybackThread (playThread). * * @param files Mp3File * @throws Exception * @return PlaybackThread */ private synchronized PlaybackThread newPlaybackThread(Mp3File[] files) throws Exception { killPlaybackThread(); if (files == null) { throw new IllegalArgumentException("Mp3File array is null."); } //convert files to PlaybackThreads PlaybackThreadImpl[] threads = new PlaybackThreadImpl[files.length]; for (int i = 0; i < files.length; i++) { threads[i] = new PlaybackThreadImpl(files[i], this); } //return a list that contains all threads playThread = new PlaylistThreadImpl(threads, this); return playThread; } /** * Kills any currently executing threads and creates a new one that will play * all mp3s in the array. * * <p>Returns the current/new PlaybackThread (playThread). * * @param files Mp3File * @throws Exception * @return PlaybackThread */ private synchronized PlaybackThread newPlaybackThread(Iterator files) throws Exception { killPlaybackThread(); if (files == null) { throw new IllegalArgumentException("Mp3File array is null."); } //convert files to PlaybackThreads List threadList = new ArrayList(); while (files.hasNext()) { threadList.add(new PlaybackThreadImpl((Mp3File) files.next(), this)); } //return a list that contains all threads playThread = new PlaylistThreadImpl(threadList.iterator(), this); return playThread; } /** * Kills any executing Playback Thread and waits for it to die. * @throws Exception */ private synchronized void killPlaybackThread() throws Exception { if (playThread != null) { playThread.terminate(); } } /** * Returns the currently executing playback thread. * @throws IllegalStateException * @return PlaybackThread */ private synchronized PlaybackThread getPlaybackThread() throws IllegalStateException { if (playThread == null) { throw new IllegalStateException("No Thread is currently playing."); } return playThread; } /** * Terminates any executing Thread. * @throws Exception */ public synchronized void close() throws Exception { killPlaybackThread(); } /** * Indicates an exception occurred during playback. * @param t Throwable */ public void exceptionOccurred(Throwable t) { if (listener != null) { listener.exceptionOccurred(t); } } /** * Indicates that the resource has began playing. * @param resource URIReference */ public void playbackStarted(URIReference resource) { setState(PLAYING); if (listener != null) { listener.playbackStarted(resource); } } /** * Indicates that the thread has finished. */ public void playbackComplete() { setState(STOPPED); if (listener != null) { listener.playbackComplete(); } } /** * Indicates that playback has been paused */ public void playbackPaused() { setState(PAUSED); if (listener != null) { listener.playbackPaused(); } } /** * Indicates that playback has resumed */ public void playbackResumed() { setState(PLAYING); if (listener != null) { listener.playbackResumed(); } } }