This the error i get when i try to run my program
Basically i have a mediapanel class that initialize and play the media as datasource
The ByteBufferDataS ource class is use to create the datasource for the player
Here is where my problem lies, i have a SeekableStream to manipulate the control of the streaming position.
Code:
Error: Unable to realize com.sun.media.amovie.AMController@18b81e3
Code:
import java.awt.BorderLayout; import java.awt.Component; import java.io.*; import java.net.URL; import javax.media.*; import javax.swing.JPanel; import java.nio.ByteBuffer; public class MediaPanel extends JPanel { InputStream stream; String name = ""; ByteBuffer inputBuffer; byte[] store = null; public MediaPanel( InputStream in ) { try{ this.stream = in; //store stream as ByteBuffer store = new byte[stream.available()]; stream.read(store); inputBuffer.allocate(store.length); inputBuffer.wrap(store); //get contentType DrmDecryption drm = new DrmDecryption(); name = drm.naming; setLayout( new BorderLayout() ); // use a BorderLayout ByteBufferDataSource ds = new ByteBufferDataSource(inputBuffer,name); // Use lightweight components for Swing compatibility Manager.setHint( Manager.LIGHTWEIGHT_RENDERER, true ); // create a player to play the media specified in the URL Player mediaPlayer = Manager.createRealizedPlayer(ds); // get the components for the video and the playback controls Component video = mediaPlayer.getVisualComponent(); Component controls = mediaPlayer.getControlPanelComponent(); if ( video != null ) add( video, BorderLayout.CENTER ); // add video component if ( controls != null ) add( controls, BorderLayout.SOUTH ); // add controls mediaPlayer.start(); // start playing the media clip }catch(Exception e){} } // end MediaPanel constructor } // end class MediaPanel
Code:
import javax.media.protocol.ContentDescriptor; import javax.media.protocol.PullDataSource; import java.nio.ByteBuffer; import java.io.IOException; import javax.media.MediaLocator; import javax.media.Duration; import javax.media.Time; public class ByteBufferDataSource extends PullDataSource { protected ContentDescriptor contentType; protected SeekableStream[] sources; protected boolean connected; protected ByteBuffer anInput; protected ByteBufferDataSource(){ } /** * Construct a ByteBufferDataSource from a ByteBuffer. * @param source The ByteBuffer that is used to create the * the DataSource. */ public ByteBufferDataSource(ByteBuffer input, String contentType) throws IOException { anInput = input; this.contentType = new ContentDescriptor( ContentDescriptor.mimeTypeToPackageName(contentType)); } /** * Open a connection to the source described by * the ByteBuffer/CODE>. * * * The connect method initiates communication with the source. * * @exception IOException Thrown if there are IO problems * when connect is called. */ public void connect() { sources = new SeekableStream [1]; sources[0] = new SeekableStream(anInput); } /** * Close the connection to the source described by the locator. * * The disconnect method frees resources used to maintain a * connection to the source. * If no resources are in use, disconnect is ignored. * If stop hasn't already been called, * calling disconnect implies a stop. * */ public void disconnect() { } /** * Get a string that describes the content-type of the media * that the source is providing. * * It is an error to call getContentType if the source is * not connected. * * @return The name that describes the media content. */ public String getContentType() { return contentType.getContentType(); } public Object getControl(String str) { return null; } public Object[] getControls() { return new Object[0]; } public javax.media.Time getDuration() { return Duration.DURATION_UNKNOWN; } /** * Get the collection of streams that this source * manages. The collection of streams is entirely * content dependent. The MIME type of this * DataSource provides the only indication of * what streams can be available on this connection. * * @return The collection of streams for this source. */ public javax.media.protocol.PullSourceStream[] getStreams() { return sources; } /** * Initiate data-transfer. The start method must be * called before data is available. *(You must call connect before calling start.) * * @exception IOException Thrown if there are IO problems with the source * when start is called. */ public void start() throws IOException { } /** * Stop the data-transfer. * If the source has not been connected and started, * stop does nothing. */ public void stop() throws IOException { } }
Code:
import java.lang.reflect.Method; import java.lang.reflect.Constructor; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.BufferUnderflowException; import javax.media.protocol.PullSourceStream; import javax.media.protocol.Seekable; import javax.media.protocol.ContentDescriptor; public class SeekableStream implements PullSourceStream, Seekable { protected ByteBuffer inputBuffer; /** * a flag to indicate EOF reached */ /** Creates a new instance of SeekableStream */ public SeekableStream(ByteBuffer byteBuffer) { inputBuffer = byteBuffer; this.seek((long)(0)); // set the ByteBuffer to to beginning } /** * Find out if the end of the stream has been reached. * * @return Returns true if there is no more data. */ public boolean endOfStream() { return (! inputBuffer.hasRemaining()); } /** * Get the current content type for this stream. * * @return The current ContentDescriptor for this stream. */ public ContentDescriptor getContentDescriptor() { return null; } /** * Get the size, in bytes, of the content on this stream. * * @return The content length in bytes. */ public long getContentLength() { return inputBuffer.capacity(); } /** * Obtain the object that implements the specified * Class or Interface * The full class or interface name must be used. * * * The control is not supported. * null is returned. * * @return null. */ public Object getControl(String controlType) { return null; } /** * Obtain the collection of objects that * control the object that implements this interface. * * * No controls are supported. * A zero length array is returned. * * @return A zero length array */ public Object[] getControls() { Object[] objects = new Object[0]; return objects; } /** * Find out if this media object can position anywhere in the * stream. If the stream is not random access, it can only be repositioned * to the beginning. * * @return Returns true if the stream is random access, false if the stream can only * be reset to the beginning. */ public boolean isRandomAccess() { return true; } /** * Block and read data from the stream. * * Reads up to length bytes from the input stream into * an array of bytes. * If the first argument is null, up to * length bytes are read and discarded. * Returns -1 when the end * of the media is reached. * * This method only returns 0 if it was called with * a length of 0. * * @param buffer The buffer to read bytes into. * @param offset The offset into the buffer at which to begin writing data. * @param length The number of bytes to read. * @return The number of bytes read, -1 indicating * the end of stream, or 0 indicating read * was called with length 0. * @throws IOException Thrown if an error occurs while reading. */ public int read(byte[] buffer, int offset, int length) throws IOException { // return n (number of bytes read), -1 (eof), 0 (asked for zero bytes) if ( length == 0 ) return 0; try { inputBuffer.get(buffer,offset,length); return length; } catch ( BufferUnderflowException E ) { return -1; } } public void close() { } /** * Seek to the specified point in the stream. * @param where The position to seek to. * @return The new stream position. */ public long seek(long where) { try { inputBuffer.position((int)(where)); return where; } catch (IllegalArgumentException E) { return this.tell(); // staying at the current position } } /** * Obtain the current point in the stream. */ public long tell() { return inputBuffer.position(); } /** * Find out if data is available now. * Returns true if a call to read would block * for data. * * @return Returns true if read would block; otherwise * returns false. */ public boolean willReadBlock() { return (inputBuffer.remaining() == 0); } }