Thursday, 1 September 2016

create a datasource from a stream using JMF ~ gniithelp

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 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