Java 使用AACDecoder启动新流
我正在做一个无线电应用程序(像调音一样) 情况:Java 使用AACDecoder启动新流,java,android,oop,android-mediaplayer,audiotrack,Java,Android,Oop,Android Mediaplayer,Audiotrack,我正在做一个无线电应用程序(像调音一样) 情况: 当收音机首先启动时,它播放音频广告,然后启动收音机(广告和收音机是两个不同的流) 当AACPlayer当前正在播放音乐且用户更改电台时 两个问题: 当广告结束时,AACPlayer需要停止并使用另一个URL开始 当用户选择另一个收音机时,它是相同的 对于AACDecoder库,只有两种方法 -开始() -停止() 这些方法可能相互干扰,使玩家处于不确定状态 我使用以下代码启动播放机: public void start(String u
- 当收音机首先启动时,它播放音频广告,然后启动收音机(广告和收音机是两个不同的流)
- 当AACPlayer当前正在播放音乐且用户更改电台时
- 当广告结束时,AACPlayer需要停止并使用另一个URL开始
- 当用户选择另一个收音机时,它是相同的
我使用以下代码启动播放机:
public void start(String url) throws Exception {
if (mPlayer == null) {
mPlayer = new MultiPlayer(this);
}
mPlayer.playAsync(url);
mState = StreamingState.PREPARING;
}
就这样停下来:
public void stop() {
if (mPlayer == null) {
return;
}
try {
mPlayer.stop();
mPlayer = null;
} catch (Exception e) {
}
setState(StreamingState.STOPPING);
}
我使用这个回调接口:
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);
}
我用这个枚举更新播放器的状态:
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
}
我找不到一个解决方案,在保护播放机状态的同时,对已经在播放流的播放机执行停止()->启动(url)(我必须考虑网络延迟)
我怎样才能做到这一点
编辑
以下是如何完成工作的快速视图:
[PlayerActivity->流化服务->PlayerObject]
为了:
单击按钮play->call method play Radio from StreamingService,通过从serviceConnection获取的实例->call method play from PlayerObject->playerState=starting->method playerStarted auto called->playerState=started->callback method from StreamingService->广播意图以通知UI->UI获取意图并更新接口
这是广播接收机:
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) {
}
}
};
有时我会遇到这样的例外:
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)
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)
我认为应该通过回调函数来完成,playercallback接口可以在这里找到: AACPlayer本身的功能是:
/**
* Sets the PlayerCallback.
* NOTE: this should be set BEFORE any of the play methods are called.
*/
public void setPlayerCallback( PlayerCallback playerCallback )
当播放器停止时,执行此功能:
/**
* 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 );
只需将重新启动逻辑放入此函数中
链接到aacPlayer的源:
编辑1
有一个指向使用aacPlayer的活动源的链接:
您应该注意,在回调函数中使用了一个处理程序,代码在单独的线程中执行,而不是在players线程中执行:
public void playerStopped( final int perf ) {
uiHandler.post( new Runnable() {
public void run() {
enableButtons();
...
playerStarted = false;
}
});
}
有时我会遇到这样的例外:
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)
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)
编辑2
链接到Similar问题:
如果mPlayer.playanc(url);在开始和结束时返回任何值,然后您可以使用该值在结束广告时启动另一个url。您可以指定实际问题是什么吗?据我所知,你们曾问过如何在前一个流停止时启动流?现在,您要求在不提供源代码的情况下调试代码?异常是我的问题的原因。关于这个问题,AAC库相当不稳定,它只提供start和stop方法,没有任何异常。此外,不可能“重置玩家”,因为选项有限,所以问题更多的是算法。在问题中,我指定了“保护播放器的状态。我也不能发布我所有的代码。这太多了,我只是粘贴了相关部分。如果异常是一个问题:谢谢,我将尝试从回调中获取音轨,并将其关闭在桌面上…不是很干净,但如果这样做有效(~ ̄△ ̄)〜我使用回调查看我的编辑。在playerStopped中重新启动播放机可能有风险,你不认为吗?我不确定我们在这里讨论的是同一个回调,我不认为你的回调正在实现
com.spoledge.aacplayer.PlayerCallback
,因此,如果播放机停止,将不会收到通知。上面提到的回调就是其中的一部分库并在播放机状态更改时得到通知,因此播放()不同的url是没有问题的。当您收到关于停止的通知时,我将在我的对象播放机中实现com.spoledge.aacplayer.PlayerCallback,然后我的回调接口向我的服务提供反馈,然后在播放机实际停止停止时执行playerStopped函数()函数只是告诉玩家线程开始停止,并在完成染色后通知回调。知道我用playerStarted阻止按钮,并用playerStopped启用按钮。但当我这么做太快太多次(大约10-15次)时,玩家会给我一个异常,我无法从库中捕捉到。