[英]Android Shoutcast internet Radio Streaming
I developed Shoutcastinternet
Radio Streaming and I'm able to stream and play Successfully. 我开发了
Shoutcastinternet
Radio Streaming,我能够成功地流式传输和播放。
But the problem is: when i execute my application,I'm able to stream and play Continuously for halfanhour,after that the stream is getting stopped(not able to play, after that if i click on again play the stream Continues and again after some time FileNotFoundException
)? 但问题是:当我执行我的应用程序时,我能够连续播放和播放半小时,之后流停止(无法播放,之后如果我再次点击播放流继续并再次播放之后一段时间
FileNotFoundException
)?
I logged the Error, after Stream
get stopped. 在
Stream
停止后我记录了错误。
The Error is : 错误是:
java.io.FileNotFoundException: /data/data/com.torilt/cache/downloadingMediaFile430 (No such file or directory)
Can't find file. Android must have deleted it on a clean up
Getting Exception in setupplayer()
在
setupplayer()
获取异常
Source Code: 源代码:
public class StreamingMediaPlayer extends Service {
final static public String AUDIO_MPEG = "audio/mpeg";
final static public String BITERATE_HEADER = "icy-br";
public int INTIAL_KB_BUFFER ;
private Handler handler;
//= 96*10/8
final public int BIT = 8;
final public int SECONDS = 60;
int bitrate = 56;
public File downloadingMediaFile;
final public String DOWNFILE = "downloadingMediaFile";
public Context context;
public int counter;
public int playedcounter;
public int preparecounter;
public MediaPlayer mp1;
public MediaPlayer mp2;
public boolean mp1prepared;
public boolean mp2prepared;
public boolean mp1preparing;
public boolean mp2preparing;
public boolean downloadingformp1;
public boolean downloadingformp2;
public boolean prepareState;
public String SONGURL = "";
// playing is "true" for mp1 and "false" for mp2
public boolean mp1playing;
public boolean started;
public boolean processHasStarted;
public boolean processHasPaused;
public boolean regularStream;
public BufferedInputStream stream;
public URL url;
public URLConnection urlConn;
public String station;
public String audiourl;
public Intent startingIntent = null;
public boolean stopping;
Thread preparringthread;
boolean waitingForPlayer;
// Setup all the variables
private void setupVars() {
counter = 0;
playedcounter = 0;
preparecounter = 0;
mp1 = new MediaPlayer();
mp2 = new MediaPlayer();
mp1prepared = false;
mp2prepared = false;
mp1preparing = false;
mp2preparing = false;
downloadingformp1 = false;
downloadingformp2 = false;
prepareState = true;
mp1playing = false;
started = false;
processHasStarted = false;
processHasPaused = true;
regularStream = false;
stream = null;
url = null;
urlConn = null;
station = null;
audiourl = null;
stopping = false;
preparringthread = null;
waitingForPlayer = false;
}
// This object will allow other processes to interact with our service
private final IStreamingMediaPlayer.Stub ourBinder = new IStreamingMediaPlayer.Stub() {
// String TAG = "IStreamingMediaPlayer.Stub";
public String getStation() {
// Log.d(TAG, "getStation");
return station;
}
public String getUrl() {
// Log.d(TAG, "getUrl");
return audiourl;
}
public boolean playing() {
// Log.d(TAG, "playing?");
return isPlaying();
}
public boolean pause() {
// Log.d(TAG, "playing?");
return isPause();
}
public void startAudio() {
// Log.d(TAG, "startAudio");
Runnable r = new Runnable() {
public void run() {
onStart(startingIntent, 0);
}
};
new Thread(r).start();
}
public void stopAudio() {
// Log.d(TAG, "stopAudio");
stop();
}
};
@Override
public void onCreate() {
super.onCreate();
context = this;
}
@Override
public void onStart(Intent intent, int startId) throws NullPointerException {
super.onStart(intent, startId);
// final String TAG = "StreamingMediaPlayer - onStart";
context = this;
setupVars();
if (intent.hasExtra("audiourl")) {
raiseThreadPriority();
processHasStarted = true;
processHasPaused = false;
audiourl = intent.getStringExtra("audiourl");
station = intent.getStringExtra("station");
downloadingMediaFile = new File(context.getCacheDir(), DOWNFILE+ counter);
downloadingMediaFile.deleteOnExit();
Runnable r = new Runnable() {
public void run() {
try {
startStreaming(audiourl);
} catch (IOException e) {
// Log.d(TAG, e.toString());
}
}
};
Thread t = new Thread(r);
t.start();
}
}
@Override
public void onDestroy() {
super.onDestroy();
mp1.stop();
mp2.stop();
}
@Override
public IBinder onBind(Intent intent) {
startingIntent = intent;
context = this;
return ourBinder;
}
@Override
public boolean onUnbind(Intent intent) {
super.onUnbind(intent);
stopSelf();
return true;
}
/**
* Progressivly download the media to a temporary location and update the
* MediaPlayer as new content becomes available.
*/
public void startStreaming(final String mediaUrl) throws IOException {
try {
url = new URL(mediaUrl);
urlConn = (HttpURLConnection) url.openConnection();
urlConn.setReadTimeout(1000 * 20);
urlConn.setConnectTimeout(1000 * 5);
//The getContentType method is used by the getContent method to determine the type of the remote object; subclasses may find it convenient to override the getContentType method.
String ctype = urlConn.getContentType();
if (ctype == null) {
ctype = "";
} else {
ctype = ctype.toLowerCase();
}
if (ctype.contains(AUDIO_MPEG) || ctype.equals("")) {
String temp = urlConn.getHeaderField(BITERATE_HEADER);
if (temp != null) {
bitrate = new Integer(temp).intValue();
}
} else {
stopSelf();
return;
}
}
catch(NullPointerException ne)
{
}
catch (IOException ioe) {
// Log.e(TAG, "Could not connect to " + mediaUrl);
stopSelf();
return;
}
if (!regularStream) {
INTIAL_KB_BUFFER = bitrate * SECONDS / BIT;
Runnable r = new Runnable() {
public void run() {
try {
downloadAudioIncrement(mediaUrl);
Log.i("TAG12344444", "Unable to play");
stopSelf();
return;
} catch (IOException e) {
Log.i("TAG123", "Unable to initialize the MediaPlayer for Audio Url = "+mediaUrl, e);
stopSelf();
return;
} catch (NullPointerException e) {
stopSelf();
return;
}
}
};
Thread t = new Thread(r);
t.start();
}
}
/**
* Download the url stream to a temporary location and then call the
* setDataSource for that local file
*/
public void downloadAudioIncrement(String mediaUrl) throws IOException{
int bufsizeForDownload = 8 * 1024;
int bufsizeForfile = 64 * 1024;
stream = new BufferedInputStream(urlConn.getInputStream(),bufsizeForDownload);
Log.i("bufsize",Integer.toString(urlConn.getInputStream().available()));
try{
if(stream == null || stream.available() == 0){
stopSelf();
Log.i("unable to create ","stream null");
return;
}
}catch (NullPointerException e) {
stopSelf();
Log.i("return1","return1");
return;
}
BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(downloadingMediaFile), bufsizeForfile);
byte buf[] = new byte[bufsizeForDownload];
int totalBytesRead = 0, totalKbRead = 0, numread = 0;
do {
if (bout == null) {
counter++;
downloadingMediaFile = new File(context.getCacheDir(), DOWNFILE+ counter);
downloadingMediaFile.deleteOnExit();
bout = new BufferedOutputStream(new FileOutputStream(downloadingMediaFile), bufsizeForfile);
}
try {
numread = stream.read(buf);
} catch (IOException e) {
Log.d("Downloadingfile", "Bad read. Let's quit.");
// stop();
Log.i("return2","return2");
stopSelf();
// return;
}
catch (NullPointerException e) {
// Let's get out of here
e.printStackTrace();
break;
}
if (numread < 0) {
bout.flush();
stopSelf();
Log.i("Bad read from stream", "Bad read from stream3");
if(stream == null){
urlConn = new URL(mediaUrl).openConnection();
urlConn.setConnectTimeout(1000 * 30);
urlConn.connect();
stream = new BufferedInputStream(urlConn.getInputStream(),bufsizeForDownload);
}else{
handler.post(new Runnable() {
public void run() {
Log.i("Bad read from stream", "Bad read from xyz");
context.stopService(startingIntent);
Log.i("return3","return3");
return;
}
});
}
} else if (numread >= 1) {
bout.write(buf, 0, numread);
totalBytesRead += numread;
totalKbRead += totalBytesRead / 1000;
}
if (totalKbRead >= INTIAL_KB_BUFFER && stopping != true) {
bout.flush();
bout.close();
bout = null;
if (started == false) {
Runnable r = new Runnable() {
public void run() {
setupplayer();
}
};
Thread t = new Thread(r);
t.start();
}
totalBytesRead = 0;
totalKbRead = 0;
}
if (stopping == true) {
stream = null;
}
} while (stream != null);
}
/** oncompletelister for media player **/
class listener implements MediaPlayer.OnCompletionListener {
public void onCompletion(MediaPlayer mp) {
waitingForPlayer = false;
long timeInMilli = Calendar.getInstance().getTime().getTime();
long timeToQuit = (1000 * 30) + timeInMilli; // add 30 seconds
if (mp1playing)
{
mp1.reset();
removefile();
mp1prepared = false;
// Log.d(TAG, "mp1 is Free.");
if (downloadingformp2) {
if (mp2preparing && stopping == false) {
waitingForPlayer = true;
}
while (mp2preparing && stopping == false) {
if (timeInMilli > timeToQuit) {
stopSelf();
}
timeInMilli = Calendar.getInstance().getTime().getTime();
}
}
} else {
mp2.reset();
removefile();
mp2prepared = false;
if (downloadingformp1) {
if (mp1preparing && stopping == false) {
waitingForPlayer = true;
}
while (mp1preparing && stopping == false) {
if (timeInMilli > timeToQuit) {
stopSelf();
}
timeInMilli = Calendar.getInstance().getTime().getTime();
}
}
}
if (waitingForPlayer == true) {
// we must have been waiting
waitingForPlayer = false;
}
if (stopping == false) {
if (mp1playing) {
mp2.start();
mp1playing = false;
Runnable r = new Runnable() {
public void run() {
setupplayer();
}
};
Thread t = new Thread(r);
t.start();
} else {
mp1.start();
mp1playing = true;
Runnable r = new Runnable() {
public void run() {
setupplayer();
}
};
Thread t = new Thread(r);
t.start();
}
}
}
}
/** OnPreparedListener for media player **/
class preparelistener implements MediaPlayer.OnPreparedListener {
public void onPrepared(MediaPlayer mp) {
if (prepareState) {
prepareState = false;
mp1preparing = false;
mp1prepared = true;
if (started == false) {
started = true;
mp1.start();
mp1playing = true;
Runnable r = new Runnable() {
public void run() {
setupplayer();
}
};
Thread t = new Thread(r);
t.start();
}
} else {
prepareState = true;
mp2preparing = false;
mp2prepared = true;
}
}
};
/**
* Set Up player(s)
*/
public void setupplayer() {
final String TAG = "setupplayer";
Runnable r = new Runnable() {
public void run() {
try {
if (!mp1preparing && !mp1prepared) {
while (true) {
downloadingformp1 = true;
if (started == false)
break;
if (counter > preparecounter)
break;
}
File f = new File(context.getCacheDir(), DOWNFILE+ preparecounter);
FileInputStream ins = new FileInputStream(f);
mp1.setDataSource(ins.getFD());
mp1.setAudioStreamType(AudioManager.STREAM_MUSIC);//playing for live streaming
mp1.setOnCompletionListener(new listener());
mp1.setOnPreparedListener(new preparelistener());
if (started == false || waitingForPlayer == true){
}
mp1.prepareAsync();// .prepare();
mp1preparing = true;
downloadingformp1 = false;
preparecounter++;
} else if (!mp2preparing && !mp2prepared) {
while (true) {
downloadingformp2 = true;
if (started == false)
break;
if (counter > preparecounter)
break;
}
File f = new File(context.getCacheDir(), DOWNFILE+ preparecounter);
FileInputStream ins = new FileInputStream(f);
mp2.setDataSource(ins.getFD());
mp2.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp2.setOnCompletionListener(new listener());
mp2.setOnPreparedListener(new preparelistener());
mp2.prepareAsync();
mp2preparing = true;
downloadingformp2 = false;
preparecounter++;
// }
} else
Log.d(TAG, "No Media player is available to setup.");
return;
} catch (FileNotFoundException e) {
Log.e(TAG, e.toString());
Log.e(TAG,"Can't find file. Android must have deleted it on a clean up ");
stop();
return;
} catch (IllegalStateException e) {
Log.e(TAG, e.toString());
stop();
} catch (IOException e) {
Log.e(TAG, e.toString());
stop();
}
}
};
preparringthread = new Thread(r);
preparringthread.start();
try {
preparringthread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void removefile() {
File temp = new File(context.getCacheDir(), DOWNFILE + playedcounter);
temp.delete();
playedcounter++;
}
public boolean stop() {
final String TAG = "STOP";
stopping = true;
try {
if (mp1.isPlaying()){
if (!(stream == null)) {
Log.i("IN STOP", "MP1 is nill");
stopSelf();
}
mp1.stop();
}
if (mp2.isPlaying()){
Log.i("IN STOP", "MP2 is nill");
if (!(stream == null)){
stopSelf();
}
mp2.stop();
}
} catch (Exception e) {
Log.e(TAG, "error stopping players");
}
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
Log.e(TAG, "error closing open connection");
}
}
stream = null;
processHasStarted = false;
processHasPaused = true;
if (preparringthread != null) {
preparringthread.interrupt();
}
stopSelf();
return true;
}
public boolean isPlaying() {
return processHasStarted;
}
public boolean isPause() {
return processHasPaused;
}
private void raiseThreadPriority() {
Process.setThreadPriority(Process.THREAD_PRIORITY_AUDIO);
}
}
you should call release()
, to free the resources. 你应该调用
release()
来释放资源。 If not released, too many MediaPlayer instances may result in an exception 如果未释放,则过多的MediaPlayer实例可能会导致异常
Write this code when on youe Service
在您的
Service
上写下此代码
Updated 更新
private void releaseMediaPlayer() {
if (mediaPlayer != null) {
if(mediaPlayer.isPlaying()) {
mediaPlayer.stop();
}
mediaPlayer.release();
mediaPlayer = null;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
releaseMediaPlayer();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.