Exoplayer 2.12, dose not load local subtitles - android

Even after going through many questions on Stackoverflow and other threads we could not find any solution for the subtitle issue in Exoplayer.
Following is the code snippet we are using to load video and subtitle from local storage.
public void setVideo(String absolutePath, String vtt){
player = new SimpleExoPlayer.Builder(this).build();
videoView.setPlayer(player);
// MediaItem mediaItem = MediaItem.fromUri(absolutePath);
MediaItem.Subtitle subtitle = new MediaItem.Subtitle(Uri.parse(vtt),MimeTypes.TEXT_VTT,"en-US");
List<MediaItem.Subtitle> subtitleList = new ArrayList<>();
subtitleList.add(subtitle);
videoView.setShowSubtitleButton(true);
MediaItem mediaItem = new MediaItem.Builder()
.setUri(absolutePath)
.setDrmUuid(C.WIDEVINE_UUID)
.setDrmMultiSession(true)
.setSubtitles(subtitleList)
.build();
player.setMediaItem(mediaItem);
player.setPlayWhenReady(true);
player.prepare();
}
Here absolutePath is path to the video and vtt is the path to .srt subtitle file.
We would really appreciate any suggestions or alternative way to achieve this.

Related

Is it possible to play a rtmp livestream in android app

Does anyone know if it’s possible to play a rtmp stream with exoplayer.
I’ve tried this but didn’t manage to get it working:
ExoPlayer player = new ExoPlayer.Builder(this).build();
playerView.setPlayer(player);
Uri uri = Uri.parse("rtmp://192.168.109.84/live");
MediaItem mediaItem = MediaItem.fromUri(uri);
RtmpDataSource.Factory rtmpDataSourceFactory = new RtmpDataSource.Factory();
MediaSource mediaSource = new ProgressiveMediaSource.Factory(rtmpDataSourceFactory).createMediaSource(mediaItem);
player.setMediaSource(mediaSource);
player.prepare();
player.setPlayWhenReady(true);

How to fix 2160p mkv video not running in Exoplayer

In my video player when i try to play 2160p MKV 4k video file in exoplayer. The video is not playing.
Error message is ERROR_CODE_DECODING_FAILED
Error code is 4003.
Exoplayer version is 2.16.1
Same video file is playing using android video library and other video player app that i downloaded from play store.
Code :
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(getApplicationContext());
ProgressiveMediaSource.Factory mediaSource = new ProgressiveMediaSource.Factory(dataSourceFactory);
trackSelector = new DefaultTrackSelector(this);
builder = new ExoPlayer.Builder(getApplicationContext());
builder.setSeekBackIncrementMs(10000);
builder.setSeekForwardIncrementMs(10000);
player = builder.setMediaSourceFactory(mediaSource).setTrackSelector(trackSelector).build();//new ExoPlayer.Builder(getApplicationContext()).setTrackSelector(trackSelector).build();
playerView.setPlayer(player);
MediaItem mediaItem;
ArrayList<MediaItem> mediaItems = new ArrayList<>();
for (int i = 0; i < vdList.size(); i++) {
Uri uri = Uri.parse(vdList.get(i).path);
mediaItem = new MediaItem.Builder().setUri(uri).build();
mediaItems.add(mediaItem);
}
player.addMediaItems(mediaItems);
playerView.setKeepScreenOn(true);
playerView.requestFocus();
player.prepare();
player.seekTo(position, C.TIME_UNSET);
player.play();
Please help me out.

How to get local video Uri for ExoPlayer 2.x

I have a dog.mp4 video file in res/raw folder, which I want to play with ExoPlayer. I'm trying to figure out how to get video Uri for this line of code from ExoPlayer developers guide (https://google.github.io/ExoPlayer/guide.html):
MediaSource videoSource = new ExtractorMediaSource(mp4VideoUri,
dataSourceFactory, extractorsFactory, null, null);
To get it, I use this line:
Uri mp4VideoUri = Uri.parse("android.resources://"+getPackageName()+"/"+R.raw.dog);
Also tried this syntax: android.resource://[package]/[res type]/[res name]
But SimpleExoPlayerView stays black and I get following error:
com.google.android.exoplayer2.upstream.HttpDataSource$HttpDataSourceException: Unable to connect to android.resources://lt.wilkas.deleteexoplayer/2131099648
What am I doing wrong?
Don't move your videos from raw to any another folder
Use this code to play video:
PlayerView playerView = findViewById(R.id.player_view);
SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance(this);
// Bind the player to the view.
playerView.setPlayer(player);
// Produces DataSource instances through which media data is loaded.
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "yourApplicationName"));
// This is the MediaSource representing the media to be played.
MediaSource firstSource = new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(RawResourceDataSource.buildRawResourceUri(R.raw.dog));
// Prepare the player with the source.
player.prepare(firstSource);
According to ExoPlayer 2.12 its even easier to use MediaItem.
To create it we need Uri that could be generated from RawResourceDataSource.buildRawResourceUri.
And that's it. Just set this MediaItem do prepare() and play when ready:
SimpleExoPlayer.Builder(view.context).build().apply {
val uri = RawResourceDataSource.buildRawResourceUri(R.raw.video)
setMediaItem(MediaItem.fromUri(uri))
prepare()
playWhenReady = true
}
I've found out that res/raw folder cant be used to store local videos for ExoPlayer. They should be placed in assets folder.
res/raw folder can be used to access local video file for ExoPlayer via it's URI. Here's the solution that will not give the Malformed URL exception and it works for me. You have to use RawResourceDataSource.buildRawResourceUri(R.raw.video) method of the RawResourceDataSource class. Keep in mind that i used the 2.8.0 version of ExoPlayer.
public class MainActivity extends AppCompatActivity {
PlayerView playerView;
SimpleExoPlayer simpleExoPlayer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
playerView=findViewById(R.id.playerView);
}
#Override
protected void onStart() {
simpleExoPlayer= ExoPlayerFactory.newSimpleInstance(this,new DefaultTrackSelector());
DefaultDataSourceFactory defaultDataSourceFactory=new DefaultDataSourceFactory(this, Util.getUserAgent(this,"yourApplicationName"));
simpleExoPlayer.setPlayWhenReady(true);
ExtractorMediaSource extractorMediaSource=new ExtractorMediaSource.Factory(defaultDataSourceFactory).createMediaSource(RawResourceDataSource.buildRawResourceUri(R.raw.video));
simpleExoPlayer.prepare(extractorMediaSource);
playerView.setPlayer(simpleExoPlayer);
super.onStart();
}
#Override
protected void onStop() {
playerView.setPlayer(null);
simpleExoPlayer.release();
simpleExoPlayer=null;
super.onStop();
}
}
here is the sample to load video/audio file from res/raw with ExoPlayer :
val player = ExoPlayerFactory.newSimpleInstance(context,DefaultTrackSelector())
val rawDataSource = RawResourceDataSource(context)
rawDataSource.open(DataSpec(RawResourceDataSource.buildRawResourceUri(R.raw.brown)))
val mediaSource = ExtractorMediaSource.Factory(DataSource.Factory { rawDataSource })
.createMediaSource(rawDataSource.uri)
player.playWhenReady = true
player.prepare(mediaSource)
sample copied from
This code works for me.
fun buildMediaSourceRaw() : MediaSource{
val dataSourceFactory = DefaultDataSourceFactory(context, "exoPlayer")
val uri = RawResourceDataSource.buildRawResourceUri(R.raw.my_video)
return ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(uri)
}
Then
player?.prepare(buildMediaSourceRaw())

ExoPlayer: get songs metadata from HTTP stream

I use the following code to play a music stream through ExoPlayer:
exoPlayer = ExoPlayer.Factory.newInstance(numRenderers, minBufSize, maxBufSize);
String url = Helper.getPr().getString("url", "http://mp3.nashe.ru:80/ultra-128.mp3");
Uri uri = Uri.parse(url);
Log.i(TAG, "Going to open " + url);
Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE);
DataSource dataSource = new DefaultUriDataSource(getApplicationContext(), USER_AGENT);
ExtractorSampleSource sampleSource = new ExtractorSampleSource(uri, dataSource, allocator, BUFFER_SEGMENT_COUNT * BUFFER_SEGMENT_SIZE);
audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource);
exoPlayer.addListener(this);
exoPlayer.sendMessage(audioRenderer, MediaCodecAudioTrackRenderer.MSG_SET_VOLUME, volume);
exoPlayer.prepare(audioRenderer);
exoPlayer.setPlayWhenReady(true);
I can't find any info on how to get metadata like artist and name of the current song. Is it possible to get the metadata and if yes, how?
Thanks a lot.
There are many types of metadata in many types of media, It's depending on your stream. But currently Exoplayer itself, only parse metadata from HLS streams (HTTP Live Streaming) they get ID3 data from the stream.
As you can see on there github repository issue,this is the current state of metadata in Exoplayer lib (August 2015):
https://github.com/google/ExoPlayer/issues/704
If it's your stream case, I will recommend you to download the Exoplayer demo on github (https://github.com/google/ExoPlayer/tree/release-v2/demos).
One of the examples in the demo display stream ID3 metadata on LogCat.
If it's not your case, nothing will help you in ExoPlayer lib right now.
But there is an alternative solution, which I have used for a radio stream application, and it work well:
IcyStreamMeta to get meta data from online stream radio :
Getting metadata from SHOUTcast using IcyStreamMeta
but not sure it will work with simple mp3 file.
I am late But with Exoplayer-2. You can use an extension created by #saschpe. https://github.com/sandeeprana011/android-exoplayer2-ext-icy
For example see this app: https://play.google.com/store/apps/details?id=com.zilideus.jukebox_new
gradle
implementation 'saschpe.android:exoplayer2-ext-icy:1.0.1'
So it includes an Extra Header "Icy-Metadata" with value 1
and on the response, it extracts the metadata from the stream data.
Usage:
IcyHttpDataSourceFactory factory = new IcyHttpDataSourceFactory.Builder(Util.getUserAgent(this, getResources().getString(R.string.app_name)))
.setIcyHeadersListener(this)
.setIcyMetadataChangeListener(this).build();
DefaultDataSourceFactory datasourceFactory = new DefaultDataSourceFactory(getApplicationContext(), null, factory);
ExtractorMediaSource mediaSource = new ExtractorMediaSource.Factory(datasourceFactory)
.setExtractorsFactory(new DefaultExtractorsFactory())
.createMediaSource(uri);
Exo.resetPlayer();
Exo.getPlayer(this).prepare(mediaSource);
In the case of Icy metadata, exoplayer has built in support as of version 2.10. see: https://stackoverflow.com/a/56333429/1898380
You probably should use MediaMetadataRetriever
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
mmr.setDataSource(getActivity(), uri);
String artist = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST);
You could use the follow code to do that(Maybe you should download the mp3 file first):
MediaMetadataRetriever metaRetriver = new MediaMetadataRetriever();
metaRetriver.setDataSource("LOCAL MP3 FILE PATH");
byte[] picArray = metaRetriver.getEmbeddedPicture();
Bitmap songImage = BitmapFactory .decodeByteArray(picArray, 0, picArray.length);
String albumName = metaRetriver .extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM);
String artistName = metaRetriver .extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST);
String songGenre = metaRetriver .extractMetadata(MediaMetadataRetriever.METADATA_KEY_GENRE));
source:http://mrbool.com/how-to-extract-meta-data-from-media-file-in-android/28130#ixzz3s8PUd9E7

Stream AAC on Android

I'm working on an app for a client that requires streaming of an AAC audio stream. Unfortunately, there's nothing I can do about the stream format on the server. I'm working on Android and have discovered that Android's media player does not support raw AAC streams (which is what I'm getting). I found a project on Google Code that supports it (I tested it with the stream) but it's GPL'ed and that doesn't work for my client. I don't have much experience with this sort of thing so forgive me if my ideas aren't great. I know Android can play AAC encoded content if it is in an MP4 wrapper so I had thought about creating an MP4 wrapper on the fly on the client-side or perhaps even just doing some conversion to another format on the fly. Are these reasonable options? Does anybody have better suggestions?
Thanks in advance!
Edit To rephrase, is it possible to put a raw AAC stream from a web server in an MP4 container in real time? If so, does anybody know of resources to help me with the process?
I'm wondering if you ever came up with a solution for this problem? I'm in a similar situation. We have a web service generating AAC files, though not raw, they have the ADTS header. Android 2.2 can't play these files, though android 2.1 can, oddly enough. It seems to be a problem rooted to android switching to stagefright libraries for media playback in 2.2.
The AAC files do play fine when wrapped in an MP4 container. We've accomplish this on the server side very easily using FAAC (I realize this doesn't help you in your situation). We are still investigating licensing issues with using an mp4 container though. Does this require royalties?
To answer my own question...a lawyer has confirmed that using an mp4 container for an AAC file does not require licensing.
I TRIED ACCDECODER by Google for 4 motnhs it did work well. I found it and in 2 days I could did it works! :) I found it and saw it on the last Google I/O 2017
I can suggest to use EXOPLAYER INSTEAD MEDIAPLAYER. It is a better and improve way. I had the same problem using just MediaPlayer, but short time ago I found Exoplayer, now I do not have problem to Play audio streaming Acc, mp3, mpeg, etc. I can give a couple links to check it.
ExoPlayer is an open source project that is not part of the Android framework and is distributed separately from the Android SDK. ExoPlayer’s standard audio and video components are built on Android’s MediaCodec API, which was released in Android 4.1 (API level 16). Because ExoPlayer is a library, you can easily take advantage of new features as they become available by updating your app.
ExoPlayer supports features like Dynamic adaptive streaming over HTTP (DASH), SmoothStreaming and Common Encryption, which are not supported by MediaPlayer. It's designed to be easy to customize and extend.
This is almost the same like MediaPlayer because Exoplayer extend from it. You can see a lot of differences and an easy way to implement it. If you need more help let me know :)
For example you have this:
Media Player mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource("http://your.url.com"); //add you url address
...
mediaPlayer.prepare();
mediaPlayer.start();
In Exoplayer you need it:
// 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);
ExoPlayer example code:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private SimpleExoPlayerView simpleExoPlayerView;
private SimpleExoPlayer player;
private ExoPlayer.EventListener exoPlayerEventListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v(TAG,"portrait detected...");
setContentView(R.layout.activity_main);
// 1. Create a default TrackSelector
Handler mainHandler = new Handler();
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveVideoTrackSelection.Factory(bandwidthMeter);
TrackSelector trackSelector = new DefaultTrackSelector(mainHandler, 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);
//CHOOSE CONTENT: Livestream links may be out of date so find any m3u8 files online and replace:
//VIDEO FROM SD CARD:
// String urimp4 = "/FileName.mp4";
// Uri mp4VideoUri = Uri.parse(Environment.getExternalStorageDirectory().getAbsolutePath()+urimp4);
//yachts livestream m3m8 file:
Uri mp4VideoUri =Uri.parse("http://your.url.com");
//Random livestream file:
// Uri mp4VideoUri =Uri.parse("http://your.url.com");
//Sports livestream file:
// Uri mp4VideoUri =Uri.parse("http://your.url.com");
// Measures bandwidth during playback. Can be null if not required.
DefaultBandwidthMeter bandwidthMeterA = new DefaultBandwidthMeter();
//Produces DataSource instances through which media data is loaded.
// DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "exoplayer2example"), bandwidthMeterA);
DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "exoplayer2example"), bandwidthMeterA);
//Produces Extractor instances for parsing the media data.
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
//This is the MediaSource representing the media to be played:
//FOR SD CARD SOURCE:
// MediaSource videoSource = new ExtractorMediaSource(mp4VideoUri, dataSourceFactory, extractorsFactory, null, null);
//FOR LIVESTREAM LINK:
MediaSource videoSource = new HlsMediaSource(mp4VideoUri, dataSourceFactory, 1, null, null);
final LoopingMediaSource loopingSource = new LoopingMediaSource(videoSource);
// Prepare the player with the source.
player.prepare(loopingSource);
player.addListener(new ExoPlayer.EventListener() {
#Override
public void onLoadingChanged(boolean isLoading) {
Log.v(TAG,"Listener-onLoadingChanged...");
}
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
Log.v(TAG,"Listener-onPlayerStateChanged...");
}
#Override
public void onTimelineChanged(Timeline timeline, Object manifest) {
Log.v(TAG,"Listener-onTimelineChanged...");
}
#Override
public void onPlayerError(ExoPlaybackException error) {
Log.v(TAG,"Listener-onPlayerError...");
player.stop();
player.prepare(loopingSource);
player.setPlayWhenReady(true);
}
#Override
public void onPositionDiscontinuity() {
Log.v(TAG,"Listener-onPositionDiscontinuity...");
}
});
player.setPlayWhenReady(true);
}//End of onCreate
#Override
protected void onStop() {
super.onStop();
Log.v(TAG,"onStop()...");
}
#Override
protected void onStart() {
super.onStart();
Log.v(TAG,"onStart()...");
}
#Override
protected void onResume() {
super.onResume();
Log.v(TAG,"onResume()...");
}
#Override
protected void onPause() {
super.onPause();
Log.v(TAG,"onPause()...");
}
#Override
protected void onDestroy() {
super.onDestroy();
Log.v(TAG,"onDestroy()...");
player.release();
}
}
It was a short example, If you are looking for something else or need more help let me know! I am here! I would like to help because I know how it feels when you are googling and searching and anything it is showing up! :) Take care!!

Categories

Resources