Two things you need before you can do this. First, you need to take the stream and convert it to a byte buffer (easy enough). Secondly, you need to know the content type of the stream
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;
/**
*
* @author Chad McMillan
*/
public class ByteBufferDataSource extends PullDataSource {
protected ContentDescriptor contentType;
protected SeekableStream[] sources;
protected boolean connected;
protected ByteBuffer anInput;
protected ByteBufferDataSource(){
}
/**
* Construct a
* @param source The
* the
*/
public ByteBufferDataSource(ByteBuffer input, String contentType) throws IOException {
anInput = input;
this.contentType = new ContentDescriptor(contentType);
connected = false;
}
/**
* Open a connection to the source described by
* the
*
* The
*
* @exception IOException Thrown if there are IO problems
* when
*/
public void connect() throws java.io.IOException {
connected = true;
sources = new SeekableStream [1];
sources[0] = new SeekableStream(anInput);
}
/**
* Close the connection to the source described by the locator.
*
* The
* connection to the source.
* If no resources are in use,
* If
* calling
*
*/
public void disconnect() {
if(connected) {
sources[0].close();
connected = false;
}
}
/**
* Get a string that describes the content-type of the media
* that the source is providing.
*
* It is an error to call
* not connected.
*
* @return The name that describes the media content.
*/
public String getContentType() {
if( !connected) {
throw new java.lang.Error("Source is unconnected.");
}
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
*
* what streams can be available on this connection.
*
* @return The collection of streams for this source.
*/
public javax.media.protocol.PullSourceStream[] getStreams() {
if( !connected) {
throw new java.lang.Error("Source is unconnected.");
}
return sources;
}
/**
* Initiate data-transfer. The
* called before data is available.
*(You must call
*
* @exception IOException Thrown if there are IO problems with the source
* when
*/
public void start() throws IOException {
}
/**
* Stop the data-transfer.
* If the source has not been connected and started,
*
*/
public void stop() throws IOException {
}
}
(and for your stream)
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;
/**
*
* @author Chad McMillan
*/
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
*/
public boolean endOfStream() {
return (! inputBuffer.hasRemaining());
}
/**
* Get the current content type for this stream.
*
* @return The current
*/
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
*
* The full class or interface name must be used.
*
*
* The control is not supported.
*
*
* @return
*/
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
* be reset to the beginning.
*/
public boolean isRandomAccess() {
return true;
}
/**
* Block and read data from the stream.
*
* Reads up to
* an array of bytes.
* If the first argument is
*
* Returns -1 when the end
* of the media is reached.
*
* This method only returns 0 if it was called with
* a
*
* @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
* was called with
* @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
* for data.
*
* @return Returns
* returns
*/
public boolean willReadBlock() {
return (inputBuffer.remaining() == 0);
}
}
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;
/**
*
* @author Chad McMillan
*/
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(contentType);
connected = false;
}
/**
* 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() throws java.io.IOException {
connected = true;
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() {
if(connected) {
sources[0].close();
connected = false;
}
}
/**
* 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() {
if( !connected) {
throw new java.lang.Error("Source is unconnected.");
}
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() {
if( !connected) {
throw new java.lang.Error("Source is unconnected.");
}
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 {
}
}
(and for your stream)
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;
/**
*
* @author Chad McMillan
*/
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);
}
}
No comments:
Post a Comment