📄 jmfapp-demux.html
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta name="GENERATOR" content="Quadralay WebWorks Publisher 5.0.2">
<meta name="TEMPLATEBASE" content="Portable HTML">
<meta name="LASTUPDATED" content="11/23/99 11:48:14">
<title>Demultiplexer Plug-In </title>
</head>
<body link="#3366CC" vlink="#9999CC" text="#000000" alink="#0000CC" bgcolor="#FFFFFF"
background="images/backgrnd.gif">
<table width="100%" border="0" align="left" cellpadding="0" cellspacing="0">
<tr>
<td><a href="JMFTOC.html">CONTENTS</a> |
<a href="JMFApp-StateHelper.html">PREV </a> |
<a href="JMFApp-DataSource.html">NEXT</a> |
<a href="JMFIX.html">INDEX</a></td>
<td align="right"><em>JMF 2.0 API Guide</em>
</tr>
</table>
<p><br clear="all">
</p>
<hr align="left">
<blockquote>
<div align="right">
<a name="46909"> </a><font size="3" face="Palatino, Times New Roman, Times, serif">C <br></font>
</div>
<div align="right">
<h2>
<a name="87606"> </a><font color="#003366" face="Palatino, Times New Roman, Times, serif">Demultiplexer Plug-In</font>
</h2>
</div>
<p>
<a name="81450"> </a><font face="Palatino, Times New Roman, Times, serif">This sample demonstrates how to implement a <code>Demultiplexer</code> plug-in to extract individual tracks from a media file. This example processes GSM files.</font>
</p>
<a name="89685"> </a><font size="1" face="Palatino, Times New Roman, Times, serif">
<table border="1" bordercolorlight="#FFFFFF" bordercolordark="#000000"
cellpadding="5" cellspacing="0">
<caption><b><i><font face="Palatino, Times New Roman, Times, serif"><a name="89691"> </a>Example C-1: GSM Demultiplexer plug-in. (1 of 13)</font></i></b></caption>
<tr>
<td><font face="Palatino, Times New Roman, Times, serif"><pre>
<a name="89718"> </a><code>import java.io.IOException;
</code><a name="89719"> </a><code>import javax.media.*;
</code><a name="89720"> </a><code>import javax.media.protocol.*;
</code><a name="89721"> </a><code>import javax.media.format.Format;
</code><a name="89722"> </a><code>import javax.media.format.audio.AudioFormat;
</code><a name="89723"> </a><code>
</code><a name="89724"> </a><code>/**
</code><a name="89725"> </a><code> * Demultiplexer for GSM file format
</code><a name="89726"> </a><code> */
</code><a name="89727"> </a><code>
</code><a name="89728"> </a><code>/**
</code><a name="89729"> </a><code> * GSM
</code><a name="89730"> </a><code> * 8000 samples per sec.
</code><a name="89731"> </a><code> * 160 samples represent 20 milliseconds and GSM represents them
</code><a name="89732"> </a><code> * in 33 bytes. So frameSize is 33 bytes and there are 50 frames
</code><a name="89733"> </a><code> * in one second. One second is 1650 bytes.
</code><a name="89734"> </a><code> */
</code><a name="89750"> </a><code>
</code><a name="89751"> </a><code>public class SampleDeMux implements Demultiplexer {
</code><a name="89752"> </a><code> private Time duration = Duration.DURATION_UNKNOWN;
</code><a name="89753"> </a><code> private Format format = null;
</code><a name="89754"> </a><code> private Track[] tracks = new Track[1]; // Only 1 track is there for Gsm
</code><a name="89755"> </a><code> private int numBuffers = 4;
</code><a name="89756"> </a><code> private int bufferSize;
</code><a name="89757"> </a><code> private int dataSize;
</code><a name="89758"> </a><code> private int encoding;
</code><a name="89759"> </a><code> private String encodingString;
</code><a name="89760"> </a><code> private int sampleRate;
</code><a name="89761"> </a><code> private int samplesPerBlock;
</code><a name="89789"> </a><code> private int bytesPerSecond = 1650; // 33 * 50
</code><a name="89790"> </a><code> private int blockSize = 33;
</code></pre>
</font></td>
</tr>
<tr>
<td><font face="Palatino, Times New Roman, Times, serif"><pre>
<a name="89802"> </a><code> private int maxFrame = Integer.MAX_VALUE;
</code><a name="89780"> </a><code> private long minLocation;
</code><a name="89781"> </a><code> private long maxLocation;
</code><a name="89782"> </a><code> private PullSourceStream stream = null;
</code><a name="89783"> </a><code> private long currentLocation = 0;
</code><a name="89808"> </a><code>
</code><a name="89809"> </a><code> protected DataSource source;
</code><a name="89810"> </a><code> protected SourceStream[] streams;
</code><a name="89811"> </a><code> protected boolean seekable = false;
</code><a name="89812"> </a><code> protected boolean positionable = false;
</code><a name="89813"> </a><code> private Object sync = new Object(); // synchronizing variable
</code><a name="89814"> </a><code>
</code><a name="89815"> </a><code> private static ContentDescriptor[] supportedFormat =
</code><a name="89816"> </a><code> new ContentDescriptor[] {new ContentDescriptor("audio.x_gsm")};
</code><a name="89817"> </a><code>
</code><a name="89818"> </a><code> public ContentDescriptor [] getSupportedInputContentDescriptors() {
</code><a name="89819"> </a><code> return supportedFormat;
</code><a name="89820"> </a><code> }
</code><a name="89821"> </a><code>
</code><a name="89822"> </a><code> public void setSource(DataSource source)
</code><a name="89823"> </a><code> throws IOException, IncompatibleSourceException {
</code><a name="89824"> </a><code>
</code><a name="89825"> </a><code> if (!(source instanceof PullDataSource)) {
</code><a name="89826"> </a><code> throw new IncompatibleSourceException("DataSource
not supported: " + source);
</code><a name="89827"> </a><code> } else {
</code><a name="89828"> </a><code> streams = ((PullDataSource) source).getStreams();
</code><a name="89829"> </a><code> }
</code><a name="89830"> </a><code>
</code><a name="89831"> </a><code> if ( streams == null) {
</code><a name="89832"> </a><code> throw new IOException("Got a null stream from the DataSource");
</code><a name="89833"> </a><code> }
</code><a name="89834"> </a><code>
</code><a name="89835"> </a><code> if (streams.length == 0) {
</code><a name="89836"> </a><code> throw new IOException("Got a empty stream array
from the DataSource");
</code><a name="89837"> </a><code> }
</code><a name="89843"> </a><code> this.source = source;
</code><a name="89844"> </a><code> this.streams = streams;
</code><a name="89845"> </a><code>
</code><a name="89846"> </a><code> positionable = (streams[0] instanceof Seekable);
</code><a name="89852"> </a><code> seekable = positionable && ((Seekable)
streams[0]).isRandomAccess();
</code><a name="89853"> </a><code>
</code><a name="89854"> </a><code> if (!supports(streams))
</code><a name="89855"> </a><code> throw new IncompatibleSourceException("DataSource not
supported: " + source);
</code><a name="89856"> </a><code> }
</code><a name="89862"> </a><code>
</code><a name="89863"> </a><code> /**
</code><a name="89864"> </a><code> * A Demultiplexer may support pull only or push only or both
</code><a name="89865"> </a><code> * pull and push streams.</code>
</pre>
</font></td>
</tr>
<tr>
<td><font face="Palatino, Times New Roman, Times, serif"><pre>
<a name="89873"> </a><code> * Some Demultiplexer may have other requirements.
</code><a name="89874"> </a><code> * For e.g a quicktime Demultiplexer imposes an additional
</code><a name="89875"> </a><code> * requirement that
</code><a name="89876"> </a><code> * isSeekable() and isRandomAccess() be true
</code><a name="89877"> </a><code> */
</code><a name="89878"> </a><code> protected boolean supports(SourceStream[] streams) {
</code><a name="89879"> </a><code> return ( (streams[0] != null) &&
</code><a name="89880"> </a><code> (streams[0] instanceof PullSourceStream) );
</code><a name="89881"> </a><code> }
</code><a name="89882"> </a><code>
</code><a name="89883"> </a><code> public boolean isPositionable() {
</code><a name="89884"> </a><code> return positionable;
</code><a name="89885"> </a><code> }
</code><a name="89886"> </a><code>
</code><a name="89887"> </a><code> public boolean isRandomAccess() {
</code><a name="89888"> </a><code> return seekable;
</code><a name="89889"> </a><code> }
</code><a name="89890"> </a><code>
</code><a name="89891"> </a><code> /**
</code><a name="89892"> </a><code> * Opens the plug-in software or hardware component and acquires
</code><a name="89893"> </a><code> * necessary resources. If all the needed resources could not be
</code><a name="89894"> </a><code> * acquired, it throws a ResourceUnavailableException. Data should not
</code><a name="89895"> </a><code> * be passed into the plug-in without first calling this method.
</code><a name="89896"> </a><code> */
</code><a name="89897"> </a><code> public void open() {
</code><a name="89898"> </a><code> // throws ResourceUnavailableException;
</code><a name="89899"> </a><code> }
</code><a name="89900"> </a><code>
</code><a name="89901"> </a><code> /**
</code><a name="89902"> </a><code> * Closes the plug-in component and releases resources. No more data
</code><a name="89903"> </a><code> * will be accepted by the plug-in after a call to this method. The
</code><a name="89904"> </a><code> * plug-in can be reinstated after being closed by calling
</code><a name="89905"> </a><code> * <code>open</code>.
</code><a name="89906"> </a><code> */
</code><a name="89907"> </a><code> public void close() {
</code><a name="89908"> </a><code> if (source != null) {
</code><a name="89909"> </a><code> try {
</code><a name="89910"> </a><code> source.stop();
</code><a name="89911"> </a><code> source.disconnect();
</code><a name="89912"> </a><code> } catch (IOException e) {
</code><a name="89913"> </a><code> // Internal error?
</code><a name="89914"> </a><code> }
</code><a name="89915"> </a><code> source = null;
</code><a name="89916"> </a><code> }
</code><a name="89922"> </a><code> }
</code><a name="89923"> </a><code>
</code><a name="89924"> </a><code> /**
</code><a name="89925"> </a><code> * This get called when the player/processor is started.
</code><a name="89926"> </a><code> */
</code><a name="89927"> </a><code> public void start() throws IOException {
</code><a name="89928"> </a><code> if (source != null)
</code><a name="89929"> </a><code> source.start();
</code><a name="89930"> </a><code> }</code>
</pre>
</font></td>
</tr>
<tr>
<td><font face="Palatino, Times New Roman, Times, serif"><pre>
<a name="89938"> </a><code> /**
</code><a name="89939"> </a><code> * This get called when the player/processor is stopped.
</code><a name="89940"> </a><code> */
</code><a name="89941"> </a><code> public void stop() {
</code><a name="89942"> </a><code> if (source != null) {
</code><a name="89943"> </a><code> try {
</code><a name="89944"> </a><code> source.stop();
</code><a name="89945"> </a><code> } catch (IOException e) {
</code><a name="89946"> </a><code> // Internal errors?
</code><a name="89947"> </a><code> }
</code><a name="89948"> </a><code> }
</code><a name="89949"> </a><code> }
</code><a name="89950"> </a><code>
</code><a name="89951"> </a><code> /**
</code><a name="89952"> </a><code> * Resets the state of the plug-in. Typically at end of media
</code><a name="89953"> </a><code> * or when media is repositioned.
</code><a name="89954"> </a><code> */
</code><a name="89955"> </a><code> public void reset() {
</code><a name="89956"> </a><code> }
</code><a name="89957"> </a><code>
</code><a name="89958"> </a><code> public Track[] getTracks() throws IOException, BadHeaderException {
</code><a name="89959"> </a><code>
</code><a name="89960"> </a><code> if (tracks[0] != null)
</code><a name="89961"> </a><code> return tracks;
</code><a name="89962"> </a><code> stream = (PullSourceStream) streams[0];
</code><a name="89963"> </a><code> readHeader();
</code><a name="89964"> </a><code> bufferSize = bytesPerSecond;
</code><a name="89965"> </a><code> tracks[0] = new GsmTrack((AudioFormat) format,
</code><a name="89966"> </a><code> /*enabled=*/ true,
</code><a name="89967"> </a><code> new Time(0),
</code><a name="89968"> </a><code> numBuffers,
</code><a name="89969"> </a><code> bufferSize,
</code><a name="89970"> </a><code> minLocation,
</code><a name="89971"> </a><code> maxLocation
</code><a name="89972"> </a><code> );
</code><a name="89973"> </a><code> return tracks;
</code><a name="89974"> </a><code> }
</code><a name="89975"> </a><code>
</code><a name="89976"> </a><code> public Object[] getControls() {
</code><a name="89977"> </a><code> return new Object[0];
</code><a name="89978"> </a><code> }
</code><a name="89979"> </a><code>
</code><a name="89980"> </a><code> public Object getControl(String controlType) {
</code><a name="89981"> </a><code> return null;
</code><a name="89982"> </a><code> }
</code><a name="89988"> </a><code> private void /* for now void */ readHeader()
</code><a name="89989"> </a><code> throws IOException, BadHeaderException {
</code><a name="89990"> </a><code>
</code><a name="89991"> </a><code> minLocation = getLocation(stream); // Should be zero
</code><a name="89992"> </a><code>
</code><a name="89993"> </a><code> long contentLength = stream.getContentLength();
</code><a name="89994"> </a><code> if ( contentLength != SourceStream.LENGTH_UNKNOWN ) {
</code><a name="89995"> </a><code> double durationSeconds = contentLength / bytesPerSecond;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -