Reputation:
I made a simple test to make MediaPlayer play some live streaming data via localSocket.
class IOLoop extends Thread
{
@Override
public void run()
{
try
{
MediaPlayer mPlayer = new MediaPlayer();
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
System.out.println("----======MediaPlayer()============-- ");
LocalSocket receiver = new LocalSocket();
System.out.println("----======new LocalSocket()============-- ");
FileDescriptor fd = receiver.getFileDescriptor();
System.out.println("----fd============-- ");
mPlayer.setDataSource(fd); //<-- error
mPlayer.prepare();
System.out.println("----=========mPlayer set===============-- ");
}
catch (IOException e)
{//
}
}
}
IOLoop io00 = new IOLoop();
io00.start();
This code fails, with IllegalArgumentException
02-14 05:16:46.418 20424-20436/com.example.app I/System.out﹕ ----fd============--
02-14 05:16:46.426 20424-20436/com.example.app W/dalvikvm﹕ threadid=10: thread exiting with uncaught exception (group=0xa61ea908)
02-14 05:16:46.426 20424-20436/com.example.app E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-197
java.lang.IllegalArgumentException
at android.media.MediaPlayer.setDataSource(Native Method)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:976)
at com.example.app.MainActivity$1IOLoop.run(MainActivity.java:51)
so googled.
Basically, they say LocalSocket FileDescriptor is not seekable so not adequate for the data source.
However, according to AndroidDeveloper-Media Playback
http://developer.android.com/guide/topics/media/mediaplayer.html
It clearly stated:
The Android multimedia framework includes support for playing variety of common media types, so that you can easily integrate audio, video and images into your applications. You can play audio or video from media files stored in your application's resources (raw resources), from standalone files in the filesystem, or from a data stream arriving over a network connection, all using MediaPlayer APIs.
So, it's a strange situation.
Also, there is voice chat apps like LINE
etc. What is the workaround?
Any thought? Thank you.
EDIT:
found a similar topic:
Can I use MediaPlayer play video from stream line
How do you play Android InputStream on MediaPlayer?
https://code.google.com/p/aacdecoder-android/
What a mess..
EDIT2
This is a real good project to illustrate these area.
https://github.com/fyhertz/libstreaming
I think MediaCodec
is the way to go instead of MediaRecorder etc.
Upvotes: 3
Views: 3114
Reputation: 329
When using the version of MediaPlayer.setDataSource() that takes a FileDescriptor, MediaPlayer expects that file descriptor to be a regular seekable file. A socket is not seekable.
The "data stream arriving over a network connection" bit you quoted from the documentation refers to http/rtsp streaming, so you can either point it at a remote server URL, or implement a local server and then do something like mPlayer.setDataSource("http://localhost:12345")
Upvotes: 0
Reputation: 83
Don't use media player. Just take in the microphone input and send it to the client who is at the receiver end of the voice chat. For example to send the voice:
protected String doInBackground() throws Exception {
AudioFormat af = new AudioFormat(8000.0f,8,1,true,false);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, af);
TargetDataLine microphone = (TargetDataLine)AudioSystem.getLine(info);
microphone.open(af);
Socket conn = new Socket(SERVER,3000);
microphone.start();
DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
int bytesRead = 0;
byte[] soundData = new byte[1];
Thread inThread = new Thread(new SoundReceiver(conn));
inThread.start();
while(bytesRead != -1)
{
bytesRead = microphone.read(soundData, 0, soundData.length);
if(bytesRead >= 0)
{
dos.write(soundData, 0, bytesRead);
}
}
// TODO Auto-generated method stub
return null;
}
}
To receive the voice:
public SoundReceiver(Socket conn) throws Exception
{
connection = conn;
soundIn = new DataInputStream(connection.getInputStream());
AudioFormat af = new AudioFormat(8000.0f,8,1,true,false);
DataLine.Info info = new DataLine.Info(SourceDataLine.class, af);
inSpeaker = (SourceDataLine)AudioSystem.getLine(info);
inSpeaker.open(af);
}
public void run()
{
int bytesRead = 0;
byte[] inSound = new byte[1];
inSpeaker.start();
while(bytesRead != -1)
{
try{bytesRead = soundIn.read(inSound, 0, inSound.length);} catch (Exception e){}
if(bytesRead >= 0)
{
inSpeaker.write(inSound, 0, bytesRead);
}
}
}
Upvotes: 1