Search code examples
javaandroidmobilestreamingmedia-player

how can i get a shoucast stream to start playing almost instantly


I am still fixing my radio app and it is going well and you guys have been great at helping as a resource!!

One thing that I (and my end client) have been worried about is that the stream takes 30 seconds to 45 seconds (wifi vs cell networks vs location mobile user is at) for the stream to start playing.

They are using shoutcast as a services and I pull the streams from their shoutcast account. The streams are MP3s.

Is there a way to make it so that a few seconds after play button is pressed, the stream starts playing???

Here is my code:

import android.annotation.TargetApi;
import android.app.Activity;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.SeekBar;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import java.io.IOException;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;

import static com.javacodegeeks.androidmediaplayerexample.R.string.app_name;

public class AndroidMediaPlayerExample extends Activity  implements AdapterView.OnItemSelectedListener, MediaPlayer.OnPreparedListener {

    private MediaPlayer mediaPlayer;
    public TextView songName, duration;
    private double timeElapsed = 0, finalTime = 0;
    private int forwardTime = 2000, backwardTime = 2000;
    private Handler durationHandler = new Handler();
    private SeekBar seekbar;
    //String url = "http://radio.miraath.net:7000";
    //String url = new String[]{"http://radio.miraath.net:7000", "http://radio.miraath.net:7010", "http://radio.miraath.net:7020", "http://radio.miraath.net:7030","http://radio.miraath.net:7040", };
    String url;
    TextView radioInfo;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //set the layout of the Activity
        setContentView(R.layout.activity_main);
        Spinner dropdown = (Spinner)findViewById(R.id.spinner1);
        String[] items = new String[]{"الإذاعة الرئيسية", "الاذاعة الثانية", "إذاعة القرآن الكريم", "Miraath's English Radio", "إذاعة المجالس التأصيلية", "إذاعة دورة حفر الباطن"};
        String [] radioDescription = new String[]{" الإذاعة الرئيسية: لموقع ميراث الأنبياء ،تسهر على بث الدروس العلمية لكبار العلماء وطلبة العلم، والتلاوات القرآنية على مدار الساعة. " , "الاذاعة الثانية تنقل الدروس المتعارضة مع الاذاعة الرئيسية و تعمل وقت الدروس فقط. " , "إذاعة ميراث الأنبياء للقرآن الكريم: بث لتلاوات مختارة من القرآن الكريم لمختلف القراء " , "Ensures the broadcast of Islamic lessons from the leading Scholars and proficient students, and recitations of Quran around the Clock" , "إذاعة خاصة ببث دروس مجالس ميراث الأنبياء التأصيلية، تعمل فقط وقت الدروس المباشرة حسب ما هو مبين بالجدول في الموقع " , "إذاعة خاصة ببث دروس دورة حفر الباطن، تعمل فقط وقت الدروس المباشرة حسب ما هو مبين بالجدول في الموقع " };
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, items);
        dropdown.setAdapter(adapter);
        dropdown.setOnItemSelectedListener(this);
        int channel = Arrays.asList((getResources().getStringArray(R.array.radios_array))).indexOf(getString(app_name));

        //initialize views
        initializeViews();
    }

    public void initializeViews(){
        songName = (TextView) findViewById(R.id.songName);
        radioInfo = (TextView) findViewById(R.id.radioInfo);
        mediaPlayer = new MediaPlayer();
        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        finalTime = mediaPlayer.getDuration();
        //duration = (TextView) findViewById(R.id.songDuration);
        seekbar = (SeekBar) findViewById(R.id.seekBar);
        songName.setText("Miraath.net Radio");

        seekbar.setMax((int) finalTime);
        seekbar.setClickable(false);
    }

    public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
        //mediaPlayer.release();

        switch (position) {

            case 0:
                // Whatever you want to happen when the first item gets selected
                //mediaPlayer.release();
                url = "http://radio.miraath.net:7000";
                radioInfo.setText("الإذاعة الرئيسية: لموقع ميراث الأنبياء ،تسهر على بث الدروس العلمية لكبار العلماء وطلبة العلم، والتلاوات القرآنية على مدار الساعة");
                Toast.makeText(getApplicationContext(), url, Toast.LENGTH_LONG).show();
                break;
            case 1:
                // Whatever you want to happen when the second item gets selected
                //mediaPlayer.release();
                url = "http://radio.miraath.net:7010";
                radioInfo.setText("الاذاعة الثانية تنقل الدروس المتعارضة مع الاذاعة الرئيسية و تعمل وقت الدروس فقط");
                Toast.makeText(getApplicationContext(), url, Toast.LENGTH_LONG).show();
                break;
            case 2:
                // Whatever you want to happen when the thrid item gets selected
                //mediaPlayer.release();
                url = "http://radio.miraath.net:7020";
                radioInfo.setText("إذاعة ميراث الأنبياء للقرآن الكريم: بث لتلاوات مختارة من القرآن الكريم لمختلف القراء");
                Toast.makeText(getApplicationContext(), url, Toast.LENGTH_LONG).show();
                break;
            case 3:
                // Whatever you want to happen when the thrid item gets selected
                //mediaPlayer.release();
                url = "http://radio.miraath.net:7040";
                radioInfo.setText("Ensures the broadcast of Islamic lessons from the leading Scholars and proficient students, and recitations of Quran around the Clock");
                Toast.makeText(getApplicationContext(), url, Toast.LENGTH_LONG).show();
                break;
            case 4:
                // Whatever you want to happen when the thrid item gets selected
                //mediaPlayer.release();
                url = "http://radio.miraath.net:7030";
                radioInfo.setText("إذاعة خاصة ببث دروس مجالس ميراث الأنبياء التأصيلية، تعمل فقط وقت الدروس المباشرة حسب ما هو مبين بالجدول في الموقع");
                Toast.makeText(getApplicationContext(), url, Toast.LENGTH_LONG).show();
                break;
            case 5:
                // Whatever you want to happen when the thrid item gets selected
                //mediaPlayer.release();
                url = "http://radio.miraath.net:8010";
                radioInfo.setText("إذاعة خاصة ببث دروس دورة حفر الباطن، تعمل فقط وقت الدروس المباشرة حسب ما هو مبين بالجدول في الموقع");
                Toast.makeText(getApplicationContext(), url, Toast.LENGTH_LONG).show();
                break;
        }

    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {

    }

    // play mp3 song
    public void play(View view)
    {
        if (!mediaPlayer.isPlaying())
        {
            Toast.makeText(getApplicationContext(), "Radio selected. Buffering Now...", Toast.LENGTH_LONG).show();
            Toast.makeText(getApplicationContext(), "This may take a few moments. Please wait ...", Toast.LENGTH_LONG).show();
        }

        duration = (TextView) findViewById(R.id.songDuration);
        try
            {
                if (mediaPlayer.isPlaying())
                {
                    mediaPlayer.stop();
                    mediaPlayer.reset();
                    //mediaPlayer.release();
                    mediaPlayer.setDataSource(url);
                    mediaPlayer.setOnPreparedListener(this);
                    mediaPlayer.prepareAsync();
                }

                else if (!mediaPlayer.isPlaying()) {
                    mediaPlayer.setDataSource(url);
                    mediaPlayer.setOnPreparedListener(this);
                    mediaPlayer.prepareAsync();
                }
            }

            catch (IllegalArgumentException e)
            {
                Toast.makeText(getApplicationContext(), "Radio not Available. Please try again Later.", Toast.LENGTH_LONG).show();

            } catch (SecurityException e) {
                Toast.makeText(getApplicationContext(), "Radio not Available. Please try again Later.", Toast.LENGTH_LONG).show();

            } catch (IllegalStateException e) {
                Toast.makeText(getApplicationContext(), "Radio not Available. Please try again Later.", Toast.LENGTH_LONG).show();

            } catch (IOException e) {
                e.printStackTrace();
            }

    }

    //handler to change seekBarTime
    private Runnable updateSeekBarTime = new Runnable() {
        @TargetApi(Build.VERSION_CODES.GINGERBREAD)
        public void run() {
            //get current position
            timeElapsed = mediaPlayer.getCurrentPosition();
            //set seekbar progress
            seekbar.setProgress((int) timeElapsed);
            //set time remaing
            double timeRemaining = finalTime - timeElapsed;
            duration.setText(String.format("%d min, %d sec", TimeUnit.MILLISECONDS.toMinutes((long) timeRemaining), TimeUnit.MILLISECONDS.toSeconds((long) timeRemaining) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes((long) timeRemaining))));
            //repeat yourself that again in 100 miliseconds
            durationHandler.postDelayed(this, 100);
        }
    };

    // pause mp3 song
    public void pause(View view) {

        Toast.makeText(getApplicationContext(), "Audio Paused ...", Toast.LENGTH_LONG).show();
        mediaPlayer.reset();
    }

    // go forward at forwardTime seconds
    public void forward(View view) {
        //check if we can go forward at forwardTime seconds before song endes
        if ((timeElapsed + forwardTime) <= finalTime) {
            timeElapsed = timeElapsed + forwardTime;

            //seek to the exact second of the track
            mediaPlayer.seekTo((int) timeElapsed);
        }
    }

    // go backwards at backwardTime seconds
    public void rewind(View view) {
        //check if we can go back at backwardTime seconds after song starts
        if ((timeElapsed - backwardTime) > 0) {
            timeElapsed = timeElapsed - backwardTime;

            //seek to the exact second of the track
            mediaPlayer.seekTo((int) timeElapsed);
        }
    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        mediaPlayer.start();
        timeElapsed = mediaPlayer.getCurrentPosition();
        seekbar.setProgress((int) timeElapsed);
        durationHandler.postDelayed(updateSeekBarTime, 100);

    }
}

thanks!!! ironmantis7x


Solution

  • Outcast is not great at streaming; however making a buffer class and then controlling the player start part as a percentage of buffering sort of worked.