Play encrypted hls in exoplayer using encrypted keys - android

I am trying to play the encrypted video using .m3u8 file. I stored my video in AWS and created the .ts files and a master playlist. Aws provided me some keys for that encrypted video file. Now I have to use those keys in exoplayer. I have tried to use Aes128DataSource and DrmSessionManager but no luck.
The key types are:
Encryption Key: ####################################################################
Encryption Key MD5: ################
Encryption Initialization Vector : #############
Bellow the code I am using to play the hls video. Its plays the video smoothly without any problem. I just need to know where and how to use the keys to play the encrypted video.
String VIDEO_URL = "https://s3.amazonaws.com/######.###.##/videos/mobiletest/mobilemaster.m3u8";
//Create a default TrackSelector
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
// Create a default LoadControl
LoadControl loadControl = new DefaultLoadControl();
//Bis. Create a RenderFactory
RenderersFactory renderersFactory = new DefaultRenderersFactory(this);
//Create the player
player = ExoPlayerFactory.newSimpleInstance(renderersFactory, trackSelector, loadControl);
simpleExoPlayerView = new SimpleExoPlayerView(this);
simpleExoPlayerView = (SimpleExoPlayerView) findViewById(R.id.player_view);
//Set media controller
simpleExoPlayerView.setUseController(true);
simpleExoPlayerView.requestFocus();
// Bind the player to the view.
simpleExoPlayerView.setPlayer(player);
// Set the media source
Uri mp4VideoUri = Uri.parse(VIDEO_URL);
//Measures bandwidth during playback. Can be null if not required.
DefaultBandwidthMeter bandwidthMeterA = new DefaultBandwidthMeter();
//Produces DataSource instances through which media data is loaded.
DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "PiwikVideoApp"), bandwidthMeterA);
//Produces Extractor instances for parsing the media data.
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
//FOR LIVE STREAM LINK:
MediaSource videoSource = new HlsMediaSource(mp4VideoUri, dataSourceFactory, 1, null, null);
final MediaSource mediaSource = videoSource;
player.prepare(videoSource);
I have encrypted the video using AWS Elastic Transcoder, and using exoplayer version: 2.6.0

I have found a solution. The trick you need to do is to create your own custom data sources. You need to create a class that extends HttpDataSource.BaseFactory and add some code from DefaultHttpDataSourceFactory. I know it sounds crazy, but I have solved it this way. Don't worry, I am pasting here the whole code of that custom class.
import android.support.annotation.Nullable;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource;
import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.upstream.TransferListener;
public class CustomDataSourcesFactory extends HttpDataSource.BaseFactory{
private final String userAgent;
private final #Nullable
TransferListener listener;
private final int connectTimeoutMillis;
private final int readTimeoutMillis;
private final boolean allowCrossProtocolRedirects;
/**
* Constructs a DefaultHttpDataSourceFactory. Sets {#link
* DefaultHttpDataSource#DEFAULT_CONNECT_TIMEOUT_MILLIS} as the connection timeout, {#link
* DefaultHttpDataSource#DEFAULT_READ_TIMEOUT_MILLIS} as the read timeout and disables
* cross-protocol redirects.
*
* #param userAgent The User-Agent string that should be used.
*/
public CustomDataSourcesFactory(String userAgent) {
this(userAgent, null);
}
/**
* Constructs a DefaultHttpDataSourceFactory. Sets {#link
* DefaultHttpDataSource#DEFAULT_CONNECT_TIMEOUT_MILLIS} as the connection timeout, {#link
* DefaultHttpDataSource#DEFAULT_READ_TIMEOUT_MILLIS} as the read timeout and disables
* cross-protocol redirects.
*
* #param userAgent The User-Agent string that should be used.
* #param listener An optional listener.
*/
public CustomDataSourcesFactory(String userAgent, #Nullable TransferListener listener) {
this(userAgent, listener, DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS,
DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS, false);
}
/**
* #param userAgent The User-Agent string that should be used.
* #param connectTimeoutMillis The connection timeout that should be used when requesting remote
* data, in milliseconds. A timeout of zero is interpreted as an infinite timeout.
* #param readTimeoutMillis The read timeout that should be used when requesting remote data, in
* milliseconds. A timeout of zero is interpreted as an infinite timeout.
* #param allowCrossProtocolRedirects Whether cross-protocol redirects (i.e. redirects from HTTP
* to HTTPS and vice versa) are enabled.
*/
public CustomDataSourcesFactory(
String userAgent,
int connectTimeoutMillis,
int readTimeoutMillis,
boolean allowCrossProtocolRedirects) {
this(
userAgent,
/* listener= */ null,
connectTimeoutMillis,
readTimeoutMillis,
allowCrossProtocolRedirects);
}
/**
* #param userAgent The User-Agent string that should be used.
* #param listener An optional listener.
* #param connectTimeoutMillis The connection timeout that should be used when requesting remote
* data, in milliseconds. A timeout of zero is interpreted as an infinite timeout.
* #param readTimeoutMillis The read timeout that should be used when requesting remote data, in
* milliseconds. A timeout of zero is interpreted as an infinite timeout.
* #param allowCrossProtocolRedirects Whether cross-protocol redirects (i.e. redirects from HTTP
* to HTTPS and vice versa) are enabled.
*/
public CustomDataSourcesFactory(
String userAgent,
#Nullable TransferListener listener,
int connectTimeoutMillis,
int readTimeoutMillis,
boolean allowCrossProtocolRedirects) {
this.userAgent = userAgent;
this.listener = listener;
this.connectTimeoutMillis = connectTimeoutMillis;
this.readTimeoutMillis = readTimeoutMillis;
this.allowCrossProtocolRedirects = allowCrossProtocolRedirects;
}
#Override
protected HttpDataSource createDataSourceInternal(
HttpDataSource.RequestProperties defaultRequestProperties) {
DefaultHttpDataSource defaultHttpDataSource = new DefaultHttpDataSource(userAgent, null, listener, connectTimeoutMillis,
readTimeoutMillis, allowCrossProtocolRedirects, defaultRequestProperties);
defaultHttpDataSource.setRequestProperty("your header", "your token");
return defaultHttpDataSource;
}}
Do you see the method createDataSourceInternal? I am returning a DefaultHttpDataSource object initialised with a header key and a token defaultHttpDataSource.setRequestProperty("your header", "your token");. So now your exoplayer will hit the accusation URL with this header key and token value which will be checked by your server side in order to verify the valid request. Your hls playlist(.m3u8) contains the accusation URL. Exoplayer uses this URL automatically. All you need to do is to tell the player to use the validation keys.
So again here is the usage code of Your custom data sources:
//ExoPlayer implementation
//Create a default TrackSelector
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
// Create a default LoadControl
LoadControl loadControl = new DefaultLoadControl();
//Bis. Create a RenderFactory
RenderersFactory renderersFactory = new DefaultRenderersFactory(this);
//Create the player
player = ExoPlayerFactory.newSimpleInstance(renderersFactory, trackSelector, loadControl);
simpleExoPlayerView = new SimpleExoPlayerView(this);
simpleExoPlayerView = (SimpleExoPlayerView) findViewById(R.id.player_view);
//Set media controller
simpleExoPlayerView.setUseController(true);
simpleExoPlayerView.requestFocus();
// Bind the player to the view.
simpleExoPlayerView.setPlayer(player);
// Set the media source
Uri mp4VideoUri = Uri.parse(VIDEO_URL);
//DefaultHttpDataSource source = new DefaultHttpDataSource(Util.getUserAgent(this, "appAgent"), null);
//source.setRequestProperty("header", "user token");
//Measures bandwidth during playback. Can be null if not required.
DefaultBandwidthMeter bandwidthMeterA = new DefaultBandwidthMeter();
//DefaultDataSourceFactory o = new DefaultDataSourceFactory(this, null, new DefaultHttpDataSourceFactory(Util.getUserAgent(this, "appAgent"), bandwidthMeterA));
CustomDataSourcesFactory o = new CustomDataSourcesFactory("Exoplayer");
//Produces DataSource instances through which media data is loaded.
DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "PiwikVideoApp"), bandwidthMeterA);
//Produces Extractor instances for parsing the media data.
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
//FOR LIVE STREAM LINK:
MediaSource videoSource = new HlsMediaSource(mp4VideoUri, o, 1, null, null);
final MediaSource mediaSource = videoSource;
player.prepare(videoSource);
This problem was too much critical for me because I could not found any tutorial, resources or idea to solve this. I am writing this because I don't want other noob people like me to suffer from this.
If you are not clear enough, feel free to ask here. I will assist you further. I have also the server side code in order to generate the decryption key from AWS encrypted key.

Related

Prevent re-buffering on changing max bit rate in ExoPlayer

I am using setMaxBitrate provided by DefaultTrackSelector to set max bit rate when user changes video quality.
val parameters = defaultTrackSelector.buildUponParameters()
.setMaxVideoBitrate(bitrate)
.build()
defaultTrackSelector.parameters = parameters
But as soon as this function is called, the current buffer is discarded & re-buffering is shown right away. Is there any way to keep playing using old buffer & just load the new buffer using the new bitrate settings like YouTube does?
This issue has been discussed here:
https://github.com/google/ExoPlayer/issues/3522
https://github.com/google/ExoPlayer/issues/2250
But there doesn't seem to be any solution yet. Any help regarding this issue would be appreciated. Thanks in advance.
Easily you can do it.You have to use ExoPlayer already and ExoPlayer is provide a seekTo() method.
On this method,You should pass only player current position at which point you stopped before.
Step:-1
You have to change your Quality like 144p to 720p. on this Changing time you have to store your current ExoPlayer current position used this method:-
Private int currentPosition=player.getCurrentPosition();
Step -2
After you have to build your exoplayer media source:-
// Measures bandwidth during playback. Can be null if not required.
DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
// Produces DataSource instances through which media data is loaded.
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, getString(R.string.app_name)), bandwidthMeter);
// This is the MediaSource representing the media to be played.
MediaSource videoSource = new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource("Pass Your Video Url");
// Prepare the player with the source.
player.prepare(videoSource);
Step 3:-
check this condition
if (this.currentPosition > 0) {
player.seekTo(this.currentPosition);
this.currentPosition = 0;
player.setPlayWhenReady(true);
} else {
player.setPlayWhenReady(true);
}
and it's work good you have to watch your video in where are you left.
Step 4:-
If your quality his not good that time used is method.
public int getWifiLevel()
{
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
int linkSpeed = wifiManager.getConnectionInfo().getRssi();
int level = WifiManager.calculateSignalLevel(linkSpeed, 5);
return level;
}
Based on wifi level or link speed you can decide if it has the low connection or high connection internet.

How to toggle closed captions in Leanback ExoPlayer?

I am developing an Android app for TV using the Leanback library. I have an HLS video stream with an srt subtitle from a URI. I am using ExoPlayer version 2.5.4 as used in this example app. I created my MediaSource using:
private MediaSource onCreateMediaSource(Uri uri, Uri subtitleUri) {
String userAgent = Util.getUserAgent(mContext, "ExoPlayerAdapter");
MediaSource videoSource = new HlsMediaSource(uri,
new DefaultDataSourceFactory(mContext, userAgent),
null,
null);
Format subtitleFormat = Format.createTextSampleFormat(
"1", MimeTypes.APPLICATION_SUBRIP, 0, "en");
MediaSource subtitleSource = new SingleSampleMediaSource(
subtitleUri,
new DefaultDataSourceFactory(mContext, userAgent),
subtitleFormat, C.TIME_UNSET);
MergingMediaSource mergedSource =
new MergingMediaSource(videoSource, subtitleSource);
return mergedSource;
}
In my PlaybackTransportControlGlue, I have a PlaybackControlsRow.ClosedCaptioningAction. When this button is clicked, what do I write in the action dispatcher to toggle the closed captions?
I tried this:
#Override
public void onActionClicked(Action action) {
if (action == mClosedCaptioningAction) {
DefaultTrackSelector trackSelector = mAdapter.getTrackSelector();
int rendererIndex = 0;
if (mClosedCaptioningAction.getIndex() == PlaybackControlsRow.ClosedCaptioningAction.INDEX_ON) {
MappingTrackSelector.MappedTrackInfo mappedTrackInfo = trackSelector.getCurrentMappedTrackInfo();
TrackGroupArray textGroups = mappedTrackInfo.getTrackGroups(rendererIndex);
int groupIndex = 0;
trackSelector.setRendererDisabled(rendererIndex, false);
MappingTrackSelector.SelectionOverride override =
new MappingTrackSelector.SelectionOverride(mTrackFactory, groupIndex, 0);
trackSelector.setSelectionOverride(rendererIndex, textGroups, override);
} else {
trackSelector.setRendererDisabled(rendererIndex, true);
trackSelector.clearSelectionOverrides();
}
}
super.onActionClicked(action);
}
I got this error:
E/gralloc: unregister FBM buffer
Okay I just answered a question which got text tracks working in a simple way here. This works for adaptive files (like HLS), but I would have to modify it to get it working with progressive files (like an .mp4 that you've merged with an .srt file).
It's at least a starting point.
I'd like to circle back around and get it fully working for you, but I think it may be a matter of working with the track index and tweaking the override so that it doesn't use the AdaptiveFactory (from the below line).
TrackSelection.Factory factory = tracks.length == 1
? new FixedTrackSelection.Factory()
: new AdaptiveTrackSelection.Factory(BANDWIDTH_METER);
We have it fully working in our code for both HLS and progressive, but our implementation is wrapped in a lot of additional architecture which might make it even harder to understand the core components.

Android Google Exoplayer 2.2 HLS and DASH streaming cache

I'm trying to caching HLS and DASH streaming video,
I have tried many solution but not working with Exoplayer v2.2
many issue redirect to below links but not getting any proper solution.
https://github.com/google/ExoPlayer/issues/420 and Using cache in ExoPlayer.
In the one solution 'ExtractorSampleSource' class is not found in Google Exoplayer 2.2
OkHttpClient okHttpClient = new OkHttpClient.Builder().cache(new okhttp3.Cache(context.getCacheDir(), 1024000)).build();
OkHttpDataSource okHttpDataSource = new OkHttpDataSource(okHttpClient, "android", null);
OkHttpDataSource ok2 = new OkHttpDataSource(okHttpClient, "android", null);
HttpDataSource dataSource = new CacheDataSource(context, okHttpDataSource, ok2);
ExtractorSampleSource sampleSource = new ExtractorSampleSource(
uri,
dataSource,
allocator,
buffer_segment_count * buffer_segment_size,
new Mp4Extractor(), new Mp3Extractor());
In other solution got same error 'DefaultUriDataSource' class not found in v2.2
DataSource dataSource = new DefaultUriDataSource(context, null, new OkHttpDataSource(getClient(context), userAgent, null, null/*, CacheControl.FORCE_CACHE*/));
all the solutions are 1 to 2 year older and it's not supported latest version of Google Exoplayer v2.2.
any one have idea or any sample or any solution to do caching with HLS and DASH stream?
Used below buildDataSourceFactory and its storing the cache
DataSource.Factory buildDataSourceFactory(boolean cache) {
if (!cache) {
return new DefaultDataSourceFactory(context, BANDWIDTH_METER,
buildHttpDataSourceFactory(BANDWIDTH_METER));
}else{
return new DataSource.Factory() {
#Override
public DataSource createDataSource() {
LeastRecentlyUsedCacheEvictor evictor = new LeastRecentlyUsedCacheEvictor(100 * 1024 * 1024);
SimpleCache simpleCache = new SimpleCache(new File(context.getCacheDir(), "media_cache"), evictor);
return new CacheDataSource(simpleCache, buildCachedHttpDataSourceFactory(BANDWIDTH_METER).createDataSource(),
new FileDataSource(), new CacheDataSink(simpleCache, 10 * 1024 * 1024),
CacheDataSource.FLAG_BLOCK_ON_CACHE | CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR, null);
}
};
}
}
private DefaultDataSource.Factory buildCachedHttpDataSourceFactory(DefaultBandwidthMeter bandwidthMeter) {
return new DefaultDataSourceFactory(context, bandwidthMeter, buildHttpDataSourceFactory(bandwidthMeter));
}

ExoPlayer2 - How can I make a HTTP 301 redirect work?

I started using ExoPlayer to stream some audio. All was well until I came across an URL that has a "301 Moved Permanently" redirect. ExoPlayer2 does not handle that by default.
I've already seen this thread: https://github.com/google/ExoPlayer/issues/423
There they say to add the new "allowCrossDomainRedirects" flag to either a HttpDataSource or UriDataSource. The problem is that I don't use either of those classes:
//I am NOT using SimpleExoPlayer because I need a different renderer.
exoPlayer = ExoPlayerFactory.newInstance(renderers, trackSelector, loadControl);
final DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(
context,
Util.getUserAgent(context, applicationInfo.getAppName())
);
// Produces Extractor instances for parsing the media data.
final ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
// This is the MediaSource representing the media to be played.
MediaSource mediaSource = new ExtractorMediaSource(
Uri.parse(media.getUriString()) /* uri */,
dataSourceFactory,
extractorsFactory,
10,
null /* eventHandler */,
null /* eventListener */);
exoPlayer.prepare(mediaSource);
See how the ExtractorMediaSource requires a dataSourceFactory instead of a DataSource. In fact I can't even find the classes HttpDataSource and UriDataSource on ExoPlayer2. Looks like they have been removed.
Therefore I can't find a way to add the flag mentioned on the post. Can somebody help me?
The problem described in the issue is about cross-protocol redirects (from http to https or vice versa). Exoplayer supports this, but you have to set allowCrossProtocolRedirects to true. Regular redirects (including 301 redirects) are supported by default. The redirect you're receiving is most likely a cross-protocol redirect.
To create the data source you're calling:
DefaultDataSourceFactory(Context context, String userAgent)
This constructor creates a DefaultHttpDataSourceFactory which has allowCrossProtocolRedirects set to false.
To change this, you need to call:
DefaultDataSourceFactory(Context context, TransferListener<? super DataSource> listener,
DataSource.Factory baseDataSourceFactory)
And use your own DefaultHttpDataSourceFactory with allowCrossProtocolRedirects set to true as the baseDataSourceFactory.
For example:
String userAgent = Util.getUserAgent(context, applicationInfo.getAppName());
// Default parameters, except allowCrossProtocolRedirects is true
DefaultHttpDataSourceFactory httpDataSourceFactory = new DefaultHttpDataSourceFactory(
userAgent,
null /* listener */,
DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS,
DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS,
true /* allowCrossProtocolRedirects */
);
DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(
context,
null /* listener */,
httpDataSourceFactory
);
If you need to do this more often you can also create a helper method:
public static DefaultDataSourceFactory createDataSourceFactory(Context context,
String userAgent, TransferListener<? super DataSource> listener) {
// Default parameters, except allowCrossProtocolRedirects is true
DefaultHttpDataSourceFactory httpDataSourceFactory = new DefaultHttpDataSourceFactory(
userAgent,
listener,
DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS,
DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS,
true /* allowCrossProtocolRedirects */
);
DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(
context,
listener,
httpDataSourceFactory
);
return dataSourceFactory;
}
This will allow cross-protocol redirects.
Sidenote: "301 Moved Permanently" means clients need to update their URL to the new one. "302 Found" is used for regular redirects. If possible, update the URLs that return "301 Moved Permanently".
it works
val httpDataSourceFactory = DefaultHttpDataSourceFactory(Util.getUserAgent(context, "Player"),null,DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS,
DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS,
true)
val dataSourceFactory: DataSource.Factory = DefaultDataSourceFactory(context, null, httpDataSourceFactory)
try this:
// Build a HttpDataSource.Factory with cross-protocol redirects enabled.
HttpDataSource.Factory httpDataSourceFactory =
new DefaultHttpDataSource.Factory().setAllowCrossProtocolRedirects(true);
// Wrap the HttpDataSource.Factory in a DefaultDataSource.Factory, which adds in
// support for requesting data from other sources (e.g., files, resources, etc).
DefaultDataSource.Factory dataSourceFactory =
new DefaultDataSource.Factory(context, httpDataSourceFactory);
// Inject the DefaultDataSourceFactory when creating the player.
ExoPlayer player =
new ExoPlayer.Builder(context)
.setMediaSourceFactory(new DefaultMediaSourceFactory(dataSourceFactory))
.build();
It works for me.
The accepted answer looks a little bit outdated , because DefaultHttpDataSource class is deprecated and we suppose to replace it with DefaultHttpDataSource.Factory , see the official documentation.
So instead of
DefaultHttpDataSourceFactory httpDataSourceFactory = new DefaultHttpDataSourceFactory(
userAgent,
null /* listener */,
DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS,
DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS,
true /* allowCrossProtocolRedirects */
);
we could have
final DefaultHttpDataSource.Factory defaultDataSourceFactory = new DefaultHttpDataSource
.Factory()
.setUserAgent(userAgent)
.setTransferListener(listener)
.setConnectTimeoutMs(DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS)
.setReadTimeoutMs(DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS)
.setAllowCrossProtocolRedirects(true);
Also don't forget to use if you have to
final DefaultHttpDataSource defaultDataSource = defaultDataSourceFactory.createDataSource();
And finally guess what : DefaultDataSourceFactory is also deprecated and we should use DefaultDataSource.Factory instead.

cache played data on exoplayer

I write an android application for streaming video in MPEG-DASH protocol..
I'm using Exoplayer and for now I test on the demo
I read some questions on stackoverflow and issues on exoplayer and write this code for cache a video
in DashRendererBuilder(in demo):
Cache cache = new SimpleCache(context.getCacheDir(), new LeastRecentlyUsedCacheEvictor(1024 * 1024 * 10));
// Build the video renderer.
DataSource videoDataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent);
CacheDataSource videoCacheDataSource= new CacheDataSource(cache, videoDataSource, false, false);
ChunkSource videoChunkSource= new DashChunkSource(manifestFetcher,
DefaultDashTrackSelector.newVideoInstance(context, true, filterHdContent),
videoCacheDataSource, new AdaptiveEvaluator(bandwidthMeter), LIVE_EDGE_LATENCY_MS,
elapsedRealtimeOffset, mainHandler, player);//*/
ChunkSampleSource videoSampleSource = new ChunkSampleSource(videoChunkSource, loadControl,
VIDEO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, mainHandler, player,
DemoPlayer.TYPE_VIDEO);
TrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(context, videoSampleSource,
MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, drmSessionManager, true,
mainHandler, player, 50);
//cache audio
Cache cache2 = new SimpleCache(context.getCacheDir(), new LeastRecentlyUsedCacheEvictor(1024 * 1024 * 4));
// Build the audio renderer.
DataSource audioDataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent);
CacheDataSource audioCacheDataSource= new CacheDataSource(cache2, audioDataSource, false, false);
ChunkSource audioChunkSource = new DashChunkSource(manifestFetcher,
DefaultDashTrackSelector.newAudioInstance(), audioCacheDataSource, null, LIVE_EDGE_LATENCY_MS,
elapsedRealtimeOffset, mainHandler, player);
ChunkSampleSource audioSampleSource = new ChunkSampleSource(audioChunkSource, loadControl,
AUDIO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, mainHandler, player,
DemoPlayer.TYPE_AUDIO);
TrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(audioSampleSource,
drmSessionManager, true, mainHandler, player, AudioCapabilities.getCapabilities(context));
the problem is when I seek forward on the cached data it works well. but seems when I seek backward on the played data, data is lose and download vide again.
how I can fix this? for example I want to cache the last two minute or cache all the played data same as how youtube works when it uses html5.

Categories

Resources