2

I'm using MediaPlayer to load an mp3 file and play it online. I am using this code:

try{
    Log.i("tag1", "try");
    mediaPlayer.setDataSource(activity.this, Uri.parse("link"));
    mediaPlayer.prepareAsync();
    mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mediaPlayer) {
            Log.i("tag2", "" + mediaPlayer.getDuration());
        }
    });
    } catch(IOException e) {
    e.printStackTrace();
}

Most of the times nothing is prepared, so I have the log.i results as below:

tag1 = try

tag2 is never executed

If, sometimes only, mediaPlayer is prepared, I get these logs:

tag1 = try

tag2 = 0 _ which is neither acceptable nor usable

Also, when I call mediaPlayer.setOnErrorListener, I get errors 1,-1004 or 1,-2147483648. Additionally, mediaPlayer.setOnInfoListener gives nothing; I think it's never called...

What could be the problem?

It is not unnecessary to mention that in the log folder of the server's file manager, I found this: "stagefright/1.2 (Linux; Android 4.4.4)". I think this could help to solve the problem. Also, related to this, can the problem be caused by PHP extensions? if yes, activating which extension solves this issue?


Any help is really appreciated.

elyar abad
  • 771
  • 1
  • 8
  • 27
  • what do you expect with such `Uri`: `Uri.parse("link")`? what actually to you want to play? – pskink Jan 04 '20 at 07:28
  • @pskink I need to play an mp3, online. like soundcloud, but in the app . . . – elyar abad Jan 04 '20 at 07:40
  • @pskink yeah, the `link` is some path toward server host, where the mp3 file is located . . . – elyar abad Jan 04 '20 at 09:24
  • 1
    tried `setOnErrorListener`? if so, what are `int what` and `int extra` in `onError` callback? also check `setOnInfoListener` too – pskink Jan 04 '20 at 09:27
  • @pskink my friend; there's nothing on onInfo. however, onError returns `1,-1004` or `1,-2147483648`. – elyar abad Jan 04 '20 at 10:32
  • so check in the official documentation what `-1004` error means – pskink Jan 04 '20 at 10:57
  • @pskink I did not find any details for such an error – elyar abad Jan 04 '20 at 13:48
  • 1
    Call `setOnPreparedListener` *before* calling `prepareAsync`. – selbie Jan 06 '20 at 07:28
  • 1
    I'm sure you've seen this, but in case not: Here is a very helpful flowchart of the MediaPlayer state machine. If you divert from this, you gonna run into problems: https://image.slidesharecdn.com/mediaplayer-110716092828-phpapp02/95/android-media-player-9-728.jpg?cb=1310809360 – muetzenflo Jan 10 '20 at 11:01
  • Dear @muetzenflo, Thanks! I obey those steps. The problem is the `onPrepare` does not prepare or prepares incompletely... so the media is not playable or, at least, the `getDuration` returns 0. – elyar abad Jan 10 '20 at 12:13
  • Sometimes the MediaPlayer isnt able to play files of certain sizes or formats, depending on what device you actually use (had that problem before). You mentioned Soundcloud and as far as I know, many of the files there are very large, like a few hours. Have you tried using different files to maybe narrow down the possible problems? – Benjamin Basmaci Jan 12 '20 at 13:56
  • @selbie, Although I tried your precious suggestion, I still think you are kind of kidding. :) Thanks so much – elyar abad Jan 12 '20 at 14:00
  • @BenjaminBasmaci I really appreciate you very help. I believe the rumors about `mediaPlayer`'s inherent lacks are not completely true except its loading duration which is more than ExoPlayer . . . Since It worked well for me and this issue happend suddenly from nowhere . .. – elyar abad Jan 12 '20 at 14:02
  • 1
    Have you tried downloading the file first and then using it instead of straight out streaming it? Also, have you tried other files with maybe different codecs? – Benjamin Basmaci Jan 12 '20 at 14:06
  • @BenjaminBasmaci, I did the latter. The first one, which I had in mind too, does not fit my case . . . – elyar abad Jan 12 '20 at 14:07
  • 1
    You should still try it though, just to narrow the room for error to make it easier to pinpoint the actual problem. Because, If downloading it beforehand makes it work, then you know the problem lies within the streaming. If it doesn't help, you know its either your implementation or the file. Always make your problems as small as possible – Benjamin Basmaci Jan 12 '20 at 14:09
  • @BenjaminBasmaci, The trouble is with STREAMING. I tried local files . . . – elyar abad Jan 12 '20 at 14:12
  • 1
    I wasn't kidding. I have an app in the store that uses MediaPlayer. Feel free to visit [the code here](https://github.com/jselbie/wrekonline/blob/master/app/src/main/java/com/selbie/wrek/MediaPlayerPresenter.java): – selbie Jan 12 '20 at 20:22
  • @selbie, good job. But I don't think "Calling `setOnPreparedListener` before calling `prepareAsync`" can be a logical solution. However I tried it. thanks,,, – elyar abad Jan 13 '20 at 05:55
  • Just in case `prepareAsync` completes before your code had a chance to set a callback. – selbie Jan 13 '20 at 05:56
  • @selbie, It just worked well in the existing order of codes. this issue was a sudden stuff. Also `setOnPreparedListener` is a listener; just acts when `prepareAsync` is prepared. – elyar abad Jan 13 '20 at 06:00

4 Answers4

2

You have a MEDIA_ERROR_IO. As the documentation says it's for File or network related operation errors.

In most cases the problem is in the implementation of the MediaPlayer class or maybe in android 4 as mentioned here

I would recommend you ExoPlayer, instead.

elyar abad
  • 771
  • 1
  • 8
  • 27
Ezaldeen sahb
  • 719
  • 7
  • 12
  • Thanks my friend! I'm trying several suggestions; among them, ExoPlayer... – elyar abad Jan 10 '20 at 19:38
  • Could you, please, introduce a suitable tutorial source for a ExoPlayer? I just need a simple one for a mp3 player... I need it to be short and to the point. I thank you so much . . . – elyar abad Jan 12 '20 at 12:03
  • 1
    sure, there's no better place than google codelabs itself, you can start from here https://codelabs.developers.google.com/codelabs/exoplayer-intro/index.html?index=..%2F..index#0 – Ezaldeen sahb Jan 12 '20 at 16:53
  • thanks! I think I should change my host provider to give a try to another service, no solution works . . . – elyar abad Jan 13 '20 at 14:05
1

You are missing mediaPlayer.start() in your MediaPlayer.OnPreparedListener(). See attached kotlin code for an extending class with example http request

Error 1004: Source not found (f.e. wrong path or no stream at url)

Error 2147483648: Media format not supported at your device

Another mention: keeping references for audiofiles on device system needs persistable uri permission

Here's stripped down code for starting a radio stream in kotlin with OkHttp

class MyPlayer: MediaPlayer(), MediaPlayer.OnPreparedListener {

  fun playStream() {
    try {
        val uri = Uri.parse( [URL] )

        //check if url valid
        val client = OkHttpClient()
        val request = Request.Builder().url( [URL] ).build()
        val newCall = client.newCall(request).execute()
        if (newCall.code() != 200) {
            //handle error for stream, stream not broadcasting
            return
        }

        val headers = HashMap<String, String>()
        headers.put("User-Agent", " [SOME AGENT] ")
        setDataSource(context, uri, headers)

        prepareAsync()

    } catch (e: Exception) {
        L.e("Url Parsing failed for ${e.message}")
        setInternalState(State.Error, StreamErrorMapping.ShoutCastError)
    }
  }
}

override fun onPrepared(player: MediaPlayer) {
    player.start()  //<-- this call is missing in your code
}

By the way, like Ezaldeenn sahb already mentioned, I would also recommend using ExoPlayer, since it's way more faster than MediaPlayer! In my projects buffering went down from 2-4seconds (MediaPlayer) to 200ms (Exoplayer). Happy coding

longi
  • 11,104
  • 10
  • 55
  • 89
  • I Thank you for you help. How is it possible to `start` a `mediaPlayer` while the `onPrepare` does not response or responds odd? I have used `.start()` in my code, where the play button takes action, which induces the issue. However, here, I've just brought the `logi` of my codes to show the errors. – elyar abad Jan 10 '20 at 12:22
  • Could you, please, introduce a suitable tutorial source for a ExoPlayer? I just need a simple one for a mp3 player... – elyar abad Jan 12 '20 at 12:04
  • 1
    This is another question, but here s all you need: https://github.com/google/ExoPlayer – longi Jan 13 '20 at 13:31
  • 1
    You cannot call `start()` if `onPrepared()` wasn't called. If onPrepared isn't called, something is wrong with your media source or format – longi Jan 13 '20 at 13:39
  • yeah, I'm trying to change my host . . . , plenty of stuff to do... – elyar abad Jan 13 '20 at 14:03
1

It seems your problem is because of using http links instead of https. Add android:usesCleartextTraffic="true" to your manifest application tag like so:

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:usesCleartextTraffic="true"
    android:theme="@style/AppTheme"
    >
      ...

</application>

Also, don't forget to use internet permission.

Squti
  • 4,171
  • 3
  • 10
  • 21
0

Of course, I thank all my friends who put their most effort to answer this problem of mine, but none of them solved the main issue.

How I came to find a way to get rid of this situation:

I tried another Host for my files and it worked. So I decided to move all my data and databases to another Host.

elyar abad
  • 771
  • 1
  • 8
  • 27