⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 basicplayer.java

📁 J2me唆哈的代码
💻 JAVA
字号:
/*
 * Created on 2005-9-27 by pcy
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package a.a.a.mmedia;

import javax.microedition.media.*;
import javax.microedition.media.control.*;
import java.util.*;
import java.io.*;
import javax.microedition.io.*;

public abstract class BasicPlayer implements Player, VolumeControl {


    private static int pcount = -1;

    private static Hashtable mplayers = new Hashtable(4);

    private static Object idLock = new Object();

    private String locator;

    int state = UNREALIZED;

    int loopCountSet = 1, loopCount;

    boolean EOM = false;

    boolean loopAfterEOM = false;

    Vector listeners = new Vector(2);

    EvtQ evtQ = null;

    Object evtLock = new Object();

    protected int pID = 0;


    public BasicPlayer() {
        synchronized (idLock) {
            pcount = (pcount+1) % 32767;
            pID = pcount;
        }
        mplayers.put(new Integer(pID), this);
    }

    
    protected void chkClosed(boolean unrealized) {
        if (state == CLOSED || (unrealized && state == UNREALIZED)) { 
            throw new IllegalStateException("The Player is " +
                (state == CLOSED ? "closed" : "unrealized"));
        }
    }

    public void setLoopCount(int count) throws IllegalArgumentException, IllegalStateException {
        chkClosed(false);
        if (state == STARTED){
            throw new IllegalStateException("setLoopCount");
        }
        if (count == 0 || count < -1){
            throw new IllegalArgumentException("setLoopCount");
        }
        loopCountSet = count;
        loopCount = count;
    }

    public synchronized void realize() throws MediaException {
        chkClosed(false);
    
        if (state >= REALIZED)
            return;
    
        doRealize();
        state = REALIZED;
    }

    abstract protected void doRealize() throws MediaException;


    public synchronized void prefetch() throws MediaException {
        
        chkClosed(false);
    
        if (state >= PREFETCHED)
            return;
    
        if (state < REALIZED)
            realize();
            
        doPrefetch();
    
        state = PREFETCHED;
    }

    abstract protected void doPrefetch() throws MediaException;

    public synchronized void start() throws MediaException {
    
        chkClosed(false);

        if (state >= STARTED){
            return;
        }
    
        if (state < REALIZED){
            realize();
        }
    
        if (state < PREFETCHED){
            prefetch();
        }
    
        // If it's at the EOM, it will automatically
        // loop back to the beginning.
        if (EOM){
            setMediaTime(0);
        }
    
        if (!doStart()){
            throw new MediaException("start");
        }
        state = STARTED;
        sendEvent(PlayerListener.STARTED, new Long(getMediaTime()));
    }

    abstract protected boolean doStart();


    public synchronized void stop() {
        chkClosed(false);
    
        loopAfterEOM = false;
        
        if (state < STARTED){
            return;
        }
    
        doStop();
    
        state = PREFETCHED;
        sendEvent(PlayerListener.STOPPED, new Long(getMediaTime()));
    }


    abstract protected void doStop();

    public synchronized void deallocate() {
        chkClosed(false);
    
        loopAfterEOM = false;
        
        if (state < PREFETCHED){
            return;
        }
    
        if (state == STARTED){
            stop();
        }
    
        doDeallocate();
        state = REALIZED;
    }

    abstract protected void doDeallocate();


    public synchronized void close() {
        if (state == CLOSED){
            return;
        }
        
        deallocate();
        doClose();
    
        state = CLOSED;
        try {
            if (stream != null)
            stream.close();
        } catch (IOException e) { }
        sendEvent(PlayerListener.CLOSED, null);
        mplayers.remove(new Integer(pID));
    }

    abstract protected void doClose();

    public synchronized long setMediaTime(long now) throws MediaException {
        
        chkClosed(true);
    
        if (now < 0)
            now = 0;
        
        long theDur = getDuration();
        if ((theDur != TIME_UNKNOWN) && (now > theDur))
            now = theDur;
    
        long rtn = doSetMediaTime(now);
        EOM = false;
    
        return rtn;
    }

    abstract protected long doSetMediaTime(long now) throws MediaException;

    public long getMediaTime() {
        chkClosed(false);
        return doGetMediaTime();
    }

    abstract protected long doGetMediaTime();

    public int getState() {
        return state;
    }

    public long getDuration() {
        chkClosed(false);
        return doGetDuration();
    }

    abstract protected long doGetDuration();

    public void addPlayerListener(PlayerListener playerListener) {
        chkClosed(false);
        if (playerListener != null){
            listeners.addElement(playerListener);
        }
    }

    public void removePlayerListener(PlayerListener playerListener) {
        chkClosed(false);
        listeners.removeElement(playerListener);
    }

    public void sendEvent(String evt, Object evtData) {

        //  There's always one listener for EOM -- itself.
        if (listeners.size() == 0 && evt != PlayerListener.END_OF_MEDIA){
            return;
        }
        // Deliver the event to the listeners.
        synchronized (evtLock) {
            if (evtQ == null)
            evtQ = new EvtQ(this);
            evtQ.sendEvent(evt, evtData);
        }
    }


    synchronized void doLoop() {

    // If a loop count is set, we'll loop back to the beginning.
    	if ((loopCount > 1) || (loopCount == -1)) {
            try {
                if (setMediaTime(0) == 0) {
                    if (loopCount > 1){
                        loopCount--;
                    }
                    
                    start();
                } else{
                    loopCount = 1;
                }
            } catch (MediaException ex) {
                loopCount = 1;
            }
        } else if (loopCountSet > 1){
            loopCount = loopCountSet;
        }
    
        loopAfterEOM = false;
    }

    public Control[] getControls() {
        chkClosed(true);
        return new Control[] { this };
    }

    public Control getControl(String type) {
        chkClosed(true);
    
        // Prepend the package name if the type given does not
        // have the package prefix.
        if (type.indexOf('.') < 0){
            return doGetControl("javax.microedition.media.control." + type);
        }        
        return doGetControl(type);
    }

    abstract protected Control doGetControl(String type);

    public static BasicPlayer get(int pid) {
        return (BasicPlayer)(mplayers.get(new Integer(pid)));
    }


    /**
     * ==========================
     * Methods for VolumeControl.
     * ==========================
     */

    private int  level = -1;

    private boolean mute;

    protected abstract int doSetLevel(int vol);

    public void setMute(boolean mute) {
        if (mute && !this.mute) {
            doSetLevel(0);
            this.mute = true;
            sendEvent(PlayerListener.VOLUME_CHANGED, this);
        } else if (!mute && this.mute) {
            this.level = doSetLevel(level);
            this.mute = false;
            sendEvent(PlayerListener.VOLUME_CHANGED, this);
        }
    }

    public boolean isMuted() {
        return mute;
    }

    public int setLevel(int ll) {
        int newl;
    
        if (ll < 0) {
            ll  = 0;
        } else if (ll > 100) {
            ll = 100;
        } 
    
        if (!mute) {
            newl = doSetLevel(ll);
            if (newl != level) {
                level = newl;
                sendEvent(PlayerListener.VOLUME_CHANGED, this);
            }
        }
        return level;
    }

    public int getLevel() {
        return level;
    }

    /**
     * ================
     * Input functions.
     * ================
     */

    protected InputStream stream;

    long location;

    public void setLocator(String locator, boolean con) throws IOException, MediaException {
        this.locator = locator;
        if (con){
            openConnection();
        }
    }

    public void setStrm(InputStream stream) {
        this.stream = stream;
    }

    private void openConnection() throws IOException, MediaException {
        try {
            HttpConnection httpCon = (HttpConnection)Connector.open(locator);
            int rescode = httpCon.getResponseCode();
            // both 4XX and 5XX are error codes
            if (rescode >= 400) {
                httpCon.close();
                throw new IOException("bad url");
            } else {
                stream = httpCon.openInputStream();
                String ctype = httpCon.getType();
                boolean supportedCT = false;
                if (locator.endsWith(".wav")) {
                    supportedCT = true;
                } else if (ctype != null && 
                       ctype.toLowerCase().equals("audio/x-wav")) {
                    supportedCT = true;
                }
                    
                httpCon.close();
        
                if (!supportedCT) {
                    stream.close();
                    stream =  null;
                    throw new MediaException("unsupported media type");
                }
            }
        } catch (IOException ioex) {
            throw ioex;
        } catch (MediaException mex) {
            throw mex;
        } catch (Exception ex) {
            new IOException(ex.getMessage() + " failed to connect");
        }
    
        location = 0;
    }

    protected int readStrm(byte buffer[], int offset, int length)throws IOException {
        int len = stream.read(buffer, offset, length);
        if (len > 0){
            location += len;
        }
        return len;
    }

    protected long seekStrm(long where) throws IOException, MediaException {
        if (stream == null){
            return location;
        }
        long skipped, oldLocation = location;
        if (where < oldLocation) { // seek backward
            reopenStrm();
            location = 0;
            skipped = stream.skip(where);
        } else  {
            skipped = stream.skip((where - oldLocation));
        }
    
        if (skipped > 0){
            location += skipped;
        }
    
        return location;
    }

    protected long skipStrm(int numBytes) throws IOException {
        long skipped = stream.skip(numBytes);
        /*if (skipped > 0){
            location += skipped;
        }*/
        if (skipped < numBytes){
            throw new IOException("skipped over eom");
        }
        return (skipped);
    }

    private void reopenStrm() throws IOException, MediaException {
        try {
            stream.reset();
            return;
        } catch (IOException ex) {
            if (locator == null){
                throw ex;
            }
        }
    
        try {
            stream.close();
            stream = null;
        } catch (IOException e) {}

        openConnection();
    }

    protected long getStrmLoc() {
        return location;
    }
}


class EvtQ extends Thread {

    private BasicPlayer p;

    private String[] evtQ;

    private Object[] evtDataQ;

    private int head, tail;

    private static final int size = 12;

    EvtQ(BasicPlayer p) {
        this.p = p;
        evtQ = new String[size];
        evtDataQ = new Object[size];
        start();
    }

    synchronized void sendEvent(String evt, Object evtData) {
        while ((head + 1) % size == tail) {
            try {
                wait();
            } catch (Exception e) { }
        }
        evtQ[head] = evt;
        evtDataQ[head] = evtData;
        if (++head == size){
            head = 0;
        }
        notify();
    }

    /**
     * the run method for interface Runnable
     */
    public void run() {

        String evt = "";
        Object evtData = null;
        boolean evtToGo = false;
    
        for (;;) {
    
            synchronized (this) {
    
            // If the queue is empty, we'll wait for at most
            // 5 secs.
            if (head == tail) {
                try {
                    wait(5000);
                } catch (Exception e) {
                }
            } 
    
            if (head != tail) { 
                evt = evtQ[tail];
                evtData = evtDataQ[tail];
                // For garbage collection.
                evtDataQ[tail] = null;
                evtToGo = true;
                if (++tail == size)
                tail = 0;
                notify();
            } else
                evtToGo = false;
    
            } // synchronized this
    
            if (evtToGo) {
                if (evt == PlayerListener.END_OF_MEDIA) {
                    synchronized (p) {
                        p.EOM = true;
                        p.loopAfterEOM = false;
                        if (p.state > Player.PREFETCHED) {
                            p.state = Player.PREFETCHED;
                            if (p.loopCount > 1 || p.loopCount == -1) {
                                p.loopAfterEOM = true;
                            }
                        }
                    }
                }
    
            synchronized (p.listeners) {
                PlayerListener l;
                for (int i = 0; i < p.listeners.size(); i++) {
                    try {
                        l = (PlayerListener)p.listeners.elementAt(i);
                        l.playerUpdate(p, evt, evtData);
                    } catch (Exception e) {
                        System.err.println("Error in playerUpdate: " + e);
                    }
                }
            }
    
            if (p.loopAfterEOM) 
                p.doLoop();
            }
            
            if (!evtToGo || evt == PlayerListener.CLOSED) {
            // If there's no event waking up after 5 secs,
            // we'll kill the thread.
                synchronized (p.evtLock) {
                    p.evtQ = null;
                    break;
                }
            }
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -