Sideload subtitle not working in ExoPlayer - android

I am trying to sideload a subtitle file with my video, but it does not work.
Code:
private MediaSource buildMediaSourceWithSubtitle(Uri uri, #Nullable String overrideExtension, Uri subtitle) {
Format subtitleFormat = Format.createTextSampleFormat(null, MimeTypes.APPLICATION_SUBRIP, 0, null);
MediaSource subtitleSource = new SingleSampleMediaSource.Factory(dataSourceFactory).createMediaSource(subtitle, subtitleFormat, C.TIME_UNSET);
MediaSource mediaSource = null;
#ContentType int type = Util.inferContentType(uri, overrideExtension);
switch (type) {
case C.TYPE_DASH:
mediaSource = new DashMediaSource.Factory(dataSourceFactory).setManifestParser(
new FilteringManifestParser < >(new DashManifestParser(), getOfflineStreamKeys(uri))).createMediaSource(uri);
return new MergingMediaSource(mediaSource, subtitleSource);
case C.TYPE_SS:
mediaSource = new SsMediaSource.Factory(dataSourceFactory).setManifestParser(
new FilteringManifestParser < >(new SsManifestParser(), getOfflineStreamKeys(uri))).createMediaSource(uri);
return new MergingMediaSource(mediaSource, subtitleSource);
case C.TYPE_HLS:
mediaSource = new HlsMediaSource.Factory(dataSourceFactory).setPlaylistParserFactory(
new DefaultHlsPlaylistParserFactory(getOfflineStreamKeys(uri))).createMediaSource(uri);
return new MergingMediaSource(mediaSource, subtitleSource);
case C.TYPE_OTHER:
mediaSource = new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(uri);
return new MergingMediaSource(mediaSource, subtitleSource);
default:
{
throw new IllegalStateException("Unsupported type: " + type);
}
}
}

MediaSource videoSource = new ExtractorMediaSource(
videoUri,
dataSourceFactory,
new DefaultExtractorsFactory(),
null,
null);
Format subtitleFormat = Format.createTextSampleFormat(
null,
MimeTypes.APPLICATION_SUBRIP,
C.SelectionFlags,
"en");
MediaSource textMediaSource = new SingleSampleMediaSource(
Uri.parse("http://www.storiesinflight.com/js_videosub/jellies.srt"),
dataSourceFactory,
subtitleFormat,
C.TIME_UNSET);
source = new MergingMediaSource(videoSource, textMediaSource); // to be used later
// nested to some class that has SubtitleView as member
class SomeListener implements ..., TextRenderer.Output, ... {
...
// this function doesn't seem to be invoked
public void onCues(List cues) {
// some logging here
if (subtitleView != null) {
subtitleView.onCues(cues);
}
}
...
}
player.setTextOutput(listener);
...
// later, play the video assuming its prepared and whatnot
player.setPlayWhenReady(true);

In Exoplayer 2.16.1 I used this code and worked properly:
val subtitle = MediaItem.SubtitleConfiguration.Builder(srtUri)
.setMimeType(MimeTypes.APPLICATION_SUBRIP)
.setLanguage("en")
.setSelectionFlags(C.SELECTION_FLAG_DEFAULT)
.build()
val mediaItem = MediaItem.Builder()
.setUri(videoUrl)
.setSubtitleConfigurations(ImmutableList.of(subtitle))
.build()
player?.setMediaItem(mediaItem)

Related

How to initialise exoplayer to play dash(.mpd) videos

I have the playlist of dash videos and this was the code I used to play the media when the version was 2.7.3. Now I have updated to 2.9.5, I'm facing issues.
My init and mediasource methods :
private void initializePlayer() {
if (player == null) {
// a factory to create an AdaptiveVideoTrackSelection
TrackSelection.Factory adaptiveTrackSelectionFactory =
new AdaptiveTrackSelection.Factory(BANDWIDTH_METER);
player = ExoPlayerFactory.newSimpleInstance(
new DefaultRenderersFactory(this),
new DefaultTrackSelector(adaptiveTrackSelectionFactory),
new DefaultLoadControl());
player = ExoPlayerFactory.newSimpleInstance(new DefaultRenderersFactory(this),
new DefaultTrackSelector(), new DefaultLoadControl());
playerView.setPlayer(player);
player.addListener(new PlayerEventListener());
/*player.setPlayWhenReady(playWhenReady);
player.seekTo(currentWindow, playbackPosition);*/
}
playListMediaSources = buildPlayListMediaSource(serialURLs);
concatenatingMediaSource = new ConcatenatingMediaSource(playListMediaSources);
player.prepare(concatenatingMediaSource, true, false);
player.setPlayWhenReady(playWhenReady);
player.seekTo(currentWindow, playbackPosition);
}
private MediaSource buildMediaSource(Uri uri) {
/* DefaultExtractorsFactory defaultExtractorsFactory = new DefaultExtractorsFactory();
DefaultHttpDataSourceFactory defaultHttpDataSourceFactory = new DefaultHttpDataSourceFactory("user-agent");*/
DataSource.Factory manifestDataSourceFactory =
new DefaultHttpDataSourceFactory("ua");
DashChunkSource.Factory dashChunkSourceFactory =
new DefaultDashChunkSource.Factory(
new DefaultHttpDataSourceFactory("ua", BANDWIDTH_METER));
return new DashMediaSource.Factory(dashChunkSourceFactory,
manifestDataSourceFactory).createMediaSource(uri);
}
private MediaSource[] buildPlayListMediaSource(String[] serialURLs) {
MediaSource[] mediaSources = new MediaSource[serialURLs.length];
Uri uri;
for (int i = 0; i < serialURLs.length; i++) {
uri = Uri.parse(serialURLs[i]);
mediaSources[i] = buildMediaSource(uri);
}
return mediaSources;
}
I modified my init code to this :
private void initializePlayer() {
if (player == null) {
TrackSelection.Factory adaptiveTrackSelectionFactory = new AdaptiveTrackSelection.Factory();
player = ExoPlayerFactory.newSimpleInstance(this,
new DefaultRenderersFactory(this),
new DefaultTrackSelector(adaptiveTrackSelectionFactory),
new DefaultLoadControl());
player = ExoPlayerFactory.newSimpleInstance(this,new DefaultRenderersFactory(this),
new DefaultTrackSelector(), new DefaultLoadControl());
}
if (serialURLs != null) {
playListMediaSources = buildPlayListMediaSource(serialURLs);
concatenatingMediaSource = new ConcatenatingMediaSource(playListMediaSources);
player.prepare(concatenatingMediaSource, true, false);
player.setPlayWhenReady(playWhenReady);
player.seekTo(currentWindow, playbackPosition);
}
}
But failed to play the video. My guess is I have to make some changes in Media sources methods as well, but I'm unable to figure out the changes. With my current code, the log shows the following error :
E/AndroidRuntime: FATAL EXCEPTION: ExoPlayerImplInternal:Handler
Process: com.packagename, PID: 2731
java.lang.AbstractMethodError: abstract method "void com.google.android.exoplayer2.source.BaseMediaSource.prepareSourceInternal(com.google.android.exoplayer2.upstream.TransferListener)"
at com.google.android.exoplayer2.source.BaseMediaSource.prepareSource(BaseMediaSource.java:140)
at com.google.android.exoplayer2.ExoPlayerImplInternal.prepareInternal(ExoPlayerImplInternal.java:398)
at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:285)
at android.os.Handler.dispatchMessage(Handler.java:101)
at android.os.Looper.loop(Looper.java:164)
at android.os.HandlerThread.run(HandlerThread.java:65)
I'm adding this text to avoid mostly code error. Any help is appreciated. Thanks in advance.
Both com.google.android.exoplayer:exoplayer-core and com.google.android.exoplayer:exoplayer-dash needs to be the same version in your build.gradle.
implementation 'com.google.android.exoplayer:exoplayer-core:2.9.6'
implementation 'com.google.android.exoplayer:exoplayer-dash:2.9.6'
Finally i settled for this:
private void initializePlayer() {
if (player == null) {
TrackSelection.Factory adaptiveTrackSelection = new AdaptiveTrackSelection.Factory();
TrackSelector trackSelector = new DefaultTrackSelector(adaptiveTrackSelection);
DefaultLoadControl loadControl = new DefaultLoadControl.Builder().setBufferDurationsMs(64*1024, 128*1024, 1024, 1024).createDefaultLoadControl();
//LoadControl loadControl = new DefaultLoadControl();
// HttpDataSource.Factory factory = new DefaultHttpDataSourceFactory(Util.getUserAgent(this, "Exo2"));
player = ExoPlayerFactory.newSimpleInstance(this,new DefaultRenderersFactory(this), trackSelector, loadControl);
playerView.setPlayer(player);
player.addListener(new PlayerEventListener());
}
if (isPlaylist) {
if (serialURLs != null) {
nextBtn.setVisibility(View.VISIBLE);
playListMediaSources = buildPlayListMediaSource(serialURLs);
concatenatingMediaSource = new ConcatenatingMediaSource(playListMediaSources);
readLastSeen(contentName, isWebSeries);
player.prepare(concatenatingMediaSource, true, false);
player.setPlayWhenReady(playWhenReady);
player.seekTo(currentWindow, playbackPosition);
} else {
// previousBtn.setVisibility(View.GONE);
//nextBtn.setVisibility(View.GONE);
Uri uri = Uri.parse(getString(R.string.sample_video));
mediaSource = buildMediaSource(uri);
Toast.makeText(MediaPlayerActivity.this, "Playing sample video..", Toast.LENGTH_LONG).show();
player.prepare(mediaSource, true, false);
player.setPlayWhenReady(playWhenReady);
player.seekTo(playbackPosition);
}
} else {
if (videoURL != null) {
Uri uri = Uri.parse(videoURL);
mediaSource = buildMediaSource(uri);
}
player.prepare(mediaSource, true, false);
player.setPlayWhenReady(playWhenReady);
player.seekTo(playbackPosition);
}
}
private MediaSource buildMediaSource(Uri uri) {
DataSource.Factory dataSourceFactory =
new DefaultDataSourceFactory(MediaPlayerActivity.this, "ua");
return new DashMediaSource.Factory(dataSourceFactory)
.createMediaSource(uri);
}
and these are my dependencies :
implementation 'com.google.android.exoplayer:exoplayer-core:2.10.0'
implementation 'com.google.android.exoplayer:exoplayer-dash:2.10.0'
implementation 'com.google.android.exoplayer:extension-mediasession:2.8.4'
implementation 'com.google.android.exoplayer:exoplayer-ui:2.8.+'
implementation 'com.google.android.exoplayer:exoplayer:r2.4.0'

Exoplayer changing subtitle on the fly

I am trying to change a subtitle for a video in Exoplayer. Video can already have a subtitle or user can add a new subtitle from internal storage. I know that before starting the player we can create Mediasource for both subtitle and video and merge using MergingMediaSource. However, I am not sure how to replace/add new subtitles to the currently playing video? Is it possible using DynamicConcatenatingMediaSource or any other way to do so?
MediaSource[] subTitleMediaSources = new MediaSource[uris.length];
Format subtitleFormat = Format.createTextSampleFormat(
null,
MimeTypes.APPLICATION_SUBRIP,
C.SELECTION_FLAG_DEFAULT,
null);
for (int i = 0; i < uris.length; i++) {
String subTitle = getSubtitleFile(subs, uris[i]);
if (subTitle != null) {
subTitleMediaSources[i] = new SingleSampleMediaSource.Factory(mediaDataSourceFactory).
createMediaSource(Uri.parse(subTitle), subtitleFormat,
C.TIME_UNSET);
} else {
subTitleMediaSources[i] = new SingleSampleMediaSource.Factory(mediaDataSourceFactory).
createMediaSource(Uri.parse("dummy"), subtitleFormat, C.TIME_UNSET);
}
}
MediaSource mediaSource = mediaSources.length == 1 ? mediaSources[0]
: new ConcatenatingMediaSource(mediaSources);
MediaSource subsMediaSource = subTitleMediaSources.length == 1 ? subTitleMediaSources[0]
: new ConcatenatingMediaSource(subTitleMediaSources);
MediaSource mergedSource;
if (subsMediaSource == null) {
mergedSource = mediaSource;
} else {
mergedSource = new MergingMediaSource(mediaSource, subsMediaSource);
}
I was able to get this to work by removing the Mediasource and adding it again. I used a ConcatenatingMediaSource. I think there should be a better/easy way than this by just adding new subtitle source to existing MergingMediasource. Suggestions are most welcome.
public void onSubSelected(String path) {
final long position = player.getCurrentPosition();
if (path == null) {
return;
}
List<MediaSource> subtitleSource = new ArrayList<>();
Uri uri = uris[currentIndex];
MediaSource trackSource = buildMediaSource(uri);
List<String> subPaths;
if (!pathSubtitleMapping.containsKey(uri)) {
subPaths = new ArrayList<>();
subPaths.add(path);
subtitleSource.add(buildSubtitleSource(path));
pathSubtitleMapping.put(uris[currentIndex], subPaths);
} else {
subPaths = pathSubtitleMapping.get(uri);
if (!subPaths.contains(path)) {
subPaths.add(path);
}
for (String path1 : subPaths) {
subtitleSource.add(buildSubtitleSource(path1));
}
}
MediaSource mediaSources[] = new MediaSource[subtitleSource.size() + 1];
mediaSources[0] = trackSource;
int index = 1;
for (MediaSource source : subtitleSource) {
mediaSources[index] = source;
index++;
}
finalMediaSource.removeMediaSource(currentIndex);
finalMediaSource.addMediaSource(currentIndex, new MergingMediaSource(mediaSources), new Runnable() {
#Override
public void run() {
player.seekTo(currentIndex, position);
}
});
}
private Map<Uri, List<String>> pathSubtitleMapping = new HashMap<>(); // (uri, list of subs)
private MediaSource buildMediaSource(Uri uri) {
MediaSource newSource = new ExtractorMediaSource.Factory(mediaDataSourceFactory).createMediaSource(uri);
return newSource;
}
private MediaSource buildSubtitleSource(String path) {
Format subtitleFormat = Format.createTextSampleFormat(
null,
MimeTypes.APPLICATION_SUBRIP,
C.SELECTION_FLAG_DEFAULT,
null);
MediaSource mediaSource = new SingleSampleMediaSource.Factory(mediaDataSourceFactory).
createMediaSource(Uri.parse(path), subtitleFormat, C.TIME_UNSET);
return mediaSource;
}

Exoplayer's DynamicConcatenatingMediaSource not working

I am implementing a music application. I am using Exoplayer2
I am trying to use DynamicConcatenatingMediaSource to add & remove items to the playlist dynamically.
Here is my implementation.
public void initMusicPlayer(){
if (songs !=null)
{
MediaSource mediaSource;
ArrayList<MediaSource> sources = new ArrayList<>();
MusicItem song;
for (int i=0;i< songs.size();i++)
{
song = songs.get(i);
mediaSource = buildMediaSource(Uri.parse(song.getMusicUrl()));
sources.add(mediaSource);
}
dynamicMediaSource = new DynamicConcatenatingMediaSource();
dynamicMediaSource.addMediaSources(sources);
exoPlayer.prepare(dynamicMediaSource,false,false);
exoPlayer.addListener(this);
if (currentPlayingSongIndex == -1)
{
exoPlayer.setPlayWhenReady(false);
}
else
{
exoPlayer.seekTo(currentPlayingSongIndex,0);
exoPlayer.setPlayWhenReady(true);
}
}
}
public void addItemToPlaylist(MusicItem song,boolean shouldPlay){
long position = exoPlayer.getContentPosition();
MediaSource mediaSource = buildMediaSource(Uri.parse(song.getMusicUrl()));
dynamicMediaSource.addMediaSource(mediaSource);
exoPlayer.prepare(dynamicMediaSource,false,false);
if (shouldPlay)
{
exoPlayer.seekTo(currentPlayingSongIndex,0);
}
else
{
exoPlayer.seekTo(currentPlayingSongIndex,position);
}
}
But, this implementation is not working. It doesn't play anything.
What's wrong in the above code ?
Also, how to add items dynamically to playlist ? Will the above addItemToPlaylist work ?
This is the function I created to play a playlist of mp3 files in Kotlin.
(You can copy paste it in Android Studio and it will be converted to Java if you use Java)
private fun mediaPlayerConfiguration() {
val bandwidthMeter = DefaultBandwidthMeter()
val extractorsFactory = DefaultExtractorsFactory()
val trackSelectionFactory = AdaptiveTrackSelection.Factory(bandwidthMeter)
val trackSelector = DefaultTrackSelector(trackSelectionFactory)
val defaultBandwidthMeter = DefaultBandwidthMeter()
val dataSourceFactory = DefaultDataSourceFactory(this,
Util.getUserAgent(this, "mediaPlayerSample"), defaultBandwidthMeter)
val dynamicConcatenatingMediaSource = DynamicConcatenatingMediaSource()
for (item in myActivity.list) {
var mediaSource = ExtractorMediaSource.Factory(dataSourceFactory).setExtractorsFactory(extractorsFactory).createMediaSource(Uri.parse(item))
dynamicConcatenatingMediaSource.addMediaSource(mediaSource)
}
mPlayer = ExoPlayerFactory.newSimpleInstance(this, trackSelector)
mPlayer.prepare(dynamicConcatenatingMediaSource)
mPlayer.playWhenReady = true
}

ExoPlayer playlist throws IndexOutOfBoundsException with LoopingMediaSource

I have to play video A once, and after it finished, loop video B indefinitely. I'm trying to use ConcatenatingMediaSource for that:
private SimpleExoPlayer initPlayer(ViewGroup layout, int playerViewId, ExoPlayer.EventListener eventListener) {
// 1. Create a default TrackSelector
TrackSelector trackSelector = new DefaultTrackSelector();
// 2. Create a default LoadControl
LoadControl loadControl = new DefaultLoadControl();
// 3. Create the player
this.player = ExoPlayerFactory.newSimpleInstance(getContext(), trackSelector, loadControl);
SimpleExoPlayerView simpleExoPlayerView = (SimpleExoPlayerView) layout.findViewById(playerViewId);
// Bind the player to the view.
simpleExoPlayerView.setUseController(false);
simpleExoPlayerView.setPlayer(player);
if (eventListener != null)
player.addListener(eventListener);
// Prepare the player with the source.
player.setPlayWhenReady(true);
return player;
}
public void startPlayer(String firstURL, String loopingURL) {
initProxy();
DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
MediaSource firstSource = getVideoPlayerMediaSource(bandwidthMeter, firstURL);
MediaSource secondSource = new LoopingMediaSource(getVideoPlayerMediaSource(bandwidthMeter, loopingURL));
ConcatenatingMediaSource concatenatedSource =
new ConcatenatingMediaSource(firstSource, secondSource);
player.setPlayWhenReady(true);
player.prepare(concatenatedSource);
player.setVideoScalingMode(C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
setPlayerPlaying(true);
}
private void initProxy() {
if (proxy == null)
proxy = VideoCache.getProxy(getContext());
}
#NonNull
private MediaSource getVideoPlayerMediaSource(DefaultBandwidthMeter bandwidthMeter, String videoUrl) {
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(getContext(),
Util.getUserAgent(getContext(), "com.myapp"), bandwidthMeter);
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
Uri url = Uri.parse(videoUrl);
MediaSource videoSource;
if (videoUrl.contains(".mp4")) {
url = Uri.parse(proxy.getProxyUrl(videoUrl));
videoSource = new ExtractorMediaSource(url,
dataSourceFactory, extractorsFactory, null, null);
} else {
videoSource = new HlsMediaSource(url, dataSourceFactory, null, null);
}
return videoSource;
}
But this throws:
Internal runtime error.
java.lang.IndexOutOfBoundsException
at com.google.android.exoplayer2.util.Assertions.checkIndex(Assertions.java:66)
at com.google.android.exoplayer2.ExoPlayerImplInternal.getPeriodPosition(ExoPlayerImplInternal.java:1077)
at com.google.android.exoplayer2.ExoPlayerImplInternal.getPeriodPosition(ExoPlayerImplInternal.java:1059)
at com.google.android.exoplayer2.ExoPlayerImplInternal.getPeriodPosition(ExoPlayerImplInternal.java:1050)
at com.google.android.exoplayer2.ExoPlayerImplInternal.handleSourceInfoRefreshed(ExoPlayerImplInternal.java:872)
at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:320)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:148)
at android.os.HandlerThread.run(HandlerThread.java:61)
at com.google.android.exoplayer2.util.PriorityHandlerThread.run(PriorityHandlerThread.java:40)
The problem happens only when using the secondSource as LoopingMediaSource. It works without it, but obviously doesn't loop the second video.
(ExoPlayer version r2.3.1)
Try using the other constructor for your LoopingMediaSource, where you specify a loop count and see if that works:
public LoopingMediaSource(MediaSource childSource, int loopCount) {
Assertions.checkArgument(loopCount > 0);
this.childSource = childSource;
this.loopCount = loopCount;
}
It looks like you are getting a handleSourceInfoRefreshed message, which is sent from the LoopingMediaSource prepareSource() method:
#Override
public void prepareSource(ExoPlayer player, boolean isTopLevelSource, final Listener listener) {
childSource.prepareSource(player, false, new Listener() {
#Override
public void onSourceInfoRefreshed(Timeline timeline, Object manifest) {
childPeriodCount = timeline.getPeriodCount();
listener.onSourceInfoRefreshed(new LoopingTimeline(timeline, loopCount), manifest);
}
});
}
But that creates a new LoopingTimeline object and passes it loopCount, which is 0 in your case. The LoopingTimeline class overrides getWindowCount():
#Override
public int getWindowCount() {
return childWindowCount * loopCount;
}
Which will return 0 if the loopCount is 0.
If that works, then you can get your video to loop indefinitely by passing (Integer.MAX_VALUE - 1) as the loopCount, since the LoopingTimeline will cap the loop count anyway.

Setting headers for streaming mp4 video and playing files with Exoplayer

Api has a token header that i need to set but the video is not encrypted.
I have two questions:
How can i play .mpg,.mpeg,.3gp,.mov and other files from disk with exoplayer?
How can i set headers with exoplayer and stream mp4 video from url?
Figured out the answer:
DefaultHttpDataSource source = new DefaultHttpDataSource(userAgent, null);
source.setRequestProperty("Authorization", "your auth code");
source.setRequestProperty("Accept", "...");
ExtractorSampleSource sampleSource = new ExtractorSampleSource(uri, source, extractor, 2,
BUFFER_SIZE);
MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(sampleSource,
null, true, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING, 5000, null, player.getMainHandler(),
player, 50);
MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource,
null, true, player.getMainHandler(), player);
// (1) Create method returns 'DataSource.Factory'
public DataSource.Factory headers() {
Map<String, String> headersMap = new HashMap<>();
headersMap.put("iid", "aaa123 ");
headersMap.put("version", "1.4");
headersMap.put("agent", "phone");
headersMap.put("token", "dfdf4f4yt5yf5fh4f5");
return new DefaultHttpDataSource.Factory().setDefaultRequestProperties(headersMap);
}
// (2) Add headers() method call to the player
SimpleExoPlayer player = new SimpleExoPlayer.Builder(context)
.setMediaSourceFactory(new
DefaultMediaSourceFactory(headers()))
.build();
ON exoplayer 2.13.2, DefaultDataSourceFactory constructor method is deprecated, you can use Factory instead.
val dataSourceFactory: DataSource.Factory = DefaultHttpDataSource.Factory()
.setUserAgent("")
.setDefaultRequestProperties(hashMapOf("" to ""))
.setDefaultRequestProperties(hashMapOf("" to ""))
val mediaSource: MediaSource = ProgressiveMediaSource.Factory(dataSourceFactory)
.createMediaSource(MediaItem.fromUri(url))
val player = SimpleExoPlayer
.Builder(this)
.build()
binding.videoPlayerView.player = player
player.setMediaSource(mediaSource)
player.prepare()
player.play()
// 1. Create a default TrackSelector
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelection.Factory videoTrackSelectionFactory = new
AdaptiveTrackSelection.Factory(bandwidthMeter);
TrackSelector trackSelector = new
DefaultTrackSelector(videoTrackSelectionFactory);
// 2. Create a default LoadControl
LoadControl loadControl = new DefaultLoadControl();
// 3. Create the player
player = ExoPlayerFactory.newSimpleInstance(this, 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);
String username = "username";
String password = "password";
// encrypt Authdata
byte[] toEncrypt = (username + ":" + password).getBytes();
encoded = Base64.encodeToString(toEncrypt, Base64.DEFAULT);
DefaultHttpDataSourceFactory dataSourceFactory = new
DefaultHttpDataSourceFactory(Util.getUserAgent(this,
"exoplayer2example"));
DefaultHttpDataSource source = new DefaultHttpDataSource(Util.getUserAgent(this, "exoplayer2example"),null);
dataSourceFactory.setDefaultRequestProperty("Authorization","Basic "+encoded);
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
MediaSource videoSource = new ExtractorMediaSource(Uri.parse("https://example.com/assets/video/SampleVideo.mp4"),
dataSourceFactory, extractorsFactory, null, null);
final LoopingMediaSource loopingSource = new LoopingMediaSource(videoSource);
exoplayer.prepare(videoSource);
How can i set headers with exoplayer and stream mp4 video from url?
I implemented basic authorisation so:
private SimpleExoPlayer player;
private PlayerView playerView;
private void initializePlayer() {
player = ExoPlayerFactory.newSimpleInstance(
new DefaultRenderersFactory(this),
new DefaultTrackSelector(),
new DefaultLoadControl());
playerView.setPlayer(player);
player.setPlayWhenReady(true);
player.seekTo(0, 0);
Uri uri = Uri.parse(getString(R.string.media_url));
MediaSource mediaSource = buildMediaSource(uri);
player.prepare(mediaSource, true, false);
}
private MediaSource buildMediaSource(final Uri uri) {
HttpDataSource.BaseFactory myDSFactory = new HttpDataSource.BaseFactory() {
#Override
protected HttpDataSource createDataSourceInternal(HttpDataSource.RequestProperties defaultRequestProperties) {
byte[] toEncrypt = uri.getUserInfo().getBytes();
String encoded = "Basic " + Base64.encodeToString(toEncrypt, Base64.DEFAULT).trim();
DefaultHttpDataSourceFactory dsf = new DefaultHttpDataSourceFactory("exoplayer-codelab");
HttpDataSource ds = dsf.createDataSource();
ds.setRequestProperty("Authorization", encoded);
return ds;
}
};
ExtractorMediaSource.Factory emf = new ExtractorMediaSource.Factory(myDSFactory);
return emf.createMediaSource(uri);
}

Categories

Resources