1

I'm doing a radio Application (Tune In like)

The situations :

  • When the radio start at first it play an audio AD and then start the radio (AD and radio are 2 diferents streams)
  • When a AACPlayer is currently playing music and the user change station

Two problems :

  • When the ad finish the AACPlayer need to stop and start with another URL
  • When the user select another radio it is the same

With the AACDecoder library there are only two methods - start() - stop()

Those methods can interfere with each other and get the player in an indeterminate state


I start a player with this code :

public void start(String url) throws Exception {
    if (mPlayer == null) {
        mPlayer = new MultiPlayer(this);
    }
    mPlayer.playAsync(url);
    mState = StreamingState.PREPARING;
}

and stop it like this :

public void stop() {
    if (mPlayer == null) {
        return;
    }
    try {
        mPlayer.stop();
        mPlayer = null;
    } catch (Exception e) {
    }
    setState(StreamingState.STOPPING);
}

I use this callback interface :

static interface RadioPlayerCallBack {
    public void radioPlayerStarted();
    public void radioPlayerStopped(int perf);
    public void radioPlayerException(Throwable e);
    public void radioPlayerMetadata(String key, String value);
    public void radioPlayerPCMFeedBuffer(boolean isPlaying, int audioBufferSizeMs, int audioBufferCapacityMs);
}

and i update the state of the player with this enum :

public enum StreamingState {
    EMPTY, // media player rested or releasedS
    CREATED, // created ready to prepare
    PREPARING, // preparing...
    PREPARED, // prepared
    STARTED, // started, and maybe playing (ready to play)
    PAUSED, // paused (media player ready!)
    STOPPED, // stopped and not prepared to play
    ERROR, // an error occured, mediaplayer is reseted
    STOPPING, // startAsync after stop
}

I can't find a solution to do Stop() -> start(url) on a player that is already playing a stream, while securing the state of the player (i must take the latency of the network in account)

How can i achieve that ?

EDIT

Here is a quick view of how things are done :

[PlayerActivity -> StreamingService -> PlayerObject]

In order :

Click on button play -> call method playRadio from StreamingService through the instance got from serviceConnection-> call method play from PlayerObject-> playerState=starting -> method playerStarted auto-called -> playerState=started -> callback method from StreamingService -> broadcast an intent to inform UI -> ui get the intent and update interface...

Here is the BroadcastReceiver :

final private BroadcastReceiver mPlayBackReceiver       = new BroadcastReceiver() {

                                                            @Override
                                                            public void onReceive(Context context, Intent intent) {
                                                                String actionString = intent.getAction();
                                                                if (actionString == ServiceStreaming.SERVICE_PLAY) {
                                                                } else if (actionString == ServiceStreaming.SERVICE_STOP) {
                                                                } else if (actionString == ServiceStreaming.SERVICE_LOADING) {
                                                                } else if (actionString == ServiceStreaming.SERVICE_ERROR) {
                                                                } else if (actionString == ServiceStreaming.SERVICE_KILLED) {
                                                                }
                                                            }
                                                        };

Somethimes i get this exception :

06-04 10:15:43.531: E/AudioTrack(8218): AudioFlinger could not create track, status: -12
06-04 10:15:43.531: E/AudioTrack-JNI(8218): Error initializing AudioTrack
06-04 10:15:43.531: E/android.media.AudioTrack(8218): Error code -20 when initializing AudioTrack.
06-04 10:15:43.531: E/PCMFeed(8218): error in playback feed: -3
06-04 10:15:43.541: E/BufferReader(8218): Exception when reading: java.net.SocketException: Socket closed
06-04 10:15:43.901: A/libc(8218): Fatal signal 11 (SIGSEGV) at 0x76652748 (code=1), thread 8955 (Thread-5266)
06-04 10:15:43.911: E/AACPlayer(8218): playAsync():
06-04 10:15:43.911: E/AACPlayer(8218): java.lang.IllegalStateException
06-04 10:15:43.911: E/AACPlayer(8218):  at com.spoledge.aacdecoder.Decoder.start(Decoder.java:231)
06-04 10:15:43.911: E/AACPlayer(8218):  at com.spoledge.aacdecoder.AACPlayer.playImpl(AACPlayer.java:424)
06-04 10:15:43.911: E/AACPlayer(8218):  at com.spoledge.aacdecoder.AACPlayer.play(AACPlayer.java:386)
06-04 10:15:43.911: E/AACPlayer(8218):  at com.spoledge.aacdecoder.AACPlayer.play(AACPlayer.java:338)
06-04 10:15:43.911: E/AACPlayer(8218):  at com.spoledge.aacdecoder.AACPlayer$1.run(AACPlayer.java:296)
06-04 10:15:43.911: E/AACPlayer(8218):  at java.lang.Thread.run(Thread.java:841)
An-droid
  • 6,433
  • 9
  • 48
  • 93
  • If mPlayer.playAsync(url); returns any value on start & on finish then you can use that value for starting another url on finishing ad. – VVB Jul 17 '14 at 13:47
  • Can you specify what is your actual question ? from my understanding you have asked how to start stream when previous one have stopped ? now you are asking to debug your code without giving sources ? – firegnom Jul 22 '14 at 08:28
  • The exception is the cause of my question. The AAC lib is pretty instable concerning this matter, it only gives start and stop methods without any exceptions catching. Also it is not possible to "reset a player" the options are limited so the question is more about Algorithmic. In the question i specified "securing the state of the player. Also I can't post all my code this is too much, i just pasted the relevant parts – An-droid Jul 22 '14 at 08:44
  • if exception is a problem : http://stackoverflow.com/questions/17527996/android-application-crashes-after-generating-an-audio-signal-a-few-times – firegnom Jul 22 '14 at 09:09
  • thanks i'll try to get the audiotrack from the callbacks and close it in onStopped... not really clean but well if this works (〜 ̄△ ̄)〜 – An-droid Jul 22 '14 at 09:24

1 Answers1

1

I think it should be done by callback function playercallback interface can be found here:

https://code.google.com/p/aacplayer-android/source/browse/trunk/src/com/spoledge/aacplayer/PlayerCallback.java

and the function in AACPlayer itself is :

/**
 * Sets the PlayerCallback.
 * NOTE: this should be set BEFORE any of the play methods are called.
 */
public void setPlayerCallback( PlayerCallback playerCallback )

then when player stops this function is executed:

/**
 * This method is called when the player is stopped.
 * Note: __after__ this method the method playerException might be also called.
 */
public void playerStopped( int perf );

just put your restarting logic inside this function.

link to sources of aacPlayer:

https://code.google.com/p/aacplayer-android/source/browse/trunk/src/com/spoledge/aacplayer/AACPlayer.java

EDIT 1

there is a link to source of Activity using aacPlayer : https://code.google.com/p/aacplayer-android/source/browse/trunk/src/com/spoledge/aacplayer/AACPlayerActivity.java

You should notice that in callback function a Handler is used and a code is executed in separate thread not executed in players thread:

public void playerStopped( final int perf ) {
    uiHandler.post( new Runnable() {
        public void run() {
            enableButtons();
            ...
            playerStarted = false;
        }
    });
}

Somethimes i get this exception :

06-04 10:15:43.531: E/AudioTrack(8218): AudioFlinger could not create track, status: -12
06-04 10:15:43.531: E/AudioTrack-JNI(8218): Error initializing AudioTrack
06-04 10:15:43.531: E/android.media.AudioTrack(8218): Error code -20 when initializing AudioTrack.
06-04 10:15:43.531: E/PCMFeed(8218): error in playback feed: -3
06-04 10:15:43.541: E/BufferReader(8218): Exception when reading: java.net.SocketException: Socket closed
06-04 10:15:43.901: A/libc(8218): Fatal signal 11 (SIGSEGV) at 0x76652748 (code=1), thread 8955 (Thread-5266)
06-04 10:15:43.911: E/AACPlayer(8218): playAsync():
06-04 10:15:43.911: E/AACPlayer(8218): java.lang.IllegalStateException
06-04 10:15:43.911: E/AACPlayer(8218):  at com.spoledge.aacdecoder.Decoder.start(Decoder.java:231)
06-04 10:15:43.911: E/AACPlayer(8218):  at com.spoledge.aacdecoder.AACPlayer.playImpl(AACPlayer.java:424)
06-04 10:15:43.911: E/AACPlayer(8218):  at com.spoledge.aacdecoder.AACPlayer.play(AACPlayer.java:386)
06-04 10:15:43.911: E/AACPlayer(8218):  at com.spoledge.aacdecoder.AACPlayer.play(AACPlayer.java:338)
06-04 10:15:43.911: E/AACPlayer(8218):  at com.spoledge.aacdecoder.AACPlayer$1.run(AACPlayer.java:296)
06-04 10:15:43.911: E/AACPlayer(8218):  at java.lang.Thread.run(Thread.java:841)

edit 2

link to simmilar questions:

Android Application crashes after generating an audio signal a few times

AudioFlinger could not create track. status: -12

Community
  • 1
  • 1
firegnom
  • 833
  • 7
  • 20
  • I use callbacks see my edit. Restart the player in playerStopped could be risky don't you think ? – An-droid Jul 21 '14 at 12:21
  • I am not exactly sure if we are talking about the same callback here i don't think your callback is implementing `com.spoledge.aacplayer.PlayerCallback` so it won't be notified if player stops . the callback mentioned above is part of this library and is notified whenever player state is changed , so there is no problem to play() different url when u are notified about stop – firegnom Jul 21 '14 at 13:42
  • i implement com.spoledge.aacplayer.PlayerCallback in my Object player, then my callback Interface gives feedback to my service – An-droid Jul 21 '14 at 13:57
  • then playerStopped function is executed when player actually stoped stop() function is only telling player thread to start stopping and notify callback when finished – firegnom Jul 21 '14 at 14:25
  • Yes. Knowing that i block the buttons with playerStarted and enable them with playerStopped. But when i do it fast and too many times (around 10-15) the player gives me an exception that i can't catch from inside the lib. – An-droid Jul 21 '14 at 14:32
  • First of all if you have an exception you probably should post that exception in the question , this should help answering your question .Secondly u should not execute start() in callbacs thread you should create new one or execute it in ui thread see EDIT 1 – firegnom Jul 21 '14 at 18:21
  • Unfortunatly my app is a bit more complicated than the example. I can't really use it. See my edit – An-droid Jul 22 '14 at 08:04
  • I accept your answer since i don't think we can add more indormations to this issue (for now) thanks for the help o/ – An-droid Jul 23 '14 at 09:35