RTP audio stream player












0















Can android supports audio rtp reading in native API?
I want to develop an rtp audio player, I have tried with:



MediaPlayer API : rtp does not work:



package com.javacodegeeks.androidmediaplayerexample;

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

import android.app.Activity;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.*;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.SeekBar;
import android.widget.TextView;
//import java.lang.String;


import static android.util.Log.i;

public class AndroidMediaPlayerExample extends Activity implements 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;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

//set the layout of the Activity
setContentView(R.layout.activity_main);

//initialize views
try {
initializeViews();
} catch (IOException e) {
e.printStackTrace();
}
}

public void initializeViews() throws IOException {
songName = (TextView) findViewById(R.id.songName);
//mediaPlayer = MediaPlayer.create(this, R.raw.sample_song);


//mediaPlayer = MediaPlayer.create(this, myUri);
try {
Uri myUri = Uri.parse("rtsp://192.168.1.210:5000/test"); // initialize Uri here
i("TestAudio", "URI : " + myUri.getScheme());
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource("rtsp://192.168.1.210:5000/test");
//mediaPlayer.setDataSource(getApplicationContext(), myUri);

mediaPlayer.setOnPreparedListener(this);
mediaPlayer.prepareAsync(); // used for streaming
//mediaPlayer.prepare(); //Message: Prepare failed.: status=0x1 Cause: null

/*mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
//Called when the media file is ready for playback.
mp.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
i("TestAudio","Percent : " + Integer.toString(percent));
if(percent == 100)
{
mp.start();
}
}
});
}
});*/
} catch (Exception e) {
i("TestAudio", "Message: " + e.getMessage() + " Cause: " + e.getCause());
e.printStackTrace();

}

/*finalTime = mediaPlayer.getDuration();
duration = (TextView) findViewById(R.id.songDuration);
seekbar = (SeekBar) findViewById(R.id.seekBar);
songName.setText("Sample_Song.mp3");

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

// play mp3 song
public void play(View view) {
mediaPlayer.start();
/*timeElapsed = mediaPlayer.getCurrentPosition();
seekbar.setProgress((int) timeElapsed);
durationHandler.postDelayed(updateSeekBarTime, 100);*/
}

//handler to change seekBarTime
private Runnable updateSeekBarTime = new Runnable() {
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) {
mediaPlayer.pause();
}

// 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) {
mp.start();
}

@Override
public void onDestroy() {
super.onDestroy();
if (mediaPlayer != null) mediaPlayer.release();
}

}


ExoPlayer API : does not support rtp and rtsp:



package com.ayalus.exoplayer2example;

import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Surface;
import android.widget.TextView;

import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.decoder.DecoderCounters;
import com.google.android.exoplayer2.source.LoopingMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.source.hls.HlsMediaSource;
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.ui.PlayerView;
import com.google.android.exoplayer2.ui.SimpleExoPlayerView;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.VideoRendererEventListener;



/*
Created by: Ayal Fieldust
Date: 8/2017

Description:
This Example app was created to show a simple example of ExoPlayer Version 2.8.4.
There is an option to play mp4 files or live stream content.
Exoplayer provides options to play many different formats, so the code can easily be tweaked to play the requested format.
Scroll down to "ADJUST HERE:" I & II to change between sources.
Keep in mind that m3u8 files might be stale and you would need new sources.
*/

public class MainActivity extends AppCompatActivity implements VideoRendererEventListener {


private static final String TAG = "MainActivity";
private PlayerView simpleExoPlayerView;
private SimpleExoPlayer player;
private TextView resolutionTextView;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
resolutionTextView = new TextView(this);
resolutionTextView = (TextView) findViewById(R.id.resolution_textView);

//// I. ADJUST HERE:
////CHOOSE CONTENT: LiveStream / SdCard
//
////LIVE STREAM SOURCE: * Livestream links may be out of date so find any m3u8 files online and replace:
//
//// Uri mp4VideoUri =Uri.parse("http://81.7.13.162/hls/ss1/index.m3u8"); //random 720p source
//// Uri mp4VideoUri =Uri.parse("http://54.255.155.24:1935//Live/_definst_/amlst:sweetbcha1novD235L240P/playlist.m3u8"); //Radnom 540p indian channel
// Uri mp4VideoUri =Uri.parse("http://cbsnewshd-lh.akamaihd.net/i/CBSNHD_7@199302/index_700_av-p.m3u8"); //CNBC
//Uri mp4VideoUri =Uri.parse("http://live.field59.com/wwsb/ngrp:wwsb1_all/playlist.m3u8"); //ABC NEWS
Uri mp4VideoUri =Uri.parse("rtsp://192.168.1.110/test"); //ABC NEWS
//// Uri mp4VideoUri =Uri.parse("FIND A WORKING LINK ABD PLUg INTO HERE"); //PLUG INTO HERE<------------------------------------------
//
//
////VIDEO FROM SD CARD: (2 steps. set up file and path, then change videoSource to get the file)
//// String urimp4 = "path/FileName.mp4"; //upload file to device and add path/name.mp4
//// Uri mp4VideoUri = Uri.parse(Environment.getExternalStorageDirectory().getAbsolutePath()+urimp4);


DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(); //test

TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
TrackSelector trackSelector =
new DefaultTrackSelector(videoTrackSelectionFactory);

// 2. Create the player
player = ExoPlayerFactory.newSimpleInstance(this, trackSelector);
simpleExoPlayerView = new SimpleExoPlayerView(this);
simpleExoPlayerView = (SimpleExoPlayerView) findViewById(R.id.player_view);

int h = simpleExoPlayerView.getResources().getConfiguration().screenHeightDp;
int w = simpleExoPlayerView.getResources().getConfiguration().screenWidthDp;
Log.v(TAG, "height : " + h + " weight: " + w);
////Set media controller
simpleExoPlayerView.setUseController(false);//set to true or false to see controllers
simpleExoPlayerView.requestFocus();
// Bind the player to the view.
simpleExoPlayerView.setPlayer(player);

// Measures bandwidth during playback. Can be null if not required.
// Produces DataSource instances through which media data is loaded.
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "exoplayer2example"), bandwidthMeter);
// This is the MediaSource representing the media to be played.
// MediaSource videoSource = new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(liveStreamUri);

//// II. ADJUST HERE:

//// DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "exoplayer2example"), bandwidthMeterA);
////Produces Extractor instances for parsing the media data.
// ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();

//This is the MediaSource representing the media to be played:
//FOR SD CARD SOURCE:
// MediaSource videoSource = new ExtractorMediaSource(mp4VideoUri, dataSourceFactory, extractorsFactory, null, null);

//FOR LIVESTREAM LINK:
MediaSource videoSource = new HlsMediaSource(mp4VideoUri, dataSourceFactory, 1, null, null);
final LoopingMediaSource loopingSource = new LoopingMediaSource(videoSource);
// Prepare the player with the source.
player.prepare(videoSource);

player.addListener(new ExoPlayer.EventListener() {


@Override
public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {

}

@Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
Log.v(TAG, "Listener-onTracksChanged... ");
}

@Override
public void onLoadingChanged(boolean isLoading) {

}

@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
Log.v(TAG, "Listener-onPlayerStateChanged..." + playbackState+"|||isDrawingCacheEnabled():"+simpleExoPlayerView.isDrawingCacheEnabled());
}

@Override
public void onRepeatModeChanged(int repeatMode) {

}

@Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {

}

@Override
public void onPlayerError(ExoPlaybackException error) {
Log.v(TAG, "Listener-onPlayerError...");
player.stop();
player.prepare(loopingSource);
player.setPlayWhenReady(true);
}

@Override
public void onPositionDiscontinuity(int reason) {

}

@Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {

}

@Override
public void onSeekProcessed() {

}
});
player.setPlayWhenReady(true); //run file/link when ready to play.
player.setVideoDebugListener(this);
}



@Override
public void onVideoEnabled(DecoderCounters counters) {

}

@Override
public void onVideoDecoderInitialized(String decoderName, long initializedTimestampMs, long initializationDurationMs) {

}

@Override
public void onVideoInputFormatChanged(Format format) {

}

@Override
public void onDroppedFrames(int count, long elapsedMs) {

}

@Override
public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
Log.v(TAG, "onVideoSizeChanged [" + " width: " + width + " height: " + height + "]");
resolutionTextView.setText("RES:(WxH):" + width + "X" + height + "n " + height + "p");//shows video info
}

@Override
public void onRenderedFirstFrame(Surface surface) {

}

@Override
public void onVideoDisabled(DecoderCounters counters) {

}
//-------------------------------------------------------ANDROID LIFECYCLE---------------------------------------------------------------------------------------------

@Override
protected void onStop() {
super.onStop();
Log.v(TAG, "onStop()...");
}

@Override
protected void onStart() {
super.onStart();
Log.v(TAG, "onStart()...");
}

@Override
protected void onResume() {
super.onResume();
Log.v(TAG, "onResume()...");
}

@Override
protected void onPause() {
super.onPause();
Log.v(TAG, "onPause()...");
}

@Override
protected void onDestroy() {
super.onDestroy();
Log.v(TAG, "onDestroy()...");
player.release();
}
}


AudioStream API: rtp does not work:



import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.media.*;
import android.net.rtp.*;
import android.os.StrictMode;

import android.util.Log;

import java.net.*;

import static android.util.Log.i;

public class MainActivity extends AppCompatActivity {
AudioStream audioStream;
AudioGroup audioGroup;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitNetwork().build();
StrictMode.setThreadPolicy(policy);
AudioManager audio = (AudioManager)getSystemService(AUDIO_SERVICE);
audio.setMode(AudioManager.MODE_NORMAL);
audioGroup = new AudioGroup();
audioGroup.setMode(AudioGroup.MODE_NORMAL);
InetAddress inetAddress;
i("TestSon","aaaaa");
try {
inetAddress = InetAddress.getByName("192.168.1.182");
audioStream = new AudioStream(inetAddress);
audioStream.setCodec(AudioCodec.PCMU);
audioStream.setMode(RtpStream.MODE_RECEIVE_ONLY);
InetAddress inetAddressRemote = InetAddress.getByName("192.168.1.210");
audioStream.associate(inetAddressRemote, 6000);
audioStream.join(audioGroup);

i("TestSon","Local port : " + audioStream.getLocalPort());
i("TestSon","Local address : " + audioStream.getLocalAddress());

i("TestSon","Remote port : " + audioStream.getRemotePort());
i("TestSon","Remote address : " + audioStream.getRemoteAddress());

}
catch ( UnknownHostException e ) {
i("TestSon","exception1: " + e.getMessage());
e.printStackTrace();
}
catch ( SocketException e ) {
i("TestSon","exception2: " + e.getMessage());
e.printStackTrace();
}
}
}


should I use an external lib like libvlc or ffmpeg?










share|improve this question



























    0















    Can android supports audio rtp reading in native API?
    I want to develop an rtp audio player, I have tried with:



    MediaPlayer API : rtp does not work:



    package com.javacodegeeks.androidmediaplayerexample;

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

    import android.app.Activity;
    import android.media.AudioManager;
    import android.media.MediaPlayer;
    import android.media.MediaPlayer.*;
    import android.net.Uri;
    import android.os.Bundle;
    import android.os.Handler;
    import android.view.View;
    import android.widget.SeekBar;
    import android.widget.TextView;
    //import java.lang.String;


    import static android.util.Log.i;

    public class AndroidMediaPlayerExample extends Activity implements 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;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    //set the layout of the Activity
    setContentView(R.layout.activity_main);

    //initialize views
    try {
    initializeViews();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }

    public void initializeViews() throws IOException {
    songName = (TextView) findViewById(R.id.songName);
    //mediaPlayer = MediaPlayer.create(this, R.raw.sample_song);


    //mediaPlayer = MediaPlayer.create(this, myUri);
    try {
    Uri myUri = Uri.parse("rtsp://192.168.1.210:5000/test"); // initialize Uri here
    i("TestAudio", "URI : " + myUri.getScheme());
    mediaPlayer = new MediaPlayer();
    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    mediaPlayer.setDataSource("rtsp://192.168.1.210:5000/test");
    //mediaPlayer.setDataSource(getApplicationContext(), myUri);

    mediaPlayer.setOnPreparedListener(this);
    mediaPlayer.prepareAsync(); // used for streaming
    //mediaPlayer.prepare(); //Message: Prepare failed.: status=0x1 Cause: null

    /*mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
    //Called when the media file is ready for playback.
    mp.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
    @Override
    public void onBufferingUpdate(MediaPlayer mp, int percent) {
    i("TestAudio","Percent : " + Integer.toString(percent));
    if(percent == 100)
    {
    mp.start();
    }
    }
    });
    }
    });*/
    } catch (Exception e) {
    i("TestAudio", "Message: " + e.getMessage() + " Cause: " + e.getCause());
    e.printStackTrace();

    }

    /*finalTime = mediaPlayer.getDuration();
    duration = (TextView) findViewById(R.id.songDuration);
    seekbar = (SeekBar) findViewById(R.id.seekBar);
    songName.setText("Sample_Song.mp3");

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

    // play mp3 song
    public void play(View view) {
    mediaPlayer.start();
    /*timeElapsed = mediaPlayer.getCurrentPosition();
    seekbar.setProgress((int) timeElapsed);
    durationHandler.postDelayed(updateSeekBarTime, 100);*/
    }

    //handler to change seekBarTime
    private Runnable updateSeekBarTime = new Runnable() {
    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) {
    mediaPlayer.pause();
    }

    // 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) {
    mp.start();
    }

    @Override
    public void onDestroy() {
    super.onDestroy();
    if (mediaPlayer != null) mediaPlayer.release();
    }

    }


    ExoPlayer API : does not support rtp and rtsp:



    package com.ayalus.exoplayer2example;

    import android.net.Uri;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.view.Surface;
    import android.widget.TextView;

    import com.google.android.exoplayer2.ExoPlaybackException;
    import com.google.android.exoplayer2.ExoPlayer;
    import com.google.android.exoplayer2.ExoPlayerFactory;
    import com.google.android.exoplayer2.Format;
    import com.google.android.exoplayer2.PlaybackParameters;
    import com.google.android.exoplayer2.SimpleExoPlayer;
    import com.google.android.exoplayer2.Timeline;
    import com.google.android.exoplayer2.decoder.DecoderCounters;
    import com.google.android.exoplayer2.source.LoopingMediaSource;
    import com.google.android.exoplayer2.source.MediaSource;
    import com.google.android.exoplayer2.source.TrackGroupArray;
    import com.google.android.exoplayer2.source.hls.HlsMediaSource;
    import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
    import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
    import com.google.android.exoplayer2.trackselection.TrackSelection;
    import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
    import com.google.android.exoplayer2.trackselection.TrackSelector;
    import com.google.android.exoplayer2.ui.PlayerView;
    import com.google.android.exoplayer2.ui.SimpleExoPlayerView;
    import com.google.android.exoplayer2.upstream.DataSource;
    import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
    import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
    import com.google.android.exoplayer2.util.Util;
    import com.google.android.exoplayer2.video.VideoRendererEventListener;



    /*
    Created by: Ayal Fieldust
    Date: 8/2017

    Description:
    This Example app was created to show a simple example of ExoPlayer Version 2.8.4.
    There is an option to play mp4 files or live stream content.
    Exoplayer provides options to play many different formats, so the code can easily be tweaked to play the requested format.
    Scroll down to "ADJUST HERE:" I & II to change between sources.
    Keep in mind that m3u8 files might be stale and you would need new sources.
    */

    public class MainActivity extends AppCompatActivity implements VideoRendererEventListener {


    private static final String TAG = "MainActivity";
    private PlayerView simpleExoPlayerView;
    private SimpleExoPlayer player;
    private TextView resolutionTextView;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    resolutionTextView = new TextView(this);
    resolutionTextView = (TextView) findViewById(R.id.resolution_textView);

    //// I. ADJUST HERE:
    ////CHOOSE CONTENT: LiveStream / SdCard
    //
    ////LIVE STREAM SOURCE: * Livestream links may be out of date so find any m3u8 files online and replace:
    //
    //// Uri mp4VideoUri =Uri.parse("http://81.7.13.162/hls/ss1/index.m3u8"); //random 720p source
    //// Uri mp4VideoUri =Uri.parse("http://54.255.155.24:1935//Live/_definst_/amlst:sweetbcha1novD235L240P/playlist.m3u8"); //Radnom 540p indian channel
    // Uri mp4VideoUri =Uri.parse("http://cbsnewshd-lh.akamaihd.net/i/CBSNHD_7@199302/index_700_av-p.m3u8"); //CNBC
    //Uri mp4VideoUri =Uri.parse("http://live.field59.com/wwsb/ngrp:wwsb1_all/playlist.m3u8"); //ABC NEWS
    Uri mp4VideoUri =Uri.parse("rtsp://192.168.1.110/test"); //ABC NEWS
    //// Uri mp4VideoUri =Uri.parse("FIND A WORKING LINK ABD PLUg INTO HERE"); //PLUG INTO HERE<------------------------------------------
    //
    //
    ////VIDEO FROM SD CARD: (2 steps. set up file and path, then change videoSource to get the file)
    //// String urimp4 = "path/FileName.mp4"; //upload file to device and add path/name.mp4
    //// Uri mp4VideoUri = Uri.parse(Environment.getExternalStorageDirectory().getAbsolutePath()+urimp4);


    DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(); //test

    TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
    TrackSelector trackSelector =
    new DefaultTrackSelector(videoTrackSelectionFactory);

    // 2. Create the player
    player = ExoPlayerFactory.newSimpleInstance(this, trackSelector);
    simpleExoPlayerView = new SimpleExoPlayerView(this);
    simpleExoPlayerView = (SimpleExoPlayerView) findViewById(R.id.player_view);

    int h = simpleExoPlayerView.getResources().getConfiguration().screenHeightDp;
    int w = simpleExoPlayerView.getResources().getConfiguration().screenWidthDp;
    Log.v(TAG, "height : " + h + " weight: " + w);
    ////Set media controller
    simpleExoPlayerView.setUseController(false);//set to true or false to see controllers
    simpleExoPlayerView.requestFocus();
    // Bind the player to the view.
    simpleExoPlayerView.setPlayer(player);

    // Measures bandwidth during playback. Can be null if not required.
    // Produces DataSource instances through which media data is loaded.
    DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "exoplayer2example"), bandwidthMeter);
    // This is the MediaSource representing the media to be played.
    // MediaSource videoSource = new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(liveStreamUri);

    //// II. ADJUST HERE:

    //// DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "exoplayer2example"), bandwidthMeterA);
    ////Produces Extractor instances for parsing the media data.
    // ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();

    //This is the MediaSource representing the media to be played:
    //FOR SD CARD SOURCE:
    // MediaSource videoSource = new ExtractorMediaSource(mp4VideoUri, dataSourceFactory, extractorsFactory, null, null);

    //FOR LIVESTREAM LINK:
    MediaSource videoSource = new HlsMediaSource(mp4VideoUri, dataSourceFactory, 1, null, null);
    final LoopingMediaSource loopingSource = new LoopingMediaSource(videoSource);
    // Prepare the player with the source.
    player.prepare(videoSource);

    player.addListener(new ExoPlayer.EventListener() {


    @Override
    public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {

    }

    @Override
    public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
    Log.v(TAG, "Listener-onTracksChanged... ");
    }

    @Override
    public void onLoadingChanged(boolean isLoading) {

    }

    @Override
    public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
    Log.v(TAG, "Listener-onPlayerStateChanged..." + playbackState+"|||isDrawingCacheEnabled():"+simpleExoPlayerView.isDrawingCacheEnabled());
    }

    @Override
    public void onRepeatModeChanged(int repeatMode) {

    }

    @Override
    public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {

    }

    @Override
    public void onPlayerError(ExoPlaybackException error) {
    Log.v(TAG, "Listener-onPlayerError...");
    player.stop();
    player.prepare(loopingSource);
    player.setPlayWhenReady(true);
    }

    @Override
    public void onPositionDiscontinuity(int reason) {

    }

    @Override
    public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {

    }

    @Override
    public void onSeekProcessed() {

    }
    });
    player.setPlayWhenReady(true); //run file/link when ready to play.
    player.setVideoDebugListener(this);
    }



    @Override
    public void onVideoEnabled(DecoderCounters counters) {

    }

    @Override
    public void onVideoDecoderInitialized(String decoderName, long initializedTimestampMs, long initializationDurationMs) {

    }

    @Override
    public void onVideoInputFormatChanged(Format format) {

    }

    @Override
    public void onDroppedFrames(int count, long elapsedMs) {

    }

    @Override
    public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
    Log.v(TAG, "onVideoSizeChanged [" + " width: " + width + " height: " + height + "]");
    resolutionTextView.setText("RES:(WxH):" + width + "X" + height + "n " + height + "p");//shows video info
    }

    @Override
    public void onRenderedFirstFrame(Surface surface) {

    }

    @Override
    public void onVideoDisabled(DecoderCounters counters) {

    }
    //-------------------------------------------------------ANDROID LIFECYCLE---------------------------------------------------------------------------------------------

    @Override
    protected void onStop() {
    super.onStop();
    Log.v(TAG, "onStop()...");
    }

    @Override
    protected void onStart() {
    super.onStart();
    Log.v(TAG, "onStart()...");
    }

    @Override
    protected void onResume() {
    super.onResume();
    Log.v(TAG, "onResume()...");
    }

    @Override
    protected void onPause() {
    super.onPause();
    Log.v(TAG, "onPause()...");
    }

    @Override
    protected void onDestroy() {
    super.onDestroy();
    Log.v(TAG, "onDestroy()...");
    player.release();
    }
    }


    AudioStream API: rtp does not work:



    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.media.*;
    import android.net.rtp.*;
    import android.os.StrictMode;

    import android.util.Log;

    import java.net.*;

    import static android.util.Log.i;

    public class MainActivity extends AppCompatActivity {
    AudioStream audioStream;
    AudioGroup audioGroup;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitNetwork().build();
    StrictMode.setThreadPolicy(policy);
    AudioManager audio = (AudioManager)getSystemService(AUDIO_SERVICE);
    audio.setMode(AudioManager.MODE_NORMAL);
    audioGroup = new AudioGroup();
    audioGroup.setMode(AudioGroup.MODE_NORMAL);
    InetAddress inetAddress;
    i("TestSon","aaaaa");
    try {
    inetAddress = InetAddress.getByName("192.168.1.182");
    audioStream = new AudioStream(inetAddress);
    audioStream.setCodec(AudioCodec.PCMU);
    audioStream.setMode(RtpStream.MODE_RECEIVE_ONLY);
    InetAddress inetAddressRemote = InetAddress.getByName("192.168.1.210");
    audioStream.associate(inetAddressRemote, 6000);
    audioStream.join(audioGroup);

    i("TestSon","Local port : " + audioStream.getLocalPort());
    i("TestSon","Local address : " + audioStream.getLocalAddress());

    i("TestSon","Remote port : " + audioStream.getRemotePort());
    i("TestSon","Remote address : " + audioStream.getRemoteAddress());

    }
    catch ( UnknownHostException e ) {
    i("TestSon","exception1: " + e.getMessage());
    e.printStackTrace();
    }
    catch ( SocketException e ) {
    i("TestSon","exception2: " + e.getMessage());
    e.printStackTrace();
    }
    }
    }


    should I use an external lib like libvlc or ffmpeg?










    share|improve this question

























      0












      0








      0








      Can android supports audio rtp reading in native API?
      I want to develop an rtp audio player, I have tried with:



      MediaPlayer API : rtp does not work:



      package com.javacodegeeks.androidmediaplayerexample;

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

      import android.app.Activity;
      import android.media.AudioManager;
      import android.media.MediaPlayer;
      import android.media.MediaPlayer.*;
      import android.net.Uri;
      import android.os.Bundle;
      import android.os.Handler;
      import android.view.View;
      import android.widget.SeekBar;
      import android.widget.TextView;
      //import java.lang.String;


      import static android.util.Log.i;

      public class AndroidMediaPlayerExample extends Activity implements 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;

      @Override
      protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);

      //set the layout of the Activity
      setContentView(R.layout.activity_main);

      //initialize views
      try {
      initializeViews();
      } catch (IOException e) {
      e.printStackTrace();
      }
      }

      public void initializeViews() throws IOException {
      songName = (TextView) findViewById(R.id.songName);
      //mediaPlayer = MediaPlayer.create(this, R.raw.sample_song);


      //mediaPlayer = MediaPlayer.create(this, myUri);
      try {
      Uri myUri = Uri.parse("rtsp://192.168.1.210:5000/test"); // initialize Uri here
      i("TestAudio", "URI : " + myUri.getScheme());
      mediaPlayer = new MediaPlayer();
      mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
      mediaPlayer.setDataSource("rtsp://192.168.1.210:5000/test");
      //mediaPlayer.setDataSource(getApplicationContext(), myUri);

      mediaPlayer.setOnPreparedListener(this);
      mediaPlayer.prepareAsync(); // used for streaming
      //mediaPlayer.prepare(); //Message: Prepare failed.: status=0x1 Cause: null

      /*mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
      @Override
      public void onPrepared(MediaPlayer mp) {
      //Called when the media file is ready for playback.
      mp.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
      @Override
      public void onBufferingUpdate(MediaPlayer mp, int percent) {
      i("TestAudio","Percent : " + Integer.toString(percent));
      if(percent == 100)
      {
      mp.start();
      }
      }
      });
      }
      });*/
      } catch (Exception e) {
      i("TestAudio", "Message: " + e.getMessage() + " Cause: " + e.getCause());
      e.printStackTrace();

      }

      /*finalTime = mediaPlayer.getDuration();
      duration = (TextView) findViewById(R.id.songDuration);
      seekbar = (SeekBar) findViewById(R.id.seekBar);
      songName.setText("Sample_Song.mp3");

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

      // play mp3 song
      public void play(View view) {
      mediaPlayer.start();
      /*timeElapsed = mediaPlayer.getCurrentPosition();
      seekbar.setProgress((int) timeElapsed);
      durationHandler.postDelayed(updateSeekBarTime, 100);*/
      }

      //handler to change seekBarTime
      private Runnable updateSeekBarTime = new Runnable() {
      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) {
      mediaPlayer.pause();
      }

      // 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) {
      mp.start();
      }

      @Override
      public void onDestroy() {
      super.onDestroy();
      if (mediaPlayer != null) mediaPlayer.release();
      }

      }


      ExoPlayer API : does not support rtp and rtsp:



      package com.ayalus.exoplayer2example;

      import android.net.Uri;
      import android.os.Bundle;
      import android.support.v7.app.AppCompatActivity;
      import android.util.Log;
      import android.view.Surface;
      import android.widget.TextView;

      import com.google.android.exoplayer2.ExoPlaybackException;
      import com.google.android.exoplayer2.ExoPlayer;
      import com.google.android.exoplayer2.ExoPlayerFactory;
      import com.google.android.exoplayer2.Format;
      import com.google.android.exoplayer2.PlaybackParameters;
      import com.google.android.exoplayer2.SimpleExoPlayer;
      import com.google.android.exoplayer2.Timeline;
      import com.google.android.exoplayer2.decoder.DecoderCounters;
      import com.google.android.exoplayer2.source.LoopingMediaSource;
      import com.google.android.exoplayer2.source.MediaSource;
      import com.google.android.exoplayer2.source.TrackGroupArray;
      import com.google.android.exoplayer2.source.hls.HlsMediaSource;
      import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
      import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
      import com.google.android.exoplayer2.trackselection.TrackSelection;
      import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
      import com.google.android.exoplayer2.trackselection.TrackSelector;
      import com.google.android.exoplayer2.ui.PlayerView;
      import com.google.android.exoplayer2.ui.SimpleExoPlayerView;
      import com.google.android.exoplayer2.upstream.DataSource;
      import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
      import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
      import com.google.android.exoplayer2.util.Util;
      import com.google.android.exoplayer2.video.VideoRendererEventListener;



      /*
      Created by: Ayal Fieldust
      Date: 8/2017

      Description:
      This Example app was created to show a simple example of ExoPlayer Version 2.8.4.
      There is an option to play mp4 files or live stream content.
      Exoplayer provides options to play many different formats, so the code can easily be tweaked to play the requested format.
      Scroll down to "ADJUST HERE:" I & II to change between sources.
      Keep in mind that m3u8 files might be stale and you would need new sources.
      */

      public class MainActivity extends AppCompatActivity implements VideoRendererEventListener {


      private static final String TAG = "MainActivity";
      private PlayerView simpleExoPlayerView;
      private SimpleExoPlayer player;
      private TextView resolutionTextView;


      @Override
      protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      resolutionTextView = new TextView(this);
      resolutionTextView = (TextView) findViewById(R.id.resolution_textView);

      //// I. ADJUST HERE:
      ////CHOOSE CONTENT: LiveStream / SdCard
      //
      ////LIVE STREAM SOURCE: * Livestream links may be out of date so find any m3u8 files online and replace:
      //
      //// Uri mp4VideoUri =Uri.parse("http://81.7.13.162/hls/ss1/index.m3u8"); //random 720p source
      //// Uri mp4VideoUri =Uri.parse("http://54.255.155.24:1935//Live/_definst_/amlst:sweetbcha1novD235L240P/playlist.m3u8"); //Radnom 540p indian channel
      // Uri mp4VideoUri =Uri.parse("http://cbsnewshd-lh.akamaihd.net/i/CBSNHD_7@199302/index_700_av-p.m3u8"); //CNBC
      //Uri mp4VideoUri =Uri.parse("http://live.field59.com/wwsb/ngrp:wwsb1_all/playlist.m3u8"); //ABC NEWS
      Uri mp4VideoUri =Uri.parse("rtsp://192.168.1.110/test"); //ABC NEWS
      //// Uri mp4VideoUri =Uri.parse("FIND A WORKING LINK ABD PLUg INTO HERE"); //PLUG INTO HERE<------------------------------------------
      //
      //
      ////VIDEO FROM SD CARD: (2 steps. set up file and path, then change videoSource to get the file)
      //// String urimp4 = "path/FileName.mp4"; //upload file to device and add path/name.mp4
      //// Uri mp4VideoUri = Uri.parse(Environment.getExternalStorageDirectory().getAbsolutePath()+urimp4);


      DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(); //test

      TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
      TrackSelector trackSelector =
      new DefaultTrackSelector(videoTrackSelectionFactory);

      // 2. Create the player
      player = ExoPlayerFactory.newSimpleInstance(this, trackSelector);
      simpleExoPlayerView = new SimpleExoPlayerView(this);
      simpleExoPlayerView = (SimpleExoPlayerView) findViewById(R.id.player_view);

      int h = simpleExoPlayerView.getResources().getConfiguration().screenHeightDp;
      int w = simpleExoPlayerView.getResources().getConfiguration().screenWidthDp;
      Log.v(TAG, "height : " + h + " weight: " + w);
      ////Set media controller
      simpleExoPlayerView.setUseController(false);//set to true or false to see controllers
      simpleExoPlayerView.requestFocus();
      // Bind the player to the view.
      simpleExoPlayerView.setPlayer(player);

      // Measures bandwidth during playback. Can be null if not required.
      // Produces DataSource instances through which media data is loaded.
      DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "exoplayer2example"), bandwidthMeter);
      // This is the MediaSource representing the media to be played.
      // MediaSource videoSource = new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(liveStreamUri);

      //// II. ADJUST HERE:

      //// DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "exoplayer2example"), bandwidthMeterA);
      ////Produces Extractor instances for parsing the media data.
      // ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();

      //This is the MediaSource representing the media to be played:
      //FOR SD CARD SOURCE:
      // MediaSource videoSource = new ExtractorMediaSource(mp4VideoUri, dataSourceFactory, extractorsFactory, null, null);

      //FOR LIVESTREAM LINK:
      MediaSource videoSource = new HlsMediaSource(mp4VideoUri, dataSourceFactory, 1, null, null);
      final LoopingMediaSource loopingSource = new LoopingMediaSource(videoSource);
      // Prepare the player with the source.
      player.prepare(videoSource);

      player.addListener(new ExoPlayer.EventListener() {


      @Override
      public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {

      }

      @Override
      public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
      Log.v(TAG, "Listener-onTracksChanged... ");
      }

      @Override
      public void onLoadingChanged(boolean isLoading) {

      }

      @Override
      public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
      Log.v(TAG, "Listener-onPlayerStateChanged..." + playbackState+"|||isDrawingCacheEnabled():"+simpleExoPlayerView.isDrawingCacheEnabled());
      }

      @Override
      public void onRepeatModeChanged(int repeatMode) {

      }

      @Override
      public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {

      }

      @Override
      public void onPlayerError(ExoPlaybackException error) {
      Log.v(TAG, "Listener-onPlayerError...");
      player.stop();
      player.prepare(loopingSource);
      player.setPlayWhenReady(true);
      }

      @Override
      public void onPositionDiscontinuity(int reason) {

      }

      @Override
      public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {

      }

      @Override
      public void onSeekProcessed() {

      }
      });
      player.setPlayWhenReady(true); //run file/link when ready to play.
      player.setVideoDebugListener(this);
      }



      @Override
      public void onVideoEnabled(DecoderCounters counters) {

      }

      @Override
      public void onVideoDecoderInitialized(String decoderName, long initializedTimestampMs, long initializationDurationMs) {

      }

      @Override
      public void onVideoInputFormatChanged(Format format) {

      }

      @Override
      public void onDroppedFrames(int count, long elapsedMs) {

      }

      @Override
      public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
      Log.v(TAG, "onVideoSizeChanged [" + " width: " + width + " height: " + height + "]");
      resolutionTextView.setText("RES:(WxH):" + width + "X" + height + "n " + height + "p");//shows video info
      }

      @Override
      public void onRenderedFirstFrame(Surface surface) {

      }

      @Override
      public void onVideoDisabled(DecoderCounters counters) {

      }
      //-------------------------------------------------------ANDROID LIFECYCLE---------------------------------------------------------------------------------------------

      @Override
      protected void onStop() {
      super.onStop();
      Log.v(TAG, "onStop()...");
      }

      @Override
      protected void onStart() {
      super.onStart();
      Log.v(TAG, "onStart()...");
      }

      @Override
      protected void onResume() {
      super.onResume();
      Log.v(TAG, "onResume()...");
      }

      @Override
      protected void onPause() {
      super.onPause();
      Log.v(TAG, "onPause()...");
      }

      @Override
      protected void onDestroy() {
      super.onDestroy();
      Log.v(TAG, "onDestroy()...");
      player.release();
      }
      }


      AudioStream API: rtp does not work:



      import android.support.v7.app.AppCompatActivity;
      import android.os.Bundle;
      import android.media.*;
      import android.net.rtp.*;
      import android.os.StrictMode;

      import android.util.Log;

      import java.net.*;

      import static android.util.Log.i;

      public class MainActivity extends AppCompatActivity {
      AudioStream audioStream;
      AudioGroup audioGroup;
      @Override
      protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitNetwork().build();
      StrictMode.setThreadPolicy(policy);
      AudioManager audio = (AudioManager)getSystemService(AUDIO_SERVICE);
      audio.setMode(AudioManager.MODE_NORMAL);
      audioGroup = new AudioGroup();
      audioGroup.setMode(AudioGroup.MODE_NORMAL);
      InetAddress inetAddress;
      i("TestSon","aaaaa");
      try {
      inetAddress = InetAddress.getByName("192.168.1.182");
      audioStream = new AudioStream(inetAddress);
      audioStream.setCodec(AudioCodec.PCMU);
      audioStream.setMode(RtpStream.MODE_RECEIVE_ONLY);
      InetAddress inetAddressRemote = InetAddress.getByName("192.168.1.210");
      audioStream.associate(inetAddressRemote, 6000);
      audioStream.join(audioGroup);

      i("TestSon","Local port : " + audioStream.getLocalPort());
      i("TestSon","Local address : " + audioStream.getLocalAddress());

      i("TestSon","Remote port : " + audioStream.getRemotePort());
      i("TestSon","Remote address : " + audioStream.getRemoteAddress());

      }
      catch ( UnknownHostException e ) {
      i("TestSon","exception1: " + e.getMessage());
      e.printStackTrace();
      }
      catch ( SocketException e ) {
      i("TestSon","exception2: " + e.getMessage());
      e.printStackTrace();
      }
      }
      }


      should I use an external lib like libvlc or ffmpeg?










      share|improve this question














      Can android supports audio rtp reading in native API?
      I want to develop an rtp audio player, I have tried with:



      MediaPlayer API : rtp does not work:



      package com.javacodegeeks.androidmediaplayerexample;

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

      import android.app.Activity;
      import android.media.AudioManager;
      import android.media.MediaPlayer;
      import android.media.MediaPlayer.*;
      import android.net.Uri;
      import android.os.Bundle;
      import android.os.Handler;
      import android.view.View;
      import android.widget.SeekBar;
      import android.widget.TextView;
      //import java.lang.String;


      import static android.util.Log.i;

      public class AndroidMediaPlayerExample extends Activity implements 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;

      @Override
      protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);

      //set the layout of the Activity
      setContentView(R.layout.activity_main);

      //initialize views
      try {
      initializeViews();
      } catch (IOException e) {
      e.printStackTrace();
      }
      }

      public void initializeViews() throws IOException {
      songName = (TextView) findViewById(R.id.songName);
      //mediaPlayer = MediaPlayer.create(this, R.raw.sample_song);


      //mediaPlayer = MediaPlayer.create(this, myUri);
      try {
      Uri myUri = Uri.parse("rtsp://192.168.1.210:5000/test"); // initialize Uri here
      i("TestAudio", "URI : " + myUri.getScheme());
      mediaPlayer = new MediaPlayer();
      mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
      mediaPlayer.setDataSource("rtsp://192.168.1.210:5000/test");
      //mediaPlayer.setDataSource(getApplicationContext(), myUri);

      mediaPlayer.setOnPreparedListener(this);
      mediaPlayer.prepareAsync(); // used for streaming
      //mediaPlayer.prepare(); //Message: Prepare failed.: status=0x1 Cause: null

      /*mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
      @Override
      public void onPrepared(MediaPlayer mp) {
      //Called when the media file is ready for playback.
      mp.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
      @Override
      public void onBufferingUpdate(MediaPlayer mp, int percent) {
      i("TestAudio","Percent : " + Integer.toString(percent));
      if(percent == 100)
      {
      mp.start();
      }
      }
      });
      }
      });*/
      } catch (Exception e) {
      i("TestAudio", "Message: " + e.getMessage() + " Cause: " + e.getCause());
      e.printStackTrace();

      }

      /*finalTime = mediaPlayer.getDuration();
      duration = (TextView) findViewById(R.id.songDuration);
      seekbar = (SeekBar) findViewById(R.id.seekBar);
      songName.setText("Sample_Song.mp3");

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

      // play mp3 song
      public void play(View view) {
      mediaPlayer.start();
      /*timeElapsed = mediaPlayer.getCurrentPosition();
      seekbar.setProgress((int) timeElapsed);
      durationHandler.postDelayed(updateSeekBarTime, 100);*/
      }

      //handler to change seekBarTime
      private Runnable updateSeekBarTime = new Runnable() {
      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) {
      mediaPlayer.pause();
      }

      // 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) {
      mp.start();
      }

      @Override
      public void onDestroy() {
      super.onDestroy();
      if (mediaPlayer != null) mediaPlayer.release();
      }

      }


      ExoPlayer API : does not support rtp and rtsp:



      package com.ayalus.exoplayer2example;

      import android.net.Uri;
      import android.os.Bundle;
      import android.support.v7.app.AppCompatActivity;
      import android.util.Log;
      import android.view.Surface;
      import android.widget.TextView;

      import com.google.android.exoplayer2.ExoPlaybackException;
      import com.google.android.exoplayer2.ExoPlayer;
      import com.google.android.exoplayer2.ExoPlayerFactory;
      import com.google.android.exoplayer2.Format;
      import com.google.android.exoplayer2.PlaybackParameters;
      import com.google.android.exoplayer2.SimpleExoPlayer;
      import com.google.android.exoplayer2.Timeline;
      import com.google.android.exoplayer2.decoder.DecoderCounters;
      import com.google.android.exoplayer2.source.LoopingMediaSource;
      import com.google.android.exoplayer2.source.MediaSource;
      import com.google.android.exoplayer2.source.TrackGroupArray;
      import com.google.android.exoplayer2.source.hls.HlsMediaSource;
      import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
      import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
      import com.google.android.exoplayer2.trackselection.TrackSelection;
      import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
      import com.google.android.exoplayer2.trackselection.TrackSelector;
      import com.google.android.exoplayer2.ui.PlayerView;
      import com.google.android.exoplayer2.ui.SimpleExoPlayerView;
      import com.google.android.exoplayer2.upstream.DataSource;
      import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
      import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
      import com.google.android.exoplayer2.util.Util;
      import com.google.android.exoplayer2.video.VideoRendererEventListener;



      /*
      Created by: Ayal Fieldust
      Date: 8/2017

      Description:
      This Example app was created to show a simple example of ExoPlayer Version 2.8.4.
      There is an option to play mp4 files or live stream content.
      Exoplayer provides options to play many different formats, so the code can easily be tweaked to play the requested format.
      Scroll down to "ADJUST HERE:" I & II to change between sources.
      Keep in mind that m3u8 files might be stale and you would need new sources.
      */

      public class MainActivity extends AppCompatActivity implements VideoRendererEventListener {


      private static final String TAG = "MainActivity";
      private PlayerView simpleExoPlayerView;
      private SimpleExoPlayer player;
      private TextView resolutionTextView;


      @Override
      protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      resolutionTextView = new TextView(this);
      resolutionTextView = (TextView) findViewById(R.id.resolution_textView);

      //// I. ADJUST HERE:
      ////CHOOSE CONTENT: LiveStream / SdCard
      //
      ////LIVE STREAM SOURCE: * Livestream links may be out of date so find any m3u8 files online and replace:
      //
      //// Uri mp4VideoUri =Uri.parse("http://81.7.13.162/hls/ss1/index.m3u8"); //random 720p source
      //// Uri mp4VideoUri =Uri.parse("http://54.255.155.24:1935//Live/_definst_/amlst:sweetbcha1novD235L240P/playlist.m3u8"); //Radnom 540p indian channel
      // Uri mp4VideoUri =Uri.parse("http://cbsnewshd-lh.akamaihd.net/i/CBSNHD_7@199302/index_700_av-p.m3u8"); //CNBC
      //Uri mp4VideoUri =Uri.parse("http://live.field59.com/wwsb/ngrp:wwsb1_all/playlist.m3u8"); //ABC NEWS
      Uri mp4VideoUri =Uri.parse("rtsp://192.168.1.110/test"); //ABC NEWS
      //// Uri mp4VideoUri =Uri.parse("FIND A WORKING LINK ABD PLUg INTO HERE"); //PLUG INTO HERE<------------------------------------------
      //
      //
      ////VIDEO FROM SD CARD: (2 steps. set up file and path, then change videoSource to get the file)
      //// String urimp4 = "path/FileName.mp4"; //upload file to device and add path/name.mp4
      //// Uri mp4VideoUri = Uri.parse(Environment.getExternalStorageDirectory().getAbsolutePath()+urimp4);


      DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(); //test

      TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
      TrackSelector trackSelector =
      new DefaultTrackSelector(videoTrackSelectionFactory);

      // 2. Create the player
      player = ExoPlayerFactory.newSimpleInstance(this, trackSelector);
      simpleExoPlayerView = new SimpleExoPlayerView(this);
      simpleExoPlayerView = (SimpleExoPlayerView) findViewById(R.id.player_view);

      int h = simpleExoPlayerView.getResources().getConfiguration().screenHeightDp;
      int w = simpleExoPlayerView.getResources().getConfiguration().screenWidthDp;
      Log.v(TAG, "height : " + h + " weight: " + w);
      ////Set media controller
      simpleExoPlayerView.setUseController(false);//set to true or false to see controllers
      simpleExoPlayerView.requestFocus();
      // Bind the player to the view.
      simpleExoPlayerView.setPlayer(player);

      // Measures bandwidth during playback. Can be null if not required.
      // Produces DataSource instances through which media data is loaded.
      DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "exoplayer2example"), bandwidthMeter);
      // This is the MediaSource representing the media to be played.
      // MediaSource videoSource = new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(liveStreamUri);

      //// II. ADJUST HERE:

      //// DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "exoplayer2example"), bandwidthMeterA);
      ////Produces Extractor instances for parsing the media data.
      // ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();

      //This is the MediaSource representing the media to be played:
      //FOR SD CARD SOURCE:
      // MediaSource videoSource = new ExtractorMediaSource(mp4VideoUri, dataSourceFactory, extractorsFactory, null, null);

      //FOR LIVESTREAM LINK:
      MediaSource videoSource = new HlsMediaSource(mp4VideoUri, dataSourceFactory, 1, null, null);
      final LoopingMediaSource loopingSource = new LoopingMediaSource(videoSource);
      // Prepare the player with the source.
      player.prepare(videoSource);

      player.addListener(new ExoPlayer.EventListener() {


      @Override
      public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {

      }

      @Override
      public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
      Log.v(TAG, "Listener-onTracksChanged... ");
      }

      @Override
      public void onLoadingChanged(boolean isLoading) {

      }

      @Override
      public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
      Log.v(TAG, "Listener-onPlayerStateChanged..." + playbackState+"|||isDrawingCacheEnabled():"+simpleExoPlayerView.isDrawingCacheEnabled());
      }

      @Override
      public void onRepeatModeChanged(int repeatMode) {

      }

      @Override
      public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {

      }

      @Override
      public void onPlayerError(ExoPlaybackException error) {
      Log.v(TAG, "Listener-onPlayerError...");
      player.stop();
      player.prepare(loopingSource);
      player.setPlayWhenReady(true);
      }

      @Override
      public void onPositionDiscontinuity(int reason) {

      }

      @Override
      public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {

      }

      @Override
      public void onSeekProcessed() {

      }
      });
      player.setPlayWhenReady(true); //run file/link when ready to play.
      player.setVideoDebugListener(this);
      }



      @Override
      public void onVideoEnabled(DecoderCounters counters) {

      }

      @Override
      public void onVideoDecoderInitialized(String decoderName, long initializedTimestampMs, long initializationDurationMs) {

      }

      @Override
      public void onVideoInputFormatChanged(Format format) {

      }

      @Override
      public void onDroppedFrames(int count, long elapsedMs) {

      }

      @Override
      public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
      Log.v(TAG, "onVideoSizeChanged [" + " width: " + width + " height: " + height + "]");
      resolutionTextView.setText("RES:(WxH):" + width + "X" + height + "n " + height + "p");//shows video info
      }

      @Override
      public void onRenderedFirstFrame(Surface surface) {

      }

      @Override
      public void onVideoDisabled(DecoderCounters counters) {

      }
      //-------------------------------------------------------ANDROID LIFECYCLE---------------------------------------------------------------------------------------------

      @Override
      protected void onStop() {
      super.onStop();
      Log.v(TAG, "onStop()...");
      }

      @Override
      protected void onStart() {
      super.onStart();
      Log.v(TAG, "onStart()...");
      }

      @Override
      protected void onResume() {
      super.onResume();
      Log.v(TAG, "onResume()...");
      }

      @Override
      protected void onPause() {
      super.onPause();
      Log.v(TAG, "onPause()...");
      }

      @Override
      protected void onDestroy() {
      super.onDestroy();
      Log.v(TAG, "onDestroy()...");
      player.release();
      }
      }


      AudioStream API: rtp does not work:



      import android.support.v7.app.AppCompatActivity;
      import android.os.Bundle;
      import android.media.*;
      import android.net.rtp.*;
      import android.os.StrictMode;

      import android.util.Log;

      import java.net.*;

      import static android.util.Log.i;

      public class MainActivity extends AppCompatActivity {
      AudioStream audioStream;
      AudioGroup audioGroup;
      @Override
      protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitNetwork().build();
      StrictMode.setThreadPolicy(policy);
      AudioManager audio = (AudioManager)getSystemService(AUDIO_SERVICE);
      audio.setMode(AudioManager.MODE_NORMAL);
      audioGroup = new AudioGroup();
      audioGroup.setMode(AudioGroup.MODE_NORMAL);
      InetAddress inetAddress;
      i("TestSon","aaaaa");
      try {
      inetAddress = InetAddress.getByName("192.168.1.182");
      audioStream = new AudioStream(inetAddress);
      audioStream.setCodec(AudioCodec.PCMU);
      audioStream.setMode(RtpStream.MODE_RECEIVE_ONLY);
      InetAddress inetAddressRemote = InetAddress.getByName("192.168.1.210");
      audioStream.associate(inetAddressRemote, 6000);
      audioStream.join(audioGroup);

      i("TestSon","Local port : " + audioStream.getLocalPort());
      i("TestSon","Local address : " + audioStream.getLocalAddress());

      i("TestSon","Remote port : " + audioStream.getRemotePort());
      i("TestSon","Remote address : " + audioStream.getRemoteAddress());

      }
      catch ( UnknownHostException e ) {
      i("TestSon","exception1: " + e.getMessage());
      e.printStackTrace();
      }
      catch ( SocketException e ) {
      i("TestSon","exception2: " + e.getMessage());
      e.printStackTrace();
      }
      }
      }


      should I use an external lib like libvlc or ffmpeg?







      java audio streaming media-player rtp






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 26 '18 at 12:01









      developerdeveloper

      2,71342846




      2,71342846
























          1 Answer
          1






          active

          oldest

          votes


















          0














          You can use FFmpeg to stream a single audio stream using the RTP protocol. Here is more information here:



          https://trac.ffmpeg.org/wiki/StreamingGuide#StreamingasimpleRTPaudiostreamfromFFmpeg




          FFmpeg can stream a single stream using the ​RTP protocol. In order to
          avoid buffering problems on the other hand, the streaming should be
          done through the -re option, which means that the stream will be
          streamed in real-time (i.e. it slows it down to simulate a live
          streaming ​source.



          For example the following command will generate a signal, and will
          stream it to the port 1234 on localhost:



          ffmpeg -re -f lavfi -i aevalsrc="sin(400*2*PI*t)" -ar 8000 -f mulaw -f
          rtp rtp://127.0.0.1:1234 To play the stream with ffplay (which has
          some caveats, see above), run the command:



          ffplay rtp://127.0.0.1:1234 Note that rtp by default uses UDP, which,
          for large streams, can cause packet loss. See the "point to point"
          section in this document for hints if this ever happens to you.







          share|improve this answer
























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53480692%2frtp-audio-stream-player%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0














            You can use FFmpeg to stream a single audio stream using the RTP protocol. Here is more information here:



            https://trac.ffmpeg.org/wiki/StreamingGuide#StreamingasimpleRTPaudiostreamfromFFmpeg




            FFmpeg can stream a single stream using the ​RTP protocol. In order to
            avoid buffering problems on the other hand, the streaming should be
            done through the -re option, which means that the stream will be
            streamed in real-time (i.e. it slows it down to simulate a live
            streaming ​source.



            For example the following command will generate a signal, and will
            stream it to the port 1234 on localhost:



            ffmpeg -re -f lavfi -i aevalsrc="sin(400*2*PI*t)" -ar 8000 -f mulaw -f
            rtp rtp://127.0.0.1:1234 To play the stream with ffplay (which has
            some caveats, see above), run the command:



            ffplay rtp://127.0.0.1:1234 Note that rtp by default uses UDP, which,
            for large streams, can cause packet loss. See the "point to point"
            section in this document for hints if this ever happens to you.







            share|improve this answer




























              0














              You can use FFmpeg to stream a single audio stream using the RTP protocol. Here is more information here:



              https://trac.ffmpeg.org/wiki/StreamingGuide#StreamingasimpleRTPaudiostreamfromFFmpeg




              FFmpeg can stream a single stream using the ​RTP protocol. In order to
              avoid buffering problems on the other hand, the streaming should be
              done through the -re option, which means that the stream will be
              streamed in real-time (i.e. it slows it down to simulate a live
              streaming ​source.



              For example the following command will generate a signal, and will
              stream it to the port 1234 on localhost:



              ffmpeg -re -f lavfi -i aevalsrc="sin(400*2*PI*t)" -ar 8000 -f mulaw -f
              rtp rtp://127.0.0.1:1234 To play the stream with ffplay (which has
              some caveats, see above), run the command:



              ffplay rtp://127.0.0.1:1234 Note that rtp by default uses UDP, which,
              for large streams, can cause packet loss. See the "point to point"
              section in this document for hints if this ever happens to you.







              share|improve this answer


























                0












                0








                0







                You can use FFmpeg to stream a single audio stream using the RTP protocol. Here is more information here:



                https://trac.ffmpeg.org/wiki/StreamingGuide#StreamingasimpleRTPaudiostreamfromFFmpeg




                FFmpeg can stream a single stream using the ​RTP protocol. In order to
                avoid buffering problems on the other hand, the streaming should be
                done through the -re option, which means that the stream will be
                streamed in real-time (i.e. it slows it down to simulate a live
                streaming ​source.



                For example the following command will generate a signal, and will
                stream it to the port 1234 on localhost:



                ffmpeg -re -f lavfi -i aevalsrc="sin(400*2*PI*t)" -ar 8000 -f mulaw -f
                rtp rtp://127.0.0.1:1234 To play the stream with ffplay (which has
                some caveats, see above), run the command:



                ffplay rtp://127.0.0.1:1234 Note that rtp by default uses UDP, which,
                for large streams, can cause packet loss. See the "point to point"
                section in this document for hints if this ever happens to you.







                share|improve this answer













                You can use FFmpeg to stream a single audio stream using the RTP protocol. Here is more information here:



                https://trac.ffmpeg.org/wiki/StreamingGuide#StreamingasimpleRTPaudiostreamfromFFmpeg




                FFmpeg can stream a single stream using the ​RTP protocol. In order to
                avoid buffering problems on the other hand, the streaming should be
                done through the -re option, which means that the stream will be
                streamed in real-time (i.e. it slows it down to simulate a live
                streaming ​source.



                For example the following command will generate a signal, and will
                stream it to the port 1234 on localhost:



                ffmpeg -re -f lavfi -i aevalsrc="sin(400*2*PI*t)" -ar 8000 -f mulaw -f
                rtp rtp://127.0.0.1:1234 To play the stream with ffplay (which has
                some caveats, see above), run the command:



                ffplay rtp://127.0.0.1:1234 Note that rtp by default uses UDP, which,
                for large streams, can cause packet loss. See the "point to point"
                section in this document for hints if this ever happens to you.








                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Dec 3 '18 at 23:10









                Ray HunterRay Hunter

                10.7k23845




                10.7k23845
































                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53480692%2frtp-audio-stream-player%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Wiesbaden

                    Marschland

                    Dieringhausen