alxrm / audiowave-progressbar Goto Github PK
View Code? Open in Web Editor NEWLightweight audiowave progressbar for Android
License: MIT License
Lightweight audiowave progressbar for Android
License: MIT License
private int mSampleRate = 16000;
private int mChannel = AudioFormat.CHANNEL_CONFIGURATION_MONO;
private int mEncoding = AudioFormat.ENCODING_PCM_16BIT;
Hello, thanks for your library, I found that the waveform incorrect while my wav file is 16bit,
Hi, thank you for your good library.
I'm having a problem, I added AudioWaveView and working properly, but unfortunately, setOnProgressListener is not found for me.
In fact, this interface does not exist. Please check and correct. Thank .
Unfortunately this library does not give correct audio wave on marshmallow, nougat and oreo. When I input a file of length 2 seconds and sound starts at 0:00 and ends at 00:01, rest seconds are blank.. then the audio wave shows no blank moments. Instead it shouw as if the there was sound during the whole recording.
Proof:
http://yarmobile.nazwa.pl/PROJEKTY/WeType/20180511_164630.mp4
http://yarmobile.nazwa.pl/PROJEKTY/WeType/20180511_162830.mp4
I'm getting bytes with this style;
`byte[] soundBytes = null;
try {
InputStream inputStream =
getContentResolver().openInputStream(Uri.fromFile(new File(suanki_playlist.get(id).path)));
soundBytes = new byte[inputStream.available()];
soundBytes = toByteArray(inputStream);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
seekbar2.setRawData(soundBytes);`
Is it the problem?
Wow thanks for your quick awesome response <3
And i had 3 questions related to my last issue , it will be great if you would give me some tips :
In the setOnProgress Listener in onProgressChanged , what should i write to change the progress of MediaPlayer ? because the code that i wrote is not working .
What is the best way to implement codes in another thread to prevent screen hanging and possible errors ?
And i'm receiving the Mp3 file from server by an URL , and i have to wait for mediaPlayer to compeletly prepare and download the mp3 and then audiogram will be displayed and it takes time to download the file completely . is there anyway to reduce its time ? Or draw it on Runtime dynamically ?
Thank you very very much for your helps <3
i mean like LED- or LCD-like bar gauge control for iOS
https://github.com/ChiefPilot/F3BarGauge
https://github.com/ChiefPilot/F3BarGauge
listen audiowave progressbar
How to use this library in java file.my project is in java.so..I can not generate waveform from file in my activity.
First of all, i would like to thank you for such a nice library.
I have found the source for the error you talk about in #6, specifically the one about files bigger than ~10MB. It is caused by an integer overflow in the line val currentDataIndex = targetSize * index / data.size
from here. Specifically the targetSize * index
multiplication. I'm not sure about why doesn't an IndexOutOfBoundsException appear when accesing the array targetSized[prevDataIndex]
but i don't know much Kotlin.
It can be easily solved by casting index to long and the result to int as in (targetSize * index.toLong() / data.size).toInt()
if you don't want to tweak the algorithm behind index
values.
I would like to create the pull request if you are fine with it.
As a side note, the purpose of setScaledData()
could be explained a little better, to me, it wasn't clear if you meant scaled as in values or size.
Thank you.
I'm trying to change the color of the bar after audio is played. After the audio played, filled color is changed successfully but the background color is not changing to the new color. Here's a code snippet:
waveView.setOnProgressListener(new OnProgressListener() {
@Override
public void onStartTracking(float v) {
}
@Override
public void onStopTracking(float v) {
}
@Override
public void onProgressChanged(float v, boolean b) {
if (v == 100F)
waveView.setWaveColor(ContextCompat.getColor(itemView.getContext(), R.color.subtitleGray));
}
});
XML:
<rm.com.audiowave.AudioWaveView
android:id="@+id/wave"
android:layout_width="match_parent"
android:layout_height="28dp"
android:layout_marginEnd="20dp"
app:animateExpansion="false"
app:chunkWidth="3dp"
app:chunkHeight="28dp"
app:minChunkHeight="2dp"
app:chunkSpacing="1dp"
app:chunkRadius="2dp"
app:waveColor="#ef4f35" />
Tested on Moto G with 7.1.2. Any fixes/workaround is appreciated!
I figured out that this lib only supports .wav, but when we use a correct param, we can also draw the wave.
But the dataType I receive from server is a JSON like: "["0.01", "0.03", "0.02",....]" and I cannot convert to ByteArray type that the function need. Do we need to do any further step, since I can convert it to FloatArray, and then ByteArray, but turn out it shows wrong waves.
Hi
i record voice in telegram and final wave form is like following image
but when i used from this audio for test app the result was like this!
my code is
byte[] soundBytes = null;
try {
InputStream inputStream = getApplicationContext().getResources().openRawResource(R.raw.f);
soundBytes = new byte[inputStream.available()];
soundBytes = toByteArray(inputStream);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
waveView.setWaveColor(Color.parseColor("#007fff"));
waveView.setScaledData(soundBytes);
waveView.setRawData(soundBytes, new OnSamplingListener() {
@Override
public void onComplete() {
}
});
How Detect Correct Raw Data?
i am sorry . my English is poor and i am learner. please help me. i need demo. o(╥﹏╥)oo(╥﹏╥)o
Hi. There is a problem when using waveview on scrolling recyclerview .
` java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.Bitmap.isRecycled()' on a null object reference
at android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1269)
at android.graphics.Canvas.drawBitmap(Canvas.java:1325)
at rm.com.audiowave.AudioWaveView.onDraw(AudioWaveView.kt:132)
at android.view.View.draw(View.java:16302)
at android.view.View.updateDisplayListIfDirty(View.java:15284)
at android.view.View.draw(View.java:16072)
at android.view.ViewGroup.drawChild(ViewGroup.java:3622)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3409)
at android.view.View.updateDisplayListIfDirty(View.java:15279)
at android.view.View.draw(View.java:16072)
at android.view.ViewGroup.drawChild(ViewGroup.java:3622)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3409)
at android.view.View.draw(View.java:16305)
at android.view.View.updateDisplayListIfDirty(View.java:15284)
at android.view.View.draw(View.java:16072)
at android.view.ViewGroup.drawChild(ViewGroup.java:3622)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3409)
at android.view.View.draw(View.java:16305)
at android.view.View.updateDisplayListIfDirty(View.java:15284)
at android.view.View.draw(View.java:16072)
at android.view.ViewGroup.drawChild(ViewGroup.java:3622)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3409)
at android.view.View.updateDisplayListIfDirty(View.java:15279)
at android.view.View.draw(View.java:16072)
at android.view.ViewGroup.drawChild(ViewGroup.java:3622)
at android.support.v7.widget.RecyclerView.drawChild(RecyclerView.java:4400)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3409)
at android.view.View.draw(View.java:16305)
at android.support.v7.widget.RecyclerView.draw(RecyclerView.java:3792)
at android.view.View.updateDisplayListIfDirty(View.java:15284)
at android.view.View.draw(View.java:16072)
at android.view.ViewGroup.drawChild(ViewGroup.java:3622)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3409)
at android.view.View.updateDisplayListIfDirty(View.java:15279)
at android.view.View.draw(View.java:16072)
at android.view.ViewGroup.drawChild(ViewGroup.java:3622)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3409)
at android.view.View.updateDisplayListIfDirty(View.java:15279)
at android.view.View.draw(View.java:16072)
at android.view.ViewGroup.drawChild(ViewGroup.java:3622)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3409)
at android.view.View.draw(View.java:16305)
at android.view.View.updateDisplayListIfDirty(View.java:15284)
at android.view.View.draw(View.java:16072)
at android.view.ViewGroup.drawChild(ViewGroup.java:3622)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3409)
at android.view.View.updateDisplayListIfDirty(View.java:15279)
at android.view.View.draw(View.java:16072)
at android.view.ViewGroup.drawChild(ViewGroup.java:3622)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3409)
at android.view.View.updateDisplayListIfDirty(View.java:15279)
at android.view.View.draw(View.java:16072)
at android.view.ViewGroup.drawChild(ViewGroup.java:3622)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3409)
at android.view.View.updateDisplayListIfDirty(View.java:15279)
at android.view.View.draw(View.java:16072)
at android.view.ViewGroup.drawChild(ViewGroup.java:3622)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3409)
at android.view.View.updateDisplayListIfDirty(View.java:15279)
at android.view.View.draw(View.java:16072)
at android.view.ViewGroup.drawChild(ViewGroup.java:3622)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3409)
at android.view.View.updateDisplayListIfDirty(View.java:15279)
at android.view.View.draw(View.java:16072)
at android.view.ViewGroup.drawChild(ViewGroup.java:3622)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3409)
at android.view.View.updateDisplayListIfDirty(View.java:15279)
at android.view.View.draw(View.java:16072)
at android.view.ViewGroup.d`
Hello . I used WaveView inside the RecyclerView and found it to be extremely slow and adds extra load on the UI thread.
Please fix this problem. Thank .
setData :
if (itemView.wave_voice.scaledData.isEmpty()) {
Observable.fromCallable { fileHelper.getFileByte(voice.file) }
.newThread()
.subscribe {
itemView.wave_voice.scaledData = it
itemView.wave_voice.setRawData(it)
}
}
func :
fun getFileByte(filename: String): ByteArray {
val file = getFilePath(filename)
return if (file.exists())
file.readBytes()
else byteArrayOf(0)
}
hey man , thanks for your awesome library . i have implemented my player and im getting the mp3 file by url and then i convert it to ByteArray and use audioWave.setOnProgressListener(...);
. but when i implement it like seekbar i encounter with some problems , here is my code :
public class Mp3PageFragment extends Fragment {
private View rootView;
private MediaPlayer mediaPlayer;
private SeekBar seekBar;
private TextView currentTime;
private TextView totalTime;
private Timer timer;
private ImageView playButton;
private ImageView forwardButton;
private ImageView rewindButton;
private BlobVisualizer mVisualizer;
private AudioWaveView audioWaveView;
@Override
@Nullable
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (rootView == null) {
rootView = inflater.inflate(R.layout.mp3_page_fragment, container, false);
setUpViews();
setUpMediaPlayer();
}
return rootView;
}
private void setUpViews() {
setBackgroundImage("http://20dl.pw/2019/02/Overdose%25203-realThumb_20.jpg");
setImage("http://20dl.pw/2019/02/Overdose%25203-realThumb_20.jpg");
playButton = rootView.findViewById(R.id.iv_mp3_page_play_pause);
forwardButton = rootView.findViewById(R.id.iv_mp3_page_skip_next);
rewindButton = rootView.findViewById(R.id.iv_mp3_page_skip_previous);
//seekBar = rootView.findViewById(R.id.sb_mp3_page_seek_bar);
currentTime = rootView.findViewById(R.id.tv_mp3_page_current_time);
currentTime.setText(formatDuration(0));
totalTime = rootView.findViewById(R.id.tv_mp3_page_total_time);
timer = new Timer();
timer.schedule(new MainTimer(), 0, 1000);
mVisualizer = rootView.findViewById(R.id.blast);
audioWaveView = rootView.findViewById(R.id.sb_mp3_page_seek_bar);
}
private void setUpMediaPlayer() {
mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(rootView.getContext(), Uri.parse("http://20dl.pw/2019/02/04%20-%20YAS%20-%20Esalat.mp3"));
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(mediaPlayer -> {
setUpMediaPlayerElements();
int audioSessionId = mediaPlayer.getAudioSessionId();
if (audioSessionId != -1)
mVisualizer.setAudioSessionId(audioSessionId);
});
mediaPlayer.setOnCompletionListener(mediaPlayer -> {
playButton.setImageDrawable(ContextCompat.getDrawable(rootView.getContext(), R.drawable.ic_mp3_page_play_arrow_white_24dp));
mediaPlayer.seekTo(0);
});
} catch (IOException e) {
e.printStackTrace();
}
}
private void setUpMediaPlayerElements() {
playButton.setOnClickListener(view -> {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
playButton.setImageDrawable(ContextCompat.getDrawable(rootView.getContext(), R.drawable.ic_mp3_page_play_arrow_white_24dp));
} else {
mediaPlayer.start();
playButton.setImageDrawable(ContextCompat.getDrawable(rootView.getContext(), R.drawable.ic_mp3_page_pause_black_24dp));
}
});
forwardButton.setOnClickListener(view -> {
mediaPlayer.seekTo(mediaPlayer.getCurrentPosition() + 5000);
});
rewindButton.setOnClickListener(view -> {
mediaPlayer.seekTo(mediaPlayer.getCurrentPosition() - 5000);
});
try {
byte[] myByte = downloadFile(new URL("http://20dl.pw/2019/02/04%20-%20YAS%20-%20Esalat.mp3"));
assert myByte != null;
audioWaveView.setRawData(myByte);
} catch (MalformedURLException e) {
e.printStackTrace();
}
audioWaveView.setExpansionDuration(mediaPlayer.getDuration());
audioWaveView.setOnProgressListener(new OnProgressListener() {
@Override
public void onStartTracking(float v) {
}
@Override
public void onStopTracking(float v) {
}
@Override
public void onProgressChanged(float v, boolean b) {
if (b) {
mediaPlayer.seekTo((int) (v * 1000));
}
}
});
totalTime.setText(formatDuration(mediaPlayer.getDuration()));
}
private void setImage(String url) {
SimpleDraweeView image = rootView.findViewById(R.id.sdv_mp3_page_image);
image.setImageURI(Uri.parse(url));
}
private void setBackgroundImage(String url) {
SimpleDraweeView backgroundImage = rootView.findViewById(R.id.sdv_mp3_page_background_blur_image);
Uri uri1 = Uri.parse(url);
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri1)
.setPostprocessor(new IterativeBoxBlurPostProcessor(20))
.build();
DraweeController controller = Fresco.newDraweeControllerBuilder()
.setImageRequest(request)
.setOldController(backgroundImage.getController())
.build();
backgroundImage.setController(controller);
}
private String formatDuration(long duration) {
int seconds = (int) (duration / 1000);
int minutes = seconds / 60;
seconds %= 60;
return String.format(Locale.ENGLISH, "%02d", minutes) + ":" + String.format(Locale.ENGLISH, "%02d", seconds);
}
@Override
public void onDestroyView() {
mediaPlayer.release();
timer.purge();
timer.cancel();
super.onDestroyView();
}
public static byte[] downloadFile(URL url) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
try {
URLConnection conn = url.openConnection();
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
conn.connect();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
IOUtils.copy(conn.getInputStream(), baos);
return baos.toByteArray();
} catch (IOException e) {
// Log error and return null, some default or throw a runtime exception
}
return null;
}
private class MainTimer extends TimerTask {
@Override
public void run() {
Objects.requireNonNull(getActivity()).runOnUiThread(() -> {
int mCurrentPosition = mediaPlayer.getCurrentPosition() / 1000;
audioWaveView.setProgress(mCurrentPosition);
currentTime.setText(formatDuration(mediaPlayer.getCurrentPosition()));
});
}
}
}
every Thing works fine But As you can see i implement audioWaveView.setProgress(mediaPlayer.getCurrentPosition());
into the class timer to show streaming process but it makes this error :
2019-02-18 12:46:48.172 27403-27403/com.parsa.bistrap E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.parsa.bistrap, PID: 27403
java.lang.IllegalArgumentException: Progress must be in 0..100
at rm.com.audiowave.AudioWaveView.setProgress(AudioWaveView.kt:79)
at com.parsa.bistrap.fragments.mp3page.Mp3PageFragment$MainTimer.lambda$run$0(Mp3PageFragment.java:269)
at com.parsa.bistrap.fragments.mp3page.-$$Lambda$Mp3PageFragment$MainTimer$QWa9_ReuC5VaKITz2IOpWbSu168.run(Unknown Source:2)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6649)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:826)
and i think the problem is for audioWaveView.setProgress();
this method accept numbers between 0 to 100 but the mediaPlayer.getCurrentPosition()
is returning outranged number . in seekbar there was a method called : seekbar.setMax(MediaPlayer.getDuration()), but there is no such thing in your library , can you please tell me how to change that accepted number dynamically for set process ? Thanks <3
Title says it all!
Otherwise really cool library! looking forward in using it.
This happens right after pasting the dependency
Thanks for this project. I use this in recyclerview, and start progressAnim, there is some problem I think that caused by reuse with recyclerview. For example, the first items wave progress will be set for three or four item
s. How can I deal with it? Thanks
Hi, I'm using this library for a personal project where I place the progressbar between an image and a panel, with the default alpha channel it doesn't look very fine. I suggest accepting parameters for the not filled bars color, for the filled bars color and also for the alpha channel instead of using a hardcoded alpha value.
Thank for your library, it helps me a lot
but I can't catch the event of change progress value by user event,
I subscribe for setOnStopTracking and setOnProgressListener, but neither I can't catch that event.
Is there a trick?
Hi
Thank you for the great library.
I wonder where I can find the required array of bytes that I must pass to setRawData(), if I want to play a mp3 file. should I get file input stream and then get the byte array? I tried to do that but the created waves were not Compatible with the voice.
I'm getting this error when building.
Error:(251, 5) error: duplicate value for resource 'attr/progress' with config ''.
Don't know what to do!
Hello,
I tried running this in an application and for whatever reason I can't get the progress bar to animate up. It just stays flat. I have checked the bytes, and things look good. I even tried the static bytes array in your sample app with no prevail. Thank you!
Here is my code
` mBeatWaveFormIV.setRawData(getByte(mAudioFile.getAbsolutePath()), new OnSamplingListener() {
@OverRide
public void onComplete() {
Log.d("audio", "Completed");
}
});
private byte[] getByte(String path) {
byte[] getBytes = {};
try {
File file = new File(path);
getBytes = new byte[(int) file.length()];
InputStream is = new FileInputStream(file);
is.read(getBytes);
is.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Log.d("Bytes", getBytes.length+"");
return getBytes;
}
03-04 02:06:52.760 18245-18245/me.rapchat.rapchat D/Bytes: 3048734
`
Hey @alxrm , Thanks for this library. but i have a query. Right now i think the width of Audiowaves are confined to the width of parent layout. i want to add it inside a scrollview so that it takes as much width it needs and i should be able to scroll. is there an easy way to do this or need to modify the library code?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.