As the javafxports Media is not yet implemented I'm looking to use the Android Native MediaPlayer instead. Does anyone know how to do this.
If you have a look at the GoNative sample here (docs and code), you'll find a way to add Android native code to your JavaFX project.
This is a simple example of adding android.media.MediaPlayer to a JavaFX project using the Gluon plugin.
Based on a Single View project, let's add first an interface with the required audio method signatures:
public interface NativeAudioService {
void play();
void pause();
void resume();
void stop();
}
Now in our View we can create the buttons to call those methods based on an instance of AndroidNativeAudio class that implements the NativeAudioService interface:
public class BasicView extends View {
private NativeAudioService service;
private boolean pause;
public BasicView(String name) {
super(name);
try {
service = (NativeAudioService) Class.forName("com.gluonhq.nativeaudio.AndroidNativeAudio").newInstance();
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException ex) {
System.out.println("Error " + ex);
}
if (service != null) {
final HBox hBox = new HBox(10,
MaterialDesignIcon.PLAY_ARROW.button(e -> service.play()),
MaterialDesignIcon.PAUSE.button(e -> {
if (!pause) {
service.pause();
pause = true;
} else {
service.resume();
pause = false;
}
}),
MaterialDesignIcon.STOP.button(e -> service.stop()));
hBox.setAlignment(Pos.CENTER);
setCenter(new StackPane(hBox));
} else {
setCenter(new StackPane(new Label("Only for Android")));
}
}
#Override
protected void updateAppBar(AppBar appBar) {
appBar.setNavIcon(MaterialDesignIcon.MUSIC_NOTE.button());
appBar.setTitleText("Native Audio");
}
}
Now, we create the native class under the Android folder. It will make use of the android API. It will try to find the audio file audio.mp3 that we have to place under the /src/android/assets folder:
package com.gluonhq.nativeaudio;
import android.content.res.AssetFileDescriptor;
import android.media.AudioManager;
import android.media.MediaPlayer;
import java.io.IOException;
import javafxports.android.FXActivity;
public class AndroidNativeAudio implements NativeAudioService {
private MediaPlayer mp;
private int currentPosition;
public AndroidNativeAudio() { }
#Override
public void play() {
currentPosition = 0;
try {
if (mp != null) {
stop();
}
mp = new MediaPlayer();
AssetFileDescriptor afd = FXActivity.getInstance().getAssets().openFd("audio.mp3");
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
mp.setAudioStreamType(AudioManager.STREAM_RING);
mp.setOnCompletionListener(mp -> stop());
mp.prepare();
mp.start();
} catch (IOException e) {
System.out.println("Error playing audio resource " + e);
}
}
#Override
public void stop() {
if (mp != null) {
if (mp.isPlaying()) {
mp.stop();
}
mp.release();
mp = null;
}
}
#Override
public void pause() {
if (mp != null) {
mp.pause();
currentPosition = mp.getCurrentPosition();
}
}
#Override
public void resume() {
if (mp != null) {
mp.start();
mp.seekTo(currentPosition);
}
}
}
Finally, we can deploy the project to an Android device running gradlew androidInstall.
The native audio player was used in the following example:
https://gist.github.com/bgmf/d87a2bac0a5623f359637a3da334f980
Beside some prerequisites, the code looks like this:
package my.application;
import my.application.Constants;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.ReadOnlyObjectWrapper;
import org.robovm.apple.avfoundation.AVAudioPlayer;
import org.robovm.apple.foundation.NSErrorException;
import org.robovm.apple.foundation.NSURL;
import org.robovm.apple.foundation.NSURLScheme;
import java.io.File;
import java.util.logging.Level;
import java.util.logging.Logger;
public class NativeAudioServiceIOS extends PathHelperIOS implements NativeAudioService {
private static final Logger LOG = Logger.getLogger(NativeAudioServiceIOS.class.getName());
private static final String DIR_NAME = Constants.OBJECTS_BASE_PATH;
private final ReadOnlyObjectWrapper<Status> status = new ReadOnlyObjectWrapper<>(this, "status", Status.STOP);
private String filename = null;
private AVAudioPlayer player = null;
public NativeAudioServiceIOS() {
super();
}
#Override
public void init(String filename) throws NativeServiceException {
this.filename = filename.startsWith("/") ? filename.substring(1) : filename;
LOG.warning("Called with file: " + filename);
status.set(Status.STOP);
try {
if(!filename.startsWith("/")) filename = "/" + filename;
File fullfile = new File(pathBase.getAbsolutePath() + filename);
if(fullfile.exists()) {
NSURL fullurl = new NSURL(NSURLScheme.File, "", fullfile.getAbsolutePath());
LOG.log(Level.SEVERE, "Loading URL: " + fullurl);
// Create audio player object and initialize with URL to sound
player = new AVAudioPlayer(fullurl);
LOG.log(Level.SEVERE, "Player initialized: " + player);
status.set(Status.STOP);
} else {
LOG.log(Level.WARNING, String.format("Audiofile doesn't exist: %s (%s / %s)",
fullfile.getAbsolutePath(),
pathBase.getAbsolutePath(),
filename));
player = null;
status.set(Status.ERROR);
}
} catch(NSErrorException error) {
LOG.log(Level.SEVERE, "Audio Setup Failed: " + error.toString(), error);
status.set(Status.ERROR);
}
}
#Override
public void play() throws NativeServiceException {
if(player == null) return;
player.play();
status.set(Status.PLAY);
}
#Override
public void pause() throws NativeServiceException {
if(player == null) return;
player.pause();
status.set(Status.PAUSE);
}
#Override
public void resume() throws NativeServiceException {
if(player == null) return;
player.play();
status.set(Status.PLAY);
}
#Override
public void stop() throws NativeServiceException {
if(player == null) return;
player.stop();
player.setCurrentTime(0.0);
status.set(Status.STOP);
}
#Override
public ReadOnlyObjectProperty<Status> statusProperty() {
return status.getReadOnlyProperty();
}
#Override
public Status getStatus() {
return status.get();
}
}
Related
I am trying to make a video player in android.
It plays the 3GP format videos.
But it does not support the mp4 video.Below is my code in android for the same.Why does it not support the mp4 format on the device and emulator?
package com.example.videoplayer;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import org.json.JSONObject;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.StrictMode;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.URLUtil;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Toast;
import android.widget.VideoView;
public class VideoViewDemo extends Activity {
private static final String TAG = "VideoViewDemo";
private VideoView mVideoView;
private EditText mPath;
private ImageButton mPlay;
private ImageButton mPause;
private ImageButton mReset;
private ImageButton mStop;
private String current;
#SuppressLint({ "NewApi", "NewApi", "NewApi" })
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.activity_main);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
mVideoView = (VideoView) findViewById(R.id.surface_view);
mPath = (EditText) findViewById(R.id.path);
mPath.setText("ooklnet.com/files/368/368007/video.mp4");
mPlay = (ImageButton) findViewById(R.id.play);
mPause = (ImageButton) findViewById(R.id.pause);
mReset = (ImageButton) findViewById(R.id.reset);
mStop = (ImageButton) findViewById(R.id.stop);
mPlay.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
playVideo();
}
});
mPause.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
if (mVideoView != null) {
mVideoView.pause();
}
}
});
mReset.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
if (mVideoView != null) {
mVideoView.seekTo(0);
}
}
});
mStop.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
if (mVideoView != null) {
current = null;
mVideoView.stopPlayback();
}
}
});
/*runOnUiThread(new Runnable(){
public void run() {
sleep(2000);
playVideo();
}
});*/
Thread _trd1 = new Thread() {
public void run() {
try {
sleep(2000);
runOnUiThread(new Runnable() {
public void run() {
playVideo();
}
});
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
_trd1.start();
// new DoBackgroundTask().execute();
}
public class DoBackgroundTask extends AsyncTask
<String, Void, String> {
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
}
protected String doInBackground(String... locationNames) {
playVideo();
return null;
}
protected void onPostExecute(String addresses){
}
}
private void playVideo() {
try {
final String path = mPath.getText().toString();
Log.v(TAG, "path: " + path);
if (path == null || path.length() == 0) {
Toast.makeText(VideoViewDemo.this, "File URL/path is empty",
Toast.LENGTH_LONG).show();
} else {
// If the path has not changed, just start the media player
if (path.equals(current) && mVideoView != null) {
mVideoView.start();
mVideoView.requestFocus();
return;
}
current = path;
mVideoView.setVideoPath(getDataSource("ooklnet.com/files/368/368007/video.mp4"));
mVideoView.start();
mVideoView.requestFocus();
}
} catch (Exception e) {
Log.e(TAG, "error: " + e.getMessage(), e);
if (mVideoView != null) {
mVideoView.stopPlayback();
}
}
}
private String getDataSource(String path) throws IOException {
if (!URLUtil.isNetworkUrl(path)) {
return path;
} else {
URL url = new URL(path);
URLConnection cn = url.openConnection();
cn.connect();
InputStream stream = cn.getInputStream();
if (stream == null)
throw new RuntimeException("stream is null");
File temp = File.createTempFile("mediaplayertmp", "dat");
temp.deleteOnExit();
String tempPath = temp.getAbsolutePath();
FileOutputStream out = new FileOutputStream(temp);
byte buf[] = new byte[128];
do {
int numread = stream.read(buf);
if (numread <= 0)
break;
out.write(buf, 0, numread);
} while (true);
try {
stream.close();
} catch (IOException ex) {
Log.e(TAG, "error: " + ex.getMessage(), ex);
}
return tempPath;
}
}
}
Please advise as soon as possible.
Thanks.
The problem might be with the video encoding. Android Froyo and Gingerbread doesn't support H264 formats other than "Baseline" H264. So if your video is Mp4 & H264 encoded make sure its "AVC baseline" encoded. Use some tools like "Media info" in windows/Linux and check your video encoding. Convert the video to Baseline if possible.
An alternative workaround is to skip the Videoview and use a video play intent and redirect the playback to an app. User will be prompted to pick a player to handle the playback. Obviously if the video view cant play the file, the default player also wont be able to handle the file. you can choose some other installed player like Mx-Player which will stream the file perfectly.
Hope that solved your issue.
Try correct video url with protocol: http://www.ooklnet.com/files/368/368007/video.mp4
I'm trying to implement a service to play a stream in background using mediaplayer class.. anyway in some phone (galaxy tab and some LG model) when my app is in background, the sound chops when I open another application... why this? following some tutorial I implemented the service in this way:
import com.somafm.api.PlayListFile;
import com.somafm.api.Playlist;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.IBinder;
import android.os.PowerManager;
import android.util.Log;
public class PlayerBackgroundService extends Service {
static MediaPlayer.OnPreparedListener prepared_listener;
static MediaPlayer.OnBufferingUpdateListener buffering_listener;
static MediaPlayer.OnCompletionListener completion_listener;
static MediaPlayer.OnErrorListener error_listener;
private static Playlist playlist;
private static PlayerController player;
private static StreamProxy proxy;
private static MediaPlayer mp = new MediaPlayer();
static boolean canPlay;
static boolean clean;
static boolean cancelRequest;
static boolean buffering;
static boolean isPlaying;
private static PowerManager.WakeLock powerLock;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate()
{
super.onCreate();
init();
}
public void init()
{
PowerManager pM = (PowerManager) getSystemService(Context.POWER_SERVICE);
powerLock = pM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Prevent sleeping");
powerLock.acquire();
prepared_listener = new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
canPlay = true;
clean = true;
}
};
error_listener = new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.i("!!MEDIAERROR!!", "WHAT " + what + " - " + extra);
canPlay = true;
clean = false;
isPlaying = false;
return true;
}
};
buffering_listener = new MediaPlayer.OnBufferingUpdateListener() {
#Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
Log.i("BUFFERING", "" + percent);
if(percent > 0)
{
if(mp.isPlaying() && !buffering)
{
player.notifyAllBuffering();
buffering = true;
}
}
else
{
if(buffering)
{
player.notifyAllNotBuffering();
buffering = false;
}
}
}
};
completion_listener = new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
//stop();
Log.i("COMPLETED", "COMPLETED");
}
};
}
public synchronized static void start(){
mp.start();
isPlaying = true;
}
public synchronized static void prepare(){
canPlay = false;
clean = true;
proxy = new StreamProxy();
proxy.init();
proxy.start();
if (playlist == null)
{
clean = false;
proxy.stop();
return;
}
int i = 0;
String proxyUrl = "";
playlist.fetchContent();
PlayListFile[] urlsToPlay = playlist.getFiles();
if (urlsToPlay == null)
{
clean = false;
proxy.stop();
return;
}
if (urlsToPlay.length == 0)
{
clean = false;
proxy.stop();
return;
}
do{
try{
proxyUrl = String.format("http://127.0.0.1:%d/%s", proxy
.getPort(), Uri.parse(urlsToPlay[i].getUrl()));
i++;
Log.i("Trying link", "" + urlsToPlay.length);
mp = new MediaPlayer();
mp.setOnPreparedListener(prepared_listener);
mp.setOnBufferingUpdateListener(buffering_listener);
mp.setOnErrorListener(error_listener);
mp.setOnCompletionListener(completion_listener);
mp.setDataSource(proxyUrl);
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.prepare();
}catch(Exception ex)
{
clean = false;
ex.printStackTrace();
}
if(cancelRequest == true)
{
clean = true;
return;
}
if(i >= urlsToPlay.length)
canPlay = true;
}while(canPlay == false);
if(clean == false && proxy != null)
proxy.stop();
}
public synchronized static void stop() {
if(proxy != null)
proxy.stop();
if(mp != null)
mp.stop();
isPlaying = false;
}
public synchronized static void loadPlaylist(Playlist playlist) {
PlayerBackgroundService.playlist = playlist;
}
public synchronized static void registerPlayer(PlayerController player) {
PlayerBackgroundService.player = player;
}
#Override
public void onDestroy() {
super.onDestroy();
if (powerLock != null && powerLock.isHeld())
powerLock.release();
}
}
And launch it in this way:
this.startService(new Intent(appcontext, PlayerBackgroundService.class));
maybe my class is wrong.. can you help me?
Thanks in advance
You need to manually stop and resume the audio which has been played in Media player using pause and resume Method of activity , take a look at this,
#Override
protected void onResume() {
super.onResume();
if (mediaPlayer != null) {
mediaPlayer.start();
}
}
protected void onPause() {
super.onPause();
if (mediaPlayer != null) {
mediaPlayer.pause();
if (isFinishing()) {
mediaPlayer.stop();
mediaPlayer.release();
}
}
I am recording audio using AudioRecord class.I want to record audio into a particular file in my asset folder or resource folder.I think there is no problem in recording.but while reading buffer it is showing some problem(it is throwing NullPointerException).Can anyone suggest what may be the problem?
You can not save file inside Asset folder. Assets folder is read only instead of it you will have to save it in the internal or external storage of your device
Below there is a core to record the media file.
package com.example.media.record;
import java.io.File;
import java.io.IOException;
import android.app.Activity;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;
public class MediaRecorderActivity extends Activity implements OnClickListener {
Button btnPlay;
Button btnRecord;
ProgressBar progress;
MediaPlayer mPlayer;
MediaRecorder mRecorder;
String mFileName;
boolean mStartRecording = true;
boolean mStartPlaying = true;
Thread mThreadProgress;
int duration = 1;
private void onRecord(boolean start) {
if(start) {
startRecording();
}else {
stopRecording();
}
}
private void onPlay(boolean start) {
if(start) {
startPlaying();
}else {
stopPlaying();
}
}
private void startRecording() {
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFile(mFileName);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mRecorder.setOnErrorListener(errorListenerForRecorder);
try {
mRecorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
mRecorder.start();
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "Error :: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
private void stopRecording() {
if(mRecorder != null) {
mRecorder.stop();
mRecorder.release();
mRecorder = null;
}
}
private void startPlaying() {
mPlayer = new MediaPlayer();
try {
mPlayer.setDataSource(mFileName);
mPlayer.setOnCompletionListener(completionListener);
mPlayer.setOnErrorListener(errorListenerForPlayer);
mPlayer.prepare();
mPlayer.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void stopPlaying() {
if(mPlayer != null) {
mPlayer.stop();
mPlayer.release();
mPlayer = null;
}
}
OnCompletionListener completionListener = new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
btnRecord.setEnabled(true);
btnPlay.setText("Start playing");
mStartPlaying = !mStartPlaying;
}
};
OnErrorListener errorListenerForPlayer = new OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Toast.makeText(getApplicationContext(), "Error during playing file", 3000).show();
return false;
}
};
android.media.MediaRecorder.OnErrorListener errorListenerForRecorder = new android.media.MediaRecorder.OnErrorListener() {
#Override
public void onError(MediaRecorder mr, int what, int extra) {
Toast.makeText(getApplicationContext(), "Error during recoding file", 3000).show();
}
};
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnPlay = (Button)findViewById(R.id.btnPlay);
btnRecord = (Button)findViewById(R.id.btnRecord);
progress = (ProgressBar)findViewById(R.id.progressRecorder);
mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
mFileName += "/audiorecordtest.3gp";
File file = new File(mFileName);
if(!file.exists()) btnPlay.setEnabled(false);
btnPlay.setOnClickListener(this);
btnRecord.setOnClickListener(this);
}
#Override
protected void onPause() {
super.onPause();
if(mRecorder != null) {
mRecorder.stop();
}
if(mPlayer != null) {
mPlayer.pause();
}
}
#Override
protected void onResume() {
super.onResume();
if(mRecorder != null) {
mRecorder.start();
}
if(mPlayer != null) {
mPlayer.start();
}
}
#Override
protected void onStop() {
super.onStop();
if(mRecorder != null) {
mRecorder.stop();
}
if(mPlayer != null) {
mPlayer.stop();
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if(mRecorder != null) {
mRecorder.release();
mRecorder = null;
}
if(mPlayer != null) {
mPlayer.release();
mPlayer = null;
}
}
#Override
public void onClick(View v) {
if(v == btnPlay) {
onPlay(mStartPlaying);
if(mStartPlaying) {
duration = mPlayer.getDuration();
mThreadProgress = new ThreadProgress();
mThreadProgress.start();
((Button)v).setText("Stop Playing");
btnRecord.setEnabled(false);
}
else {
((Button)v).setText("Start Playing");
btnRecord.setEnabled(true);
if(mThreadProgress != null && !mThreadProgress.isAlive()) mThreadProgress.stop();
// t.interrupt();
}
mStartPlaying = !mStartPlaying;
} else if(v == btnRecord) {
onRecord(mStartRecording);
if(mStartRecording) {
mThreadProgress = new ThreadProgress();
mThreadProgress.start();
((Button)v).setText("Stop Recording");
btnPlay.setEnabled(false);
// t.start();
}
else {
((Button)v).setText("Start Recording");
btnPlay.setEnabled(true);
// t.interrupt();
if(mThreadProgress != null && !mThreadProgress.isAlive()) mThreadProgress.stop();
}
mStartRecording = !mStartRecording;
}
}
Handler handler = new Handler(new Callback() {
#Override
public boolean handleMessage(final Message msg) {
if(msg.what == 0) {
runOnUiThread(new Runnable() {
public void run() {
progress.setProgress(msg.arg1);
}
});
}
return false;
}
});
public class ThreadProgress extends Thread implements Runnable {
public int i = 0;
#Override
public void run() {
while((!this.isInterrupted() && mPlayer != null && mPlayer.isPlaying()) || (!this.isInterrupted() && mRecorder != null)) {
try {
if(duration == 1) i+=1;
else i += 100000 /duration;
Message message = new Message();
message.what = 0;
message.arg1 = i;
handler.sendMessage(message);
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
This is the example you can record audio as well as play audio
You can store recorded file in following places
1) File directory of your app
2) External directory(SD card)
3) Network
I am using SurfaceView to play streaming video and Media Player for streaming video. Can any one tell me how can I place media controller in surfaceview?
Here's my code:
package com.menu.donationvideos;
import android.app.Activity;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.media.MediaPlayer.OnVideoSizeChangedListener;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.MediaController;
import android.widget.MediaController.MediaPlayerControl;
import android.widget.Toast;
import android.widget.VideoView;
import com.menu.R;
public class VideoPlay extends Activity implements OnBufferingUpdateListener, OnCompletionListener,
OnPreparedListener, OnVideoSizeChangedListener, SurfaceHolder.Callback
{
private static final String TAG = "MediaPlayerDemo";
private int mVideoWidth;
private int mVideoHeight;
SurfaceHolder holder;
VideoInfo videoInfo;
String pos,videoURL;
private MediaPlayer mMediaPlayer;
private SurfaceView mPreview;
private String path;
private boolean mIsVideoSizeKnown = false;
private boolean mIsVideoReadyToBePlayed = false;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.video_play);
Bundle bundle=new Bundle();
bundle=this.getIntent().getExtras();
pos=bundle.getString("position");
videoInfo=VideoList.m_video.get(Integer.parseInt(pos));
videoURL=videoInfo.getVideoFile();
try
{
mPreview = (SurfaceView)findViewById(R.id.mySurfaceView);
holder=mPreview.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
catch(Exception e)
{
e.printStackTrace();
}
}
private void playVideo()
{
doCleanUp();
try
{
path = videoURL;
if (path == "")
{
Toast.makeText(VideoPlay.this,"URL Not found", Toast.LENGTH_LONG).show();
}
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDataSource(path);
mMediaPlayer.setDisplay(holder);
mMediaPlayer.prepare();
mMediaPlayer.setOnBufferingUpdateListener(this);
mMediaPlayer.setOnCompletionListener(this);
mMediaPlayer.setOnPreparedListener(this);
mMediaPlayer.setScreenOnWhilePlaying(true);
mMediaPlayer.setOnVideoSizeChangedListener(this);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
catch (Exception e)
{
e.printStackTrace();
}
}
public void onBufferingUpdate(MediaPlayer arg0, int percent)
{
Log.d(TAG,"Buffering:"+percent);
}
public void onCompletion(MediaPlayer arg0)
{
Log.d(TAG, "onCompletion called");
finish();
}
public void onVideoSizeChanged(MediaPlayer mp, int width, int height)
{
Log.v(TAG, "onVideoSizeChanged called");
if (width == 0 || height == 0)
{
Log.e(TAG, "invalid video width(" + width + ") or height(" + height + ")");
return;
}
mIsVideoSizeKnown = true;
mVideoWidth = width;
mVideoHeight = height;
if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown)
{
startVideoPlayback();
}
}
public void onPrepared(MediaPlayer mediaplayer)
{
Log.d(TAG, "onPrepared called");
mIsVideoReadyToBePlayed = true;
if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown)
{
startVideoPlayback();
}
}
public void surfaceChanged(SurfaceHolder surfaceholder, int i, int j, int k)
{
Log.d(TAG, "surfaceChanged called");
}
public void surfaceDestroyed(SurfaceHolder surfaceholder)
{
Log.d(TAG, "surfaceDestroyed called");
}
public void surfaceCreated(SurfaceHolder holder)
{
Log.d(TAG, "surfaceCreated called");
playVideo();
}
#Override
protected void onPause()
{
super.onPause();
releaseMediaPlayer();
doCleanUp();
}
#Override
protected void onDestroy()
{
super.onDestroy();
releaseMediaPlayer();
doCleanUp();
}
private void releaseMediaPlayer()
{
if (mMediaPlayer != null)
{
mMediaPlayer.release();
mMediaPlayer = null;
}
}
private void doCleanUp()
{
mVideoWidth = 0;
mVideoHeight = 0;
mIsVideoReadyToBePlayed = false;
mIsVideoSizeKnown = false;
}
private void startVideoPlayback()
{
Log.v(TAG, "startVideoPlayback");
holder.setFixedSize(mVideoWidth, mVideoHeight);
mMediaPlayer.start();
}
}
do {
numread = stream.read(buf);
if (numread <= 0)
break;
totalBytesRead += numread;
totalKbRead = totalBytesRead/1000;
Log.e(getClass().getName(),"Buffered byte: " +totalBytesRead+"");
if(totalBytesRead>=100000){
if(mediaPlayer!=null){
int dura = mediaPlayer.getDuration();
if(mediaPlayer.getDuration()>=90000){
isInterrupted =false;
stream.close();
out.close();
out.flush();
break;
}
}
}
This is my code but I realized that media player doesnt start until streaming in progress.
I would suggest you take a look at the source code of VideoView, which combines everything at first place (or use VideoView instead of MediaPlayer itself)
hey nirav this code try it for media streaming
package com.pocketjourney.media;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Handler;
import android.util.Log;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.TextView;
/**
* MediaPlayer does not yet support streaming from external URLs so this class provides a pseudo-streaming function
* by downloading the content incrementally & playing as soon as we get enough audio in our temporary storage.
*/
public class StreamingMediaPlayer {
private static final int INTIAL_KB_BUFFER = 96*10/8;//assume 96kbps*10secs/8bits per byte
private TextView textStreamed;
private ImageButton playButton;
private ProgressBar progressBar;
// Track for display by progressBar
private long mediaLengthInKb, mediaLengthInSeconds;
private int totalKbRead = 0;
// Create Handler to call View updates on the main UI thread.
private final Handler handler = new Handler();
private MediaPlayer mediaPlayer;
private File downloadingMediaFile;
private boolean isInterrupted;
private Context context;
private int counter = 0;
public StreamingMediaPlayer(Context context,TextView textStreamed, ImageButton playButton, Button streamButton,ProgressBar progressBar)
{
this.context = context;
this.textStreamed = textStreamed;
this.playButton = playButton;
this.progressBar = progressBar;
}
/**
* Progressivly download the media to a temporary location and update the MediaPlayer as new content becomes available.
*/
public void startStreaming(final String mediaUrl, long mediaLengthInKb, long mediaLengthInSeconds) throws IOException {
this.mediaLengthInKb = mediaLengthInKb;
this.mediaLengthInSeconds = mediaLengthInSeconds;
Runnable r = new Runnable() {
public void run() {
try {
downloadAudioIncrement(mediaUrl);
} catch (IOException e) {
Log.e(getClass().getName(), "Unable to initialize the MediaPlayer for fileUrl=" + mediaUrl, e);
return;
}
}
};
new Thread(r).start();
}
/**
* Download the url stream to a temporary location and then call the setDataSource
* for that local file
*/
public void downloadAudioIncrement(String mediaUrl) throws IOException {
URLConnection cn = new URL(mediaUrl).openConnection();
cn.connect();
InputStream stream = cn.getInputStream();
if (stream == null) {
Log.e(getClass().getName(), "Unable to create InputStream for mediaUrl:" + mediaUrl);
}
downloadingMediaFile = new File(context.getCacheDir(),"downloadingMedia.dat");
// Just in case a prior deletion failed because our code crashed or something, we also delete any previously
// downloaded file to ensure we start fresh. If you use this code, always delete
// no longer used downloads else you'll quickly fill up your hard disk memory. Of course, you can also
// store any previously downloaded file in a separate data cache for instant replay if you wanted as well.
if (downloadingMediaFile.exists()) {
downloadingMediaFile.delete();
}
FileOutputStream out = new FileOutputStream(downloadingMediaFile);
byte buf[] = new byte[16384];
int totalBytesRead = 0, incrementalBytesRead = 0;
do {
int numread = stream.read(buf);
if (numread <= 0)
break;
out.write(buf, 0, numread);
totalBytesRead += numread;
incrementalBytesRead += numread;
totalKbRead = totalBytesRead/1000;
testMediaBuffer();
fireDataLoadUpdate();
} while (validateNotInterrupted());
stream.close();
if (validateNotInterrupted()) {
fireDataFullyLoaded();
}
}
private boolean validateNotInterrupted() {
if (isInterrupted) {
if (mediaPlayer != null) {
mediaPlayer.pause();
//mediaPlayer.release();
}
return false;
} else {
return true;
}
}
/**
* Test whether we need to transfer buffered data to the MediaPlayer.
* Interacting with MediaPlayer on non-main UI thread can causes crashes to so perform this using a Handler.
*/
private void testMediaBuffer() {
Runnable updater = new Runnable() {
public void run() {
if (mediaPlayer == null) {
// Only create the MediaPlayer once we have the minimum buffered data
if ( totalKbRead >= INTIAL_KB_BUFFER) {
try {
startMediaPlayer();
} catch (Exception e) {
Log.e(getClass().getName(), "Error copying buffered conent.", e);
}
}
} else if ( mediaPlayer.getDuration() - mediaPlayer.getCurrentPosition() <= 1000 ){
// NOTE: The media player has stopped at the end so transfer any existing buffered data
// We test for < 1second of data because the media player can stop when there is still
// a few milliseconds of data left to play
transferBufferToMediaPlayer();
}
}
};
handler.post(updater);
}
private void startMediaPlayer() {
try {
File bufferedFile = new File(context.getCacheDir(),"playingMedia" + (counter++) + ".dat");
// We double buffer the data to avoid potential read/write errors that could happen if the
// download thread attempted to write at the same time the MediaPlayer was trying to read.
// For example, we can't guarantee that the MediaPlayer won't open a file for playing and leave it locked while
// the media is playing. This would permanently deadlock the file download. To avoid such a deadloack,
// we move the currently loaded data to a temporary buffer file that we start playing while the remaining
// data downloads.
moveFile(downloadingMediaFile,bufferedFile);
Log.e(getClass().getName(),"Buffered File path: " + bufferedFile.getAbsolutePath());
Log.e(getClass().getName(),"Buffered File length: " + bufferedFile.length()+"");
mediaPlayer = createMediaPlayer(bufferedFile);
// We have pre-loaded enough content and started the MediaPlayer so update the buttons & progress meters.
mediaPlayer.start();
startPlayProgressUpdater();
playButton.setEnabled(true);
} catch (IOException e) {
Log.e(getClass().getName(), "Error initializing the MediaPlayer.", e);
return;
}
}
private MediaPlayer createMediaPlayer(File mediaFile)
throws IOException {
MediaPlayer mPlayer = new MediaPlayer();
mPlayer.setOnErrorListener(
new MediaPlayer.OnErrorListener() {
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.e(getClass().getName(), "Error in MediaPlayer: (" + what +") with extra (" +extra +")" );
return false;
}
});
// It appears that for security/permission reasons, it is better to pass a FileDescriptor rather than a direct path to the File.
// Also I have seen errors such as "PVMFErrNotSupported" and "Prepare failed.: status=0x1" if a file path String is passed to
// setDataSource(). So unless otherwise noted, we use a FileDescriptor here.
FileInputStream fis = new FileInputStream(mediaFile);
mPlayer.setDataSource(fis.getFD());
mPlayer.prepare();
return mPlayer;
}
/**
* Transfer buffered data to the MediaPlayer.
* NOTE: Interacting with a MediaPlayer on a non-main UI thread can cause thread-lock and crashes so
* this method should always be called using a Handler.
*/
private void transferBufferToMediaPlayer() {
try {
// First determine if we need to restart the player after transferring data...e.g. perhaps the user pressed pause
boolean wasPlaying = mediaPlayer.isPlaying();
int curPosition = mediaPlayer.getCurrentPosition();
// Copy the currently downloaded content to a new buffered File. Store the old File for deleting later.
File oldBufferedFile = new File(context.getCacheDir(),"playingMedia" + counter + ".dat");
File bufferedFile = new File(context.getCacheDir(),"playingMedia" + (counter++) + ".dat");
// This may be the last buffered File so ask that it be delete on exit. If it's already deleted, then this won't mean anything. If you want to
// keep and track fully downloaded files for later use, write caching code and please send me a copy.
bufferedFile.deleteOnExit();
moveFile(downloadingMediaFile,bufferedFile);
// Pause the current player now as we are about to create and start a new one. So far (Android v1.5),
// this always happens so quickly that the user never realized we've stopped the player and started a new one
mediaPlayer.pause();
// Create a new MediaPlayer rather than try to re-prepare the prior one.
mediaPlayer = createMediaPlayer(bufferedFile);
mediaPlayer.seekTo(curPosition);
// Restart if at end of prior buffered content or mediaPlayer was previously playing.
// NOTE: We test for < 1second of data because the media player can stop when there is still
// a few milliseconds of data left to play
boolean atEndOfFile = mediaPlayer.getDuration() - mediaPlayer.getCurrentPosition() <= 1000;
if (wasPlaying || atEndOfFile){
mediaPlayer.start();
}
// Lastly delete the previously playing buffered File as it's no longer needed.
oldBufferedFile.delete();
}catch (Exception e) {
Log.e(getClass().getName(), "Error updating to newly loaded content.", e);
}
}
private void fireDataLoadUpdate() {
Runnable updater = new Runnable() {
public void run() {
textStreamed.setText((totalKbRead + " Kb read"));
float loadProgress = ((float)totalKbRead/(float)mediaLengthInKb);
progressBar.setSecondaryProgress((int)(loadProgress*100));
}
};
handler.post(updater);
}
private void fireDataFullyLoaded() {
Runnable updater = new Runnable() {
public void run() {
transferBufferToMediaPlayer();
// Delete the downloaded File as it's now been transferred to the currently playing buffer file.
downloadingMediaFile.delete();
textStreamed.setText(("Audio full loaded: " + totalKbRead + " Kb read"));
}
};
handler.post(updater);
}
public MediaPlayer getMediaPlayer() {
return mediaPlayer;
}
public void startPlayProgressUpdater() {
float progress = (((float)mediaPlayer.getCurrentPosition()/1000)/mediaLengthInSeconds);
progressBar.setProgress((int)(progress*100));
if (mediaPlayer.isPlaying()) {
Runnable notification = new Runnable() {
public void run() {
startPlayProgressUpdater();
}
};
handler.postDelayed(notification,1000);
}
}
public void interrupt() {
playButton.setEnabled(false);
isInterrupted = true;
validateNotInterrupted();
}
/**
* Move the file in oldLocation to newLocation.
*/
public void moveFile(File oldLocation, File newLocation)
throws IOException {
if ( oldLocation.exists( )) {
BufferedInputStream reader = new BufferedInputStream( new FileInputStream(oldLocation) );
BufferedOutputStream writer = new BufferedOutputStream( new FileOutputStream(newLocation, false));
try {
byte[] buff = new byte[8192];
int numChars;
while ( (numChars = reader.read( buff, 0, buff.length ) ) != -1) {
writer.write( buff, 0, numChars );
}
} catch( IOException ex ) {
throw new IOException("IOException when transferring " + oldLocation.getPath() + " to " + newLocation.getPath());
} finally {
try {
if ( reader != null ){
writer.close();
reader.close();
}
} catch( IOException ex ){
Log.e(getClass().getName(),"Error closing files when transferring " + oldLocation.getPath() + " to " + newLocation.getPath() );
}
}
} else {
throw new IOException("Old location does not exist when transferring " + oldLocation.getPath() + " to " + newLocation.getPath() );
}
}
}
I want to make application that gives me the list of audio files available in my SDCard and then i should be able to play that audio file from my application. And even pause resume audio playback etc. and function..
Any help on that?
You can see the below code for streaming audio from URL
private void playVideo() {
try {
final String path = "http://www.a1freesoundeffects.com/animals12557/catmeow.wav";
// If the path has not changed, just start the media player
if (path.equals(current) && mp != null) {
mp.start();
return;
}
current = path;
// Create a new media player and set the listeners
mp = new MediaPlayer();
mp.setDataSource(path);
mp.prepare();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
} catch (Exception e) {
if (mp != null) {
mp.stop();
mp.release();
}
}
}
You can try this way.
class Mp3Filter implements FilenameFilter {
public boolean accept(File dir, String name) {
return (name.endsWith(".mp3"));
}
}
public class AudioPlayer extends ListActivity implements OnClickListener{
private static final String MEDIA_PATH = new String("/sdcard/backup/songs");
private List<String> songs = new ArrayList<String>();
private MediaPlayer mp = new MediaPlayer();
private int currentPosition = 0;
private static final String TAG = "Audio Player Demo ";
private static final String isPlaying = "Media is Playing";
private static final String notPlaying = "Media has stopped Playing";
Button playerButton;
public void onClick(View v) {
if (v.getId() == R.id.play) {
playPause();
}
}
#Override
public void onCreate(Bundle icicle) {
try {
super.onCreate(icicle);
setContentView(R.layout.songlist);
playerButton = (Button) this.findViewById(R.id.play);
playerButton.setText(R.string.stop_label);
playerButton.setOnClickListener(this);
updateSongList();
//demoPlay();
} catch (NullPointerException e) {
Log.v(getString(R.string.app_name), e.getMessage());
}
}
public void updateSongList() {
File home = new File(MEDIA_PATH);
if (home.listFiles( new Mp3Filter()).length > 0) {
for (File file : home.listFiles( new Mp3Filter())) {
songs.add(file.getName());
}
ArrayAdapter<String> songList = new ArrayAdapter<String>(this,R.layout.song_item,songs);
setListAdapter(songList);
}
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
currentPosition = position;
playSong(MEDIA_PATH + songs.get(position));
}
private void playSong(String songPath) {
try {
mp.reset();
mp.setDataSource(songPath);
mp.prepare();
mp.start();
// Setup listener so next song starts automatically
mp.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer arg0) {
nextSong();}
});
} catch(IOException e) {
Log.v(getString(R.string.app_name), e.getMessage());
}
}
private void nextSong() {
if (++currentPosition >= songs.size()) {
// Last song, just reset currentPosition
currentPosition = 0;
// playSong(MEDIA_PATH + songs.get(currentPosition));
} else {
// Play next song
playSong(MEDIA_PATH + songs.get(currentPosition));
}
}
private void demoPause(){
mp.pause();
playerButton.setText(R.string.play_label);
Toast.makeText(this, notPlaying, Toast.LENGTH_LONG).show();
Log.d(TAG, notPlaying);
}
// Initiate playing the media player
private void demoPlay(){
mp.start();
playerButton.setText(R.string.stop_label);
Toast.makeText(this, isPlaying, Toast.LENGTH_LONG).show();
Log.d(TAG, isPlaying);
}
// Toggle between the play and pause
private void playPause() {
if(mp.isPlaying()) {
demoPause();
} else {
demoPlay();
}
}
}