java - Android Shoutcast 互联网广播流媒体

标签 java android android-intent java-me streaming

我开发了 Shoutcastinternet Radio Streaming,我能够成功地进行流式传输和播放。

但问题是:当我执行我的应用程序时,我能够连续播放半小时,之后流停止(无法播放,之后如果我再次单击播放流继续一段时间后 FileNotFoundException)?

我在 Stream 停止后记录了错误。

错误是:

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

setupplayer() 中获取异常

源代码:

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);

    }

}

最佳答案

您应该调用release() 来释放资源。如果不发布,过多的MediaPlayer实例可能会导致异常

当你在 Service 上时写这段代码

已更新

private void releaseMediaPlayer() {
if (mediaPlayer != null) {
    if(mediaPlayer.isPlaying()) {
        mediaPlayer.stop();
    }
    mediaPlayer.release();
    mediaPlayer = null;
  }
}

@Override
protected void onDestroy() {
   super.onDestroy();
   releaseMediaPlayer();
}

可以看到this

关于java - Android Shoutcast 互联网广播流媒体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16248304/

相关文章:

android - appcompat-v7 与其他依赖项冲突

android - 如何检测创建 Activity 时已经存在的屏幕触摸?

java - 将后台应用程序置于前台

java - Android如何在手机重启时启动BroadcastReceiver

java - Netbeans 指责不存在的错误(我猜)

java - 无法使用 photoview 库缩放图像

java - OAuth2 使用本地用户数据库和身份验证保护 Spring Boot REST Api

android - 如何在android中实现html5

java - 在 Hibernate Search 中使用多个关键字进行索引搜索

java - 在处理 Intent 时如何使用 putExtra/get_Extra?