|
Triton Mobile SDK for Android 3.5.1
This is a custom android player made by Triton Digital
|
Classes | |
| enum | State |
| interface | StateChangedListener |
| Interface to be implemented in order to be notified about the important changes of state of the server. More... | |
Public Member Functions | |
| void | setClient (Client client) |
| Client | getClient () |
| Gets the client to be used to connect to the stream. | |
| void | setServer (Server server) |
| void | setStreamContainerDecoder (StreamContainerDecoder streamContainerDecoder) |
| Sets the instance that decodes the data received by the client and links it to the client. | |
| StreamContainerDecoder | getStreamContainerDecoder () |
| Gets the instance that decodes the data received by the client. | |
| void | setDataProvider (DataProvider dataProvider) |
| Gets the instance that provides data to the server (after re-encoding it if needed) and links it to the server. | |
| URI | start (URI uri) |
| Starts proxying the stream at the given uri. | |
| String | start (String uriStr) |
| Starts proxying the stream at the given uri. | |
| URI | startAsync (URI uri) |
| Starts proxying the stream asynchronously at the given uri. | |
| String | startAsync (String uriStr) |
| Starts proxying the stream asynchronously at the given uri. | |
| void | stop () |
| Stops proxying the stream at the given uri. | |
| void | audioPlaybackDidStart () |
| Called by the media player class, which typically also starts the proxy, when the playback starts. | |
Public Attributes | |
| final String | TAG = "Proxy" |
This class allows connecting to a server to receive a stream, extract the Meta Data (if any), the Audio Data, repacketize it in a different streaming protocol and open a local server to be used instead of the original one. The proxy is transparent to the application client. It is started with the original URI that the application wishes to connect to, then it returns a different URL that the application client should use instead.
If the local server type is not a Raw Data type or has a different transport than the original stream, a repacking will occur to transform the original data into something appropriate for the server. For example, there is no repacking if the client is Flv (which uses Http) and the local server is Http Raw Data (the data is simply passed through). On the other side, an Flv client with an RTSP server automatically implies repacking, because the protocol changes.
The purpose of this is to support additional stream transport protocols than the platform originally supports. A good example is Android, which does not allow, as of this writing, streaming from an FLV source. However, it supports streaming from RTSP sources. This proxy can then be used to connect to the FLV server, convert all the data at runtime and produce a RTSP server for the Android media server to connect to. The advantage of using the proxy as a repacking tool is that it may allow supporting more formats, because some formats (like AAC on Android) are only supported over some protocols. The disadvantage of using it to convert is that it may decrease performances, especially due to the intermediate bytes array that may need to be created and garbage-collected. Great efforts have been made to reduce those creation to a minimum by reusing buffers, but there may still be cases where new bytes array are created and copied, which may impact the performance. Always benchmark before using the repacking.
It can be also be used without any repacking, just to extract MetaData from the streaming source, which is something that is not supported for all platforms. Again, as of this writing, Android supports stream raw MP3, but not streaming FLV. In order have CuePoint, this proxy could be used to connect to the FLV source, extract the MetaData to notify a listener, extract the MP3 data and pass it as-is to the media player. The advantage is that it reduces the overhead since there is no repackaging of the packets. This feature is currently not available out of the box, it requires writing an extension to the Server class which would simply take all data decoded and sent it to the client as is.
The Metadata is sent to the listener when the associated timestamp is reached. When receiving the Metadata from the original stream, its timestamp may refer to a date in the future. This is especially true if the stream is sent by burst instead of in real time. There is also a delay caused by the Android MediaPlayer implementation of RTSP which requires a very large buffering to occur before the playback actually starts. To compensate for all this, when the proxy receives a Metadata, it computes the time at which this metadata should be treated, based on the the metadata timestamp sent by the server and the reference timestamp at which the playback actually started. It then waits for the good delay and only notify the listener when the metadata should be treated. For this to work, the proxy needs to be notified when the playback starts. This is done by calling audioPlaybackDidStart on the Proxy instance.
In total, the Proxy can use up to 6 threads. It uses one thread for the Client, two for the Decoder and two or three for the server. See each component's documentation for details. When stopping, either because the media player closed the connection, because of an error an because of a manual stop, all those threads are stopped gracefully.
The simplest way to create a Proxy is by using the ProxyFactory, which takes care of the creation of all the layers needed by a proxy (Client, Stream Container Decoder, packetizer that provides data to the local server, local server). However, for more grained control or to add additional protocols for the client or the local server, it is possible to create all instances manually.
The proxy is implemented as a small state machine. See the documentation of Proxy.State for details.
Usage example for manual creation of a Proxy:
public void startPlayback()
{
Proxy proxy = new Proxy();
proxy.setClient(new HttpClient());
proxy.setStreamContainerDecoder(new FlvDecoder());
proxy.setDataProvider(new RtpPacketProviderMp4Latm());
proxy.setServer(new RtspServer());
// Connect metadata listener
proxy.getStreamContainerDecoder().setMetaDataDecodedListener(metadataDecodedListener);
// Start using the proxy and playing (mMediaPlayer could be, for example, an allocated instance of the Android MediaPlayer class)
mMediaPlayer.start(proxy.startAsync("http://myFlvUrl"));
// Optionally, but strongly recommended, make sure that the MediaPlayer.OnPreparedListener calls proxy.audioPlaybackDidStart() in
// its 'onPrepared' implementation.
}
| void com.tritondigital.net.streaming.proxy.Proxy.audioPlaybackDidStart | ( | ) |
Called by the media player class, which typically also starts the proxy, when the playback starts.
This is used to reset internal counters and timers which ensure that the data is treated at the right time. More specifically, it makes sure that the Metadata is sent to the listeners at the right time, based on the timestamp associated with it.
| void com.tritondigital.net.streaming.proxy.Proxy.setClient | ( | Client | client | ) |
Sets the client to be used to connect to the stream. This client should be preconfigured (or at least configured before start is called).
Note that the proxy automatically registers to be the listener of the client, replacing the previous listener. There is no need to keep a listener on the client directly as the proxy already forwards all the important messages in its own listener implementation. When it comes to messages and listeners, the proxy should be seen as a whole, not as an individual client and server.
| client | The client that will be used to connect to the remote server, which will do the job of pulling the data from the external server. Should be configured with its Listener, that will decode, extract data (Meta and Audio) and repack for the local server before start is called. |
| void com.tritondigital.net.streaming.proxy.Proxy.setServer | ( | Server | server | ) |
Sets the server to be used locally to send the stream to the Media Player (or the actual client that the application wishes to use). This server should be preconfigured (or at least configured before start is called).
Note that the proxy automatically registers to be the listener of the server, replacing the previous listener. There is no need to keep a listener on the server directly as the proxy already forwards all the important messages in its own listener implementation. When it comes to messages and listeners, the proxy should be seen as a whole, not as an individual client and server.
| server | The server that will be used to listen locally, to which the Media Player should connect. Should be configured with its Data Provider before start is called. |
| String com.tritondigital.net.streaming.proxy.Proxy.start | ( | String | uriStr | ) |
Starts proxying the stream at the given uri.
Convenience method to work with uri as Strings.
| uriStr | The uri (as a String) of the external server that will send the stream. |
| URI com.tritondigital.net.streaming.proxy.Proxy.start | ( | URI | uri | ) |
Starts proxying the stream at the given uri.
This method blocks until the server has started (which may need to wait for some data from the server at the given uri), then returns the URI that should be used instead of the original one.
| uri | The URI of the external server that will send the stream. |
| String com.tritondigital.net.streaming.proxy.Proxy.startAsync | ( | String | uriStr | ) |
Starts proxying the stream asynchronously at the given uri.
Convenience method to work asynchronously with uri as Strings.
| uriStr | The uri (as a String) of the external server that will send the stream. |
| URI com.tritondigital.net.streaming.proxy.Proxy.startAsync | ( | URI | uri | ) |
Starts proxying the stream asynchronously at the given uri.
Unlike start(URI), this method does not block until the server has started but returns immediately with the Uri that should be used as a replacement for the original one. However, before using this Uri, the caller could wait for the onProxyServerReady notification (this listener should be added before the call to connectAsync to avoid missing the notification). If the caller does not wait for the ready notification, then the server might block when responding to an RTSP request, until the available data is ready. A sensitive client might consider this as a timeout.
| uri | The URI of the external server that will send the stream. |
| void com.tritondigital.net.streaming.proxy.Proxy.stop | ( | ) |
Stops proxying the stream at the given uri.
Cuts the connection to the remote server, flushes any data accumulated internally and disconnect the local server.