I am developing music application. I have been using exoplayer to play music. I have lived a problem and couldn't find any solution. My problem is that ı have downloaded song file from internet. This song name contains "?" mark. I create path for this song file and use its name. After song downloaded successfully. I play with exoplayer. I create path for this song and set to exoplayer but it couldn't be played.
Song path = /storage/emulated/0/mymusic/downloads/How am I?_009.mp3
Uri uri = Uri.parse(path);
MediaSource mediaSource = new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(uri, null, null);
exoPlayer.prepare(mediaSource);
I don't want replace "?" with any character.
How can I play?
Anybody help?
Thanks
you might also want to use something like this if youre planning on playing both offline and online music:
MediaSource mediaSource = new ExtractorMediaSource
.Factory(dataSourceFactory)
.createMediaSource(
isOnlinePath(path) ? Uri.parse(path) : Uri.fromFile(new File(path))
, null, null);
exoPlayer.prepare(mediaSource);
boolean isOnlinePath(String path) {
return path != null &&
(path.contains("http") ||
path.contains(".m3u") ||
path.contains(".pls"));
}
Related
I want to make Dynamic Audio Playlist using Exoplayer.I used DynamicMediaSource as well as ConcateMediaSource it will work fine but if my player is currently playing and i will try to add mediasource then current player can be go on pause state and newly added mediasource will be playing.Initially i will create media source for only one audio and make player.playWhenReady true for only first time.then add another source in list and create audio source for my playlist.
So is it possible to add mediasouce without pause player? And playlist can be play in added manner?
below code is for create media souce for first audio:-
fun createAudioSource(data: MusicDetailResponse.AudioX, audioAllItem: MusicDetailResponse.Audio, position: Int) {
player = ExoPlayerFactory.newSimpleInstance(context, DefaultTrackSelector())
val userAgent = Util.getUserAgent(context, context.getString(R.string.label_user_agent))
val dataSourceFactory = DefaultHttpDataSourceFactory(
userAgent, null,
DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS,
1800000,
true)
val hlsMediaSource = HlsMediaSource.Factory(dataSourceFactory)
.createMediaSource(Uri.parse(data.audio))
player!!.prepare(hlsMediaSource)
player!!.playWhenReady = true
}
fun addAudioList(item: MusicDetailResponse.AudioX) {
tempAudioList.add(item)
createHlsMediaSource(tempAudioList)
}
private fun createHlsMediaSource(tempAudioList: ArrayList<MusicDetailResponse.AudioX>) {
for (i in 1 until tempAudioList.size) {
val userAgent = Util.getUserAgent(context, context.getString(R.string.label_user_agent))
val dataSourceFactory = DefaultHttpDataSourceFactory(
userAgent, null,
DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS,
1800000,
true)
val hlsMediaSource = HlsMediaSource.Factory(dataSourceFactory)
.createMediaSource(Uri.parse(tempAudioList[i].audio))
cMediaSource!!.addMediaSource(hlsMediaSource)
}
player?.prepare(cMediaSource, false, false)
}
Renamed all occurrences of DynamicConcatenatingMediaSource to ConcatenatingMediaSource.
Ever wanted to support media playlists in your Android app, where users can add and remove playlist items arbitrarily during playback? Now you can!
From ExoPlayer 2.8.0 onward we’ve updated the ConcatenatingMediaSource with dynamic playlist functionality. On the surface the new media source has a very simple and straightforward interface:
addMediaSource(mediaSource) appends a new media source at the end of the playlist.
addMediaSource(index, mediaSource) inserts a new media source at the specified index in the playlist.
addMediaSources(Collection) bulk appends a whole set of new media sources at the end of the playlist.
addMediaSources(index, Collection) bulk inserts a set of new media sources at the specified index in the playlist.
removeMediaSource(index) removes the media source at the given index.
moveMediaSource(fromIndex, toIndex) moves an existing media source within the playlist. This is useful as you do not have to create a new MediaSource object. And you can also move around the currently playing item without disrupting playback.
getMediaSource(index) allows you to access the media source at the given index.
getSize() returns the current playlist length.
Using ExoPlayer i'm trying to play two audio tracks simultaneously.
My idea was to create two MediaSource, and to "combine" between them using MergingMediaSource.
This is what I have done:
Uri uriAudio1 = Uri.parse(AUDIO_URL_1);
Uri uriAudio2 = Uri.parse(AUDIO_URL_2);
MediaSource audioSource1 = new ExtractorMediaSource(uriAudio1, dataSourceFactory, extractorsFactory, mainHandler, null);
MediaSource audioSource2 = new ExtractorMediaSource(uriAudio2, dataSourceFactory, extractorsFactory, mainHandler, null);
MergingMediaSource mergedAudioSource = new MergingMediaSource(audioSource1, audioSource2);
mPlayer.prepare(mergedAudioSource);
How ever instead of hearing both audio tracks in parallel, i hear only the first audioSource1.
Any ideas? Thanks!
Try to set channel count like this
val trackSelector = DefaultTrackSelector()
trackSelector.setParameters(
trackSelector.buildUponParameters()
.setMaxVideoSizeSd()
.setMaxAudioChannelCount(2)
)
It seems that this functionality isn't currently supported, according to issue #2200.
I ran into the same problem, solved it by using two different instances of Exoplayer, one for each audio asset, and playing them at the same time.
You can use ConcatenatingMediaSource :
List<MediaSource> mediaSources = new ArrayList<>();
for (Track track : tracks) {
MediaSource mediaSource = ...//use your uri media source from tack.getPath
mediaSources.add(mediaSource);
}
mediaPlayer.prepare(new ConcatenatingMediaSource(mediaSources.toArray(new MediaSource[mediaSources.size()])));
I'm using this piece of code to try and open a .mp4 video:
VideoView videoView=(VideoView)findViewById(R.id.videoView1);
MediaController mediaController=new MediaController(this);
mediaController.setAnchorView(videoView) ;
videoView.setVideoPath("R.raw.videoname");
videoView.setMediaController(mediaController) ;
videoView.start();
However, whenever I try to run the app, I get a message saying "Can't play this video". I am using a new Nexus 7 tablet if that means anything.
Also, when I try to open the same file that I have stored in with my movies, the video runs perfectly normally when I use Gallery or Video Player to open it.
Any help is much appreciated.
File file = new File(getFilePath());//file path of your video
MimeTypeMap map = MimeTypeMap.getSingleton();
String ext = MimeTypeMap.getFileExtensionFromUrl(file.getName());
String type = map.getMimeTypeFromExtension(ext);
if (type == null)
type = "*/*";
Uri uri = Uri.parse("www.google.com");
Intent type_intent = new Intent(Intent.ACTION_VIEW, uri);
Uri data = Uri.fromFile(file);
type_intent.setDataAndType(data, type);
startActivity(type_intent);
Make sure there will be no space in video name, otherwise it will not
be played by android VideoView.
If not solved then let me know.
I am developing video player app. I want this app to be appear as option on selecting video from sdcard, album or any folder of the phone . When i select my video player to play video, it takes to app but video is not playing. I have given permission to read and write external storage in manifest.Below is my code :
Intent in =getIntent();
file_path = in.getData().getPath();
System.out.println("file path from sdcard:"+file_path);
videoView =(VideoView)findViewById(R.id.video);
MediaController mediaController= new MediaController(this);
mediaController.setAnchorView(videoView);
Uri uri=Uri.parse(file_path);
videoView.setVideoURI(uri);
videoView.requestFocus();
videoView.start();
ERROR :
10-19 10:39:40.917: I/System.out(20430): file path from sdcard:/external/video/media/24363
10-19 10:39:40.987: E/MediaPlayer(20430): Uri is <URL suppressed>
10-19 10:39:40.997: E/MediaPlayer(20430): error (1, -2147483648)
10-19 10:39:41.017: E/MediaPlayer(20430): Error (1,-2147483648)
10-19 10:39:41.017: D/VideoView(20430): Error: 1,-2147483648
EDIT: testing phone : Android 4.1 with 32Gb inbuilt memory and does not have Sdcard.
Answer for this is here
public String getRealPathFromURI(Uri contentUri) {
String[] proj = { MediaStore.Video.Media.DATA };
Cursor cursor = managedQuery(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
I had this same problem, went down many different paths to fix it, and what finally ended up working was the following code block:
/* inside onCreate */
VideoView videoView = (VideoView)findViewById(R.id.loginVideoBackground);
videoView.setVideoURI(Uri.parse("android.resource://" + this.getPackageName() + "/raw/lights"));
videoView.start();
I had previously tried:
Extending SurfaceView
using the answer given by #brinda above (which was resulting in a NullPointerException)
and various other permutations of StackOverflow answers
....sometimes simpler is better
/external/video/media/24363 is not correct, please check. local path must be visit..e.g. /sdcard/video/media/..
videoView.setVideoPath("http://www.ebookfrenzy.com/android_book/movie.mp4"); MediaController mediaController = new MediaController(this);
mediaController.setAnchorView(videoView);
videoView.setMediaController(mediaController);
videoView.start();
To be honest, I've experienced similar problems in the past and for each account, what I've ultimately found to be the best solution was to extend SurfaceView, directly. There is a surprisingly small amount of code to write and can easily (relatively speaking) be tailored efficiently to your requirements.
I'm running into a roadblock integrating music into my Android app. The goal is just to let users see & play songs to which they already have access, via Google Play Music (or any other player such as Winamp, Poweramp, doubleTwist, etc.).
So far, I've tried a couple of approaches, but each has problems.
Approach #1: Use a ContentResolver query to get playlists & songs from Google Play music, then play using MediaPlayer
First, get a cursor on the play lists:
String[] proj = { MediaStore.Audio.Playlists.NAME,
MediaStore.Audio.Playlists._ID };
Uri playlistUri = Uri.parse("content://com.google.android.music.MusicContent/playlists");
Cursor playlistCursor = getContentResolver().query(playlistUri, proj, null, null, null);
Then iterate to get the songs in each playlist, and read them like this:
String[] proj2 = { MediaStore.Audio.Playlists.Members.TITLE,
MediaStore.Audio.Playlists.Members._ID };
String playListRef = "content://com.google.android.music.MusicContent/playlists/" + playListId + "/members";
Uri songUri = Uri.parse(playListRef);
Cursor songCursor = getContentResolver().query(songUri, proj2, null, null, null);
This works to get the playlists and songs, but then you can't actually play them (even if you tell Google Play Music to "Keep on device"). Specifically, the following code does not play a given song found as above:
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mediaPlayer.setDataSource(dataPath);
mediaPlayer.prepare();
mediaPlayer.start();
} catch (Exception e) {}
In fact, I've scanned the device, and have not been able to find the files anywhere (even though I've confirmed they are local by fully disabling the network -- on both Galaxy Nexus and Galaxy S3).
Approach #2: Invoke Google Play Music, or other player, using an Intent
According to this post, you can simply invoke the player using Intents, like this:
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
File file = new File(YOUR_SONG_URI);
intent.setDataAndType(Uri.fromFile(file), "audio/*");
startActivity(intent);
But I don't think this approach allows for any kind of control -- for example, passing a specific song to be played, or being notified when a song is done being played. Furthermore, #CommonWares points out that the music app and its Intents are not part of the Android SDK's public API, and could change without warning.
The basic functionality I'm trying to achieve exists in iOS, thanks to tight integration with iTunes. I would think that Google would want to achieve the same kind of integration, since it could mean selling a lot more music in the Play store.
In Summary: Is it possible to let users see & play songs to which they already have access on Android? What's the best way to do this with Google Play Music, or any other app? Thanks.
Approach #1 kinda works (tested with local music on device), thanks OP for the direction.
Notes:
We're playing with an undocumented internal API here - it's not
reliable.
I don't have access to online/purchased music in Google
Play Music, so the answer refers to locally stored music only.
The code below will iterate on all songs in a playlist and play the last one.
Note the "SourceId" column - it's the audio id you'd use as per documentation.
I found it by iterating on all columns returned by the cursor.
There are several more interesting columns there, like "hasLocal", "hasRemote" which might (or not) refer to where the music is stored.
String[] proj2 = { "SourceId", MediaStore.Audio.Playlists.Members.TITLE, MediaStore.Audio.Playlists.Members._ID };
String playListRef = "content://com.google.android.music.MusicContent/playlists/" + playListId + "/members";
Uri songUri = Uri.parse(playListRef);
Cursor songCursor = getContentResolver().query(songUri, proj2, null, null, null);
long audioId = -1;
while (songCursor.moveToNext()) {
audioId = songCursor.getLong(songCursor.getColumnIndex("SourceId"));
String title = songCursor.getString(songCursor.getColumnIndex(MediaStore.Audio.Playlists.Members.TITLE));
Log.v("", "audioId: " + audioId + ", title: " + title);
}
songCursor.close();
MediaPlayer mpObject = new MediaPlayer();
try {
if (audioId > 0) {
Uri contentUri = ContentUris.withAppendedId(android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, Long.valueOf(audioId));
mpObject.setAudioStreamType(AudioManager.STREAM_MUSIC);
mpObject.setDataSource(this, contentUri);
mpObject.prepare();
mpObject.start();
}
} catch (Exception e) {
e.printStackTrace();
}