Trying to work with ExoPlayer - lots of unknowns - android

There is no mention on the internet what on earth is a userAgent, what do I pass as its value and what is it used for. No documentation, nothing.
Also, how do I obtain "videoRepresentations" and what is it?
// Build the video renderer.
DataSource videoDataSource = new HttpDataSource(userAgent, HttpDataSource.REJECT_PAYWALL_TYPES, bandwidthMeter);
ChunkSource videoChunkSource = new DashChunkSource(videoDataSource, new AdaptiveEvaluator(bandwidthMeter), videoRepresentations);
ChunkSampleSource videoSampleSource = new ChunkSampleSource(videoChunkSource, loadControl, VIDEO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true);
MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(videoSampleSource, null, true, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 0, mainHandler, playerActivity, 50);
// Build the audio renderer.
DataSource audioDataSource = new HttpDataSource(userAgent, HttpDataSource.REJECT_PAYWALL_TYPES, bandwidthMeter);
ChunkSource audioChunkSource = new DashChunkSource(audioDataSource, new FormatEvaluator.FixedEvaluator(), audioRepresentation);
SampleSource audioSampleSource = new ChunkSampleSource(audioChunkSource, loadControl, AUDIO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true);
MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(audioSampleSource, null, true);
Documentation is extremely insufficient
http://developer.android.com/guide/topics/media/exoplayer.html

userAgent
private RendererBuilder getRendererBuilder() {
String userAgent = DemoUtil.getUserAgent(this);
switch (contentType) {
case DemoUtil.TYPE_SS:
return new SmoothStreamingRendererBuilder(userAgent, contentUri.toString(), contentId,
new SmoothStreamingTestMediaDrmCallback(), debugTextView);
case DemoUtil.TYPE_DASH:
return new DashRendererBuilder(userAgent, contentUri.toString(), contentId,
new WidevineTestMediaDrmCallback(contentId), debugTextView);
default:
return new DefaultRendererBuilder(this, contentUri, debugTextView);
}
}
Above code from below link where whole code available with project you just download and use it.
https://raw.githubusercontent.com/google/ExoPlayer/master/demo/src/main/java/com/google/android/exoplayer/demo/full/FullPlayerActivity.java
https://raw.githubusercontent.com/google/ExoPlayer/master/demo/src/main/java/com/google/android/exoplayer/demo/simple/SimplePlayerActivity.java

Related

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));
}

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.

android exoplayer custom datasource

I am developing a custom DataSource object to use in ExoPlayer.
I am having problems understanding how to connect it to Samplesource objects so that data requests from underlying Exoplayer components happen via my DataSource object.
Has anybody got this working?
Appreciate any comments.
Thanks.
SampleSource (or ChunkSource) takes the upstream DataSource object in its constructor - that is how you connect a DataSource to SampleSource (or ChunkSource)
Let me take an example of HLS to illustrate how to inject your custom DataSource to SampleSource.
In https://github.com/google/ExoPlayer/blob/master/demo/src/main/java/com/google/android/exoplayer/demo/player/HlsRendererBuilder.java
Existing Code
DataSource dataSource = new UriDataSource(userAgent, bandwidthMeter);
HlsChunkSource chunkSource = new HlsChunkSource(dataSource, url, manifest, bandwidthMeter, null,
HlsChunkSource.ADAPTIVE_MODE_SPLICE);
HlsSampleSource sampleSource = new HlsSampleSource(chunkSource, true, 3);
Let's assume you implement a CustomDataSource class. New code will look like this
CustomDataSource dataSource = new CustomDataSource(<your arguments here>);
HlsChunkSource chunkSource = new HlsChunkSource(dataSource, url, manifest, bandwidthMeter, null,
HlsChunkSource.ADAPTIVE_MODE_SPLICE);
HlsSampleSource sampleSource = new HlsSampleSource(chunkSource, true, 3);

How can I get the View in the FileTransfer upload method in PhoneGap?

I have created a native android app with PhoneGap + Sencha Touch 2. I have succeeded in uploading a file to the server, however, I am having a problem accessing a View from the upload success callback function in the FileTransfer upload() method. Here is my code:
upload callback:
uploadPicture: function(imageURI) {
var options = new FileUploadOptions(),
params = new Object(),
fileTransfer = new FileTransfer(),
builder = this.getBuilder(),
app = this.getApplication(),
uri = encodeURI('/myservlet');
options.fileKey = 'file';
options.fileName = imageURI.substr(imageURI.lastIndexOf('/') + 1);
options.mimeType = 'image/jpeg';
params.myparams = something;
params.moreparams = evenmore;
options.params = params;
options.chunkedMode = false;
fileTransfer.upload(imageURI, uri, this.uploadSuccess.bind(this), this.uploadError.bind(this), options);
},
upload success function
uploadSuccess: function (r) {
var builderChild = this.getBuilderChild(),
data = r.response.attachment;
builderChild.addInstance(builderChild.config, data);
navigator.notification.alert('Attachment successful.');
}
When I get into the uploadSuccess function my builderChild object is undefined. I have been able to use the builderChild object through this same Controller in other functions, but not in uploadSuccess.
Any ideas?
Give this a try, this is how I used to do it.
var ftSuccess = Ext.bind(this.uploadSuccess, this),
ftError = Ext.bind(this.uploadError, this);
fileTransfer.upload(imageURI, uri, ftSuccess, ftError, options);
Hope this helped

Categories

Resources