I have a method which I am calling from onCreate( main thread). Inside the method I am calling one more method and a Runnable that calls the same method repeatedly. This is how it looks,
public void start() {
try {
if (start == 0) {
playpause.setBackgroundDrawable(getResources().getDrawable(
R.drawable.play));
initialPoiPlayStatus = true;
playAudio();
}
if (play) {
if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
// for displaying view stub
poi = listOfPOI.get(j);
int pos = mMediaPlayer.getCurrentPosition();
int convSeconds = -1;
convSeconds = ((int) (pos) / 1000);
// displaying the you tube pop up based on the parsed value
// from the plist
youTube(convSeconds);
// call the method to change the image while the audio is
// playing
changeImage();
seek_bar.setProgress(current_position);
notification = new Runnable() {
public void run() {
start();
}
};
handler.postDelayed(notification, 1000);
} else {
if (j != (listOfPOI.size() - 1)) {
firstPlay = true;
initialPoiPlayStatus = true;
j++;
playAudio();
start();
// retrieve mascot info
if (isNetworkAvailable() == true) {
receiveResponse();
} else {
}
} else {
threadHandler.sendEmptyMessage(0);
}
}
}
} catch (Exception e) {
System.out.println(poi.getPlistPath());
e.printStackTrace();
}
}
Now inside youtube,
private void youTube(int convSeconds) {
frameLayout = (FrameLayout) findViewById(R.id.frameLayout);
youtubeWebView = (WebView) findViewById(R.id.youtubewebView);
try {
if (poi.getIsYoutubePresent().equals("true")) {
//mMediaPlayer.pause();
isNetworkAvailable();
if (isNetworkAvailable() == true) {
String startTimeyoutube = poi.getYoutubestartTime();
Integer youTubeStartTime = Integer
.parseInt(startTimeyoutube);
if (convSeconds == youTubeStartTime) {
if (frameLayout.getVisibility() == View.GONE) {
frameLayout.setVisibility(View.VISIBLE);
slideUp = AnimationUtils.loadAnimation(this,
R.anim.slide_up);
frameLayout.startAnimation(slideUp);
}
final String youTubeurl = poi.getLink();
WebSettings websets = youtubeWebView.getSettings();
websets.setJavaScriptEnabled(true);
registerForContextMenu(youtubeWebView);
youtubeWebView
.setWebViewClient(new ItemsWebViewClient());
youtubeWebView.loadUrl(youTubeurl);
youtubeWebView.getSettings().setLayoutAlgorithm(
LayoutAlgorithm.SINGLE_COLUMN);
firstPlay = false;
initialPoiPlayStatus = false;
paused = true;
play = false;
playpause.setBackgroundDrawable(getResources().getDrawable(
R.drawable.play));
if (mMediaPlayer.isPlaying()) {
mMediaPlayer.pause();
}
Button goBtn = (Button) findViewById(R.id.youtubeButton);
goBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View V) {
startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse(youTubeurl)));
}
});
ImageButton close = (ImageButton) findViewById(R.id.youtubecloseButton);
close.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
frameLayout.setVisibility(View.GONE);
if (!mMediaPlayer.isPlaying()) {
mMediaPlayer.start();
}
playpause.setBackgroundDrawable(getResources().getDrawable(
R.drawable.pause));
}
});
}
} else {
Toast.makeText(getApplicationContext(), "No network available", Toast.LENGTH_SHORT).show();
}
} else {
frameLayout.setVisibility(View.INVISIBLE);
}
} catch (Exception e) {
e.printStackTrace();
}
return;
}
Here whenever, if (convSeconds == youTubeStartTime) {} becomes true, I am making my audio pause i.e.,
if (mMediaPlayer.isPlaying()) {
mMediaPlayer.pause();
}
And during this time also I want the start() inside Runnable notification should be keep calling. But if I make audio pause this is not happening only. The control is completely lost in this case. And on pressing the Image button close, i am trying to make the audio again to play like this
if (!mMediaPlayer.isPlaying()) {
mMediaPlayer.start();
}
Audio keeps playing now, but the slider/seekbar is not moving because start() inside notification is not getting called.
Do any one know why is it happening like this?
Note: How ever if I don make my mediaplayer not to pause, it works fine. I get the problem onky when I make the audio to pause
I solved the issue finally, it may not be the standard way. But it is working for me.
i just replicated
notification = new Runnable() {
public void run() {
start();
}
};
handler.postDelayed(notification, 1000);
where I am trying to close the image button, i.e.,
ImageButton close = (ImageButton) findViewById(R.id.youtubecloseButton);
close.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
frameLayout.setVisibility(View.GONE);
if (!mMediaPlayer.isPlaying()) {
mMediaPlayer.start();
}
notification = new Runnable() {
public void run() {
start();
}
};
handler.postDelayed(notification, 1000);
}
});
Related
I have a hard issue about audio recording in android. I used AudioTrack to play my sound when I speak to my phone. I want to record a part in my voice if i press button record. For example, I will speak within 10 seconds. However, I only want to record my sound iff I press record button. It can be from 3th second to 8th second. However, my phone need to play my sound during I speaking (from 1st to 10th second).
Currently, I used a thread to play my sound as following code. I created a flag in the recording thread to decide when I will record. When I press button record, the flag will be set true. And I click stop, It will set false and write to file
public class AudioSoundThread extends Thread {
private short[] audioBuffer;
private boolean isRecording = false;
private boolean isSounding = true;
private AudioRecordingHandler handler = null;
private AudioRecord record;
private AudioTrack track;
public AudioSoundThread(AudioTrack mtrack,AudioRecord mrecord,short[] maudioBuffer, AudioRecordingHandler handler) {
this.handler = handler;
this.audioBuffer = maudioBuffer;
this.record=mrecord;
this.track=mtrack;
}
#Override
public void run() {
record.startRecording();
DataOutputStream output =null;
if(isRecording){
output = prepareWriting();
if (output == null) { return; }
}
track.play();
///////////Play during recording
int readSize =0;
while (isSound) {
readSize=record.read(audioBuffer, 0, audioBuffer.length);
if ((readSize == AudioRecord.ERROR_INVALID_OPERATION) ||
(readSize == AudioRecord.ERROR_BAD_VALUE) ||
(readSize <= 0)) {
continue;
}
if(AudioRecord.ERROR_INVALID_OPERATION != readSize){
track.write(audioBuffer, 0, readSize);
}
if(isRecording)
write(output,readSize);
//Finished to write
if(!isRecording&&output!=null)
{
finishWriting(output);
File waveFile = getFile("wav");
try {
rawToWave(mRecording, waveFile);
deleteTempFile(mRecording);
} catch (IOException e) {
Log.e("Error writing file : ", e.getMessage());
}
}
}
record.stop();
record.release();
}
public synchronized void stopSound() {
isSound = false;
}
public synchronized void startSound() {
isSound = true;
}
public synchronized void startRecordingFlag() {
isRecording = true;
}
public synchronized void stopRecording() {
isRecording = false;
}
private void finishWriting(DataOutputStream out) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
if (handler != null) {
handler.onRecordingError();
}
}
}
private DataOutputStream prepareWriting() {
if (mRecording.exists()) { mRecording.delete(); }
DataOutputStream out = null;
try {
out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(mRecording)));
} catch (FileNotFoundException e) {
e.printStackTrace();
if (handler != null) {
handler.onRecordingError();
}
}
return out;
}
In mainActivity, I have two buttons that are play my sound and button recording
private AudioSoundThread recordingThread;
//Play button
btnPlay = (Button) findViewById(R.id.btnPlay);
btnPlay.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
startSounding();
}
});
//Record button
btnRecord = (Button) findViewById(R.id.btnRecord);
btnRecord.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//record();
recordingThread.startRecordingFlag();
}
});
//Stop Record button
btnStopRecord = (Button) findViewById(R.id.btnStopRecord);
btnStopRecord .setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//record();
recordingThread.stopRecording();
}
});
private void startSounding() {
soundingThread = new AudioSoundThread(track,mRecorder,mBuffer,new AudioRecordingHandler() {
});
soundingThread.start();
}
However, my scheme does not work. I think that my flag cannot send to the thread. Could you look at my code and give me one solution?
I have made an android app in that i have implemented play pause function,But I only knows about play ,I don't know how to stop sliding on the same button click,I have used two functions for it as below,play is working but pause is not.!
onClick
if (!flag) {
play();
new Thread(ViewPagerVisibleScroll).start();
ivPlay.setBackgroundResource(R.drawable.pause);
flag = true;
} else {
pause();
new Thread(ViewPagerVisibleScroll).start();
ivPlay.setBackgroundResource(R.drawable.play_btn);
flag = false;
}
play and pause
void play() {
pos = viewPager.getCurrentItem();
ViewPagerVisibleScroll = new Runnable() {
#Override
public void run() {
try {
if (pos <= adapter.getCount() - 1) {
viewPager.setCurrentItem(pos, true);
viewPager.setScrollDurationFactor(6);
handler.postDelayed(this, 3000);
pos++;
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
}
void pause() {
pos = viewPager.getCurrentItem();
ViewPagerVisibleScroll = new Runnable() {
#Override
public void run() {
try {
if (pos <= adapter.getCount() - 1) {
viewPager.setCurrentItem(pos, true);
viewPager.setScrollDurationFactor(6);
handler.postDelayed(this, 300000);
pos++;
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
}
in pause button click :
handler.removeCallbacksAndMessages(ViewPagerVisibleScroll);
Try this
I'm facing with a problem. I want to get duration of video when i 'm recording it.
I can get duration of video when it's finish by code
MediaPlayer mp = MediaPlayer.create(mContext, Uri.parse(video));
if(mp == null)
return -1;
int duration = mp.getDuration();
mp.release();
But i want to get duration everytime when i record video to update to progressbar.
Hope your reply!
private class PlaybackObserver extends Thread {
public void run() {
currentPosition = 0;
try {
while (!killObserverThread) {
Thread.sleep(1000);
currentPosition = (int) mediaPlayer.getCurrentPosition();
runOnUiThread(new Runnable() {
public void run() {
yourProgressBar.setProgress(currentPosition);
}
});
}
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
protected void onDestroy() {
super.onDestroy();
killObserverThread = false;
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
if (task == null || !task.isAlive()) {
task = new PlaybackObserver();
task.start();
}
startPlaying();
}
add a private class for your UiThread to update your seekbar/progressbar. Then start it from onResume()
I want to play a music so I used seekber to show the progress, everything is fine until I press pause button, the seekbar stops but when I press the play button the seekbar does not move, I figured out it is because of getcurrentposition() method, it does not update after pausing, below is my code, what's wrong with it?
#Override
public void onClick(View v) {
try {
if (isPlaying) {
buttonPlayPause.setImageResource(R.drawable.play);
mediaPlayer.pause();
isPlaying = false;
} else {
buttonPlayPause.setImageResource(R.drawable.pause);
isPlaying = true;
mediaPlayer.start();
primarySeekBarProgressUpdater();
}
} catch (Exception e) {
onDestroy();
}
}
});
private void primarySeekBarProgressUpdater() {
try {
seekBarProgress
.setProgress((int) (((float) mediaPlayer
.getCurrentPosition() / mediaFileLengthInMilliseconds) * 100));
if (mediaPlayer.isPlaying()) {
Runnable notification = new Runnable() {
public void run() {
primarySeekBarProgressUpdater();
}
};
handler.postDelayed(notification, 1000);
}
} catch (Exception e) {
onDestroy();
}
}
I am trying to update two TextViews txtName and textEndName. When i debug sometimes it updates the text but rest of the time it does not works. Sometime it works but not not exactly what it is suppose to.What is the problem in the below given code ?
txtName = (TextView) findViewById(R.id.txtstarttag);
textEndName = (TextView) findViewById(R.id.txtendtag);
startSec = (TextView) findViewById(R.id.txtstartsecnd);
endSec = (TextView) findViewById(R.id.txtendsecnd);
btnplay = (ImageButton) findViewById(R.id.btnplay);
btnback = (Button) findViewById(R.id.btnback);
btnback.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
((MyMixes) getParent()).goBack();
}
});
btnplay.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
btnClick();
}
});
splitArray();
Thread t = new Thread()
{
public void run()
{
while (isDownloading)
{
if (Data.filenames != null && Data.filenames.size() >= (getIntent() .getExtras().getInt("index") + 1) && Data.filenames.get(getIntent().getExtras() .getInt("index")) != null)
{
try
{
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(Data.filenames.get(getIntent().getExtras().getInt("index")));
mediaPlayer.prepare();
mediaPlayer.start();
Timer t = new Timer();
handler.postDelayed(onEverySecond, 1000);
mediaPlayer.setOnCompletionListener(new OnCompletionListener()
{
#Override
public void onCompletion(MediaPlayer mp) {
mediaPlayer.seekTo(0);
}
});
boolean isPlaying = mediaPlayer.isPlaying();
if(!isPlaying){
mediaPlayer.pause();
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
isDownloading = false;
}
}
}
}
};
t.start();
}
private Runnable onEverySecond=new Runnable()
{
public void run()
{
if (mediaPlayer.isPlaying())
{
for (int i = index; i < intervals.length; i++)
{
if (i != index && mediaPlayer.getCurrentPosition() > intervals[i])
{
index = i;
handler.dispatchMessage(handler.obtainMessage());
handler.postDelayed(onEverySecond, 1000);
break;
}
}
}
}
};
Handler handler = new Handler()
{
#Override
public void handleMessage(Message msg) {
txtName.setText(arrName.get(index));
textEndName.setText(arrName.get(index+1));
super.handleMessage(msg);
}
};
public void splitArray()
{
strSplit = kggg.split("\n");// string array
intervals = new long[strSplit.length];
Time timer;
for (int j = 0; j < strSplit.length; j++)
{
split = strSplit[j];// string
split1 = split.split("-");// string array
arrName.add(split1[0]);
String timeq = split1[1];
String[] timed = timeq.split(":");
if(timed.length == 3)
{
timer = new Time(Integer.parseInt(timed[0].trim()), Integer.parseInt(timed[1].trim()), Integer.parseInt(timed[2].trim()));
intervals[j] = timer.getTime();
}
else if(timed.length == 2)
{
timer = new Time(0, Integer.parseInt(timed[0].trim()), Integer.parseInt(timed[1].trim()));
intervals[j] = timer.getTime();
}
else if(timed.length == 1)
{
timer = new Time(0, 0, Integer.parseInt(timed[0].trim()));
intervals[j] = timer.getTime();
}
}
for (int j = intervals.length-1; j >= 0 ; j--)
{
intervals[j] = intervals[j] - intervals[0];
}
}
public void btnClick()
{
k++;
k = k % 2;
startSong(k);
}
private void startSong(int i) {
if (i == 1) {
System.out.println("11111" + i);
btnplay.setImageResource(R.drawable.pause);
try {
System.out.println("start try chech------");
mediaPlayer.start();
} catch (Exception e) {
mediaPlayer.pause();
}
}
if (i == 0) {
btnplay.setImageResource(R.drawable.play);
mediaPlayer.pause();
System.out.println("00000" + i);
}
}
You shouldn't be doing this:
handler.dispatchMessage(handler.obtainMessage());
Try this instead:
handler.sendMessage(handler.obtainMessage());
EDIT: Added other things I noticed
I also see that in your Thread you have a loop while (isDownloading) and you set isDownloading to false in the finally block. This loop while never run more than once.
Also, you do
btnplay.setImageResource(R.drawable.play);
inside a thead. This isn't good. You need to do everything related to UI on the main (UI) thread.