Lightweight audiowave progressbar for Android

Overview

Audiogram

License

Super lightweight audiowave progressbar written in Kotlin

Getting started

Add to your root build.gradle:

allprojects {
	repositories {
	    ...
	    maven { url "https://jitpack.io" }
	}
}

Add the dependency:

dependencies {
  implementation 'com.github.alxrm:audiowave-progressbar:0.9.2'
}

Attrs

attr format description
waveColor color with this color chunks will be filled
chunkWidth dimension every chunk will have this width
chunkHeight dimension maximum height all the chunks can be
minChunkHeight dimension minimum height all the chunks can be
chunkSpacing dimension spacing between chunks
chunkRadius dimension how much corners of every chunk will be rounded
progress float should be 0..100, it's float so you can easily animate this
animateExpansion boolean toggle the animated expansion
touchable boolean toggle to use it as a seekbar, default value is true

Note: If you are going to place this in a RecyclerView item, you have to set animateExpansion to false, otherwise you'll see an incredibly laggy scroll (check out the example)

In code

Settle the wave somewhere in your XML like this:

<rm.com.audiowave.AudioWaveView
    android:id="@+id/wave"
    android:layout_width="match_parent"
    android:layout_height="32dp"
    android:layout_margin="16dp"
    app:animateExpansion="false"
    app:chunkWidth="3dp"
    app:chunkHeight="24dp"
    app:minChunkHeight="2dp"
    app:chunkSpacing="1dp"
    app:chunkRadius="1dp"
    app:touchable="true"
    app:waveColor="@android:color/white"
    />

API

Set raw byte array asynchronously

// does downsampling in O(N) and shows the animation you see in a gif above (the inflation-like one)
setRawData(byte[] data);

// you also have the ability to listen, when does the downsampling complete
setRawData(byte[] data, OnSamplingListener callback);

In case you have a scaled byte array you want to draw, i. e. an array whose size is the amount of chunks to draw

// instantly redraws the wave without async downsampling process
setScaledData(byte[] scaledData);

You can use it like a Seekbar, it reacts on touches, just attach listener

wave.setOnProgressListener(OnProgressListener listener);

Note: that setOnProgressListener is a Java style API and with Kotlin you have to set it like this:

wave.onProgressListener = object : OnProgressListener {...}

This listener has 3 methods like a built-in Seekbar

void onStartTracking(float progress) {
  // invokes when user touches the view
}

void onStopTracking(float progress) {
  // invokes when user releases the touch
}

void onProgressChanged(float progress, boolean byUser) {
  // invokes every time the progress's been changed
}

Kotlin users can listen Seekbar event in a more convenient and clean way with properties:

wave.onStopTracking = {
  Log.d("wave", "Progress set: $it")
}

wave.onStartTracking = {
  Log.d("wave", "Started tracking from: $it")
}

wave.onProgressChanged = {progress, byUser ->
  Log.d("wave", "Progress set: $progress, and it's $byUser that user did this")
}

Contribution

There are some features(like better precision) I am about to implement, but a little bit later. If you'd like to help, you are always free to send pull requests or issues if you only want to suggest something

Note: All your pull requests should be written in kotlin

License

MIT License

Copyright (c) 2016 Alexey Derbyshev

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Comments
  • Progress bar not animating

    Progress bar not animating

    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 `

    opened by JeremyPacker 9
  • Not available the setOnProgressListener

    Not available the setOnProgressListener

    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 .

    opened by aaaamirabbas 7
  • The waves doesn't match the sound?

    The waves doesn't match the sound?

    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?

    opened by tolgayavuz 6
  • can i make as flat

    can i make as flat

    opened by nzala 5
  • Fix code style.

    Fix code style.

    My eyes hurt when I saw it, so I fixed.

    Also a question, wouldn't it be better to use @JvmOverloads on AudioWaveView and replace inflateAttrs with init?

    opened by bernaferrari 4
  • synchronizing audigram with mediaplayer

    synchronizing audigram with mediaplayer

    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 themediaPlayer.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

    opened by parsa10 3
  • Wave background color is not updating

    Wave background color is not updating

    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!

    bug 
    opened by laurentiusandre 3
  • WaveView on RecyclerView

    WaveView on RecyclerView

    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`
    
    opened by EMIN3M1986 3
  • Don't know to convert to data type to use setRawwData() function

    Don't know to convert to data type to use setRawwData() function

    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.

    opened by lhtriet 2
  • AudioWaveView inside ScrollView

    AudioWaveView inside ScrollView

    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?

    opened by anugotta 2
  • Slow and excess load on the UI thread

    Slow and excess load on the UI thread

    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)
        }
    
    opened by aaaamirabbas 2
  • Not displaying correct audio wave on oreo, nougat and marshmallow

    Not displaying correct audio wave on oreo, nougat and marshmallow

    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

    wontfix 
    opened by JasonTheDynamite 3
  • How Detect Correct Raw Data?

    How Detect Correct Raw Data?

    Hi i record voice in telegram and final wave form is like following image

    b

    but when i used from this audio for test app the result was like this!

    a

    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?

    wontfix 
    opened by saeedmozaffari 1
  • [REQUEST] Optional alpha channel

    [REQUEST] Optional alpha channel

    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.

    enhancement 
    opened by aexvir 3
  • Animation in RecyclerView

    Animation in RecyclerView

    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 items. How can I deal with it? Thanks

    opened by DonnyHe 2
  • given array of bytes

    given array of bytes

    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.

    enhancement 
    opened by MohammedElotol 7
Releases(0.9.2)
  • 0.9.2(May 24, 2018)

    What's new in v0.9.2

    • updated dependencies #18
    • made chunksCount property public #17
    • implemented isTouchable property(also as xml attribute)
    • fixed wave background color not being changed on waveColor change, issue #15

    ❤️ Big thanks to @Gounlaf for his PRs and to @laurentiusandre for a good bug catch

    Source code(tar.gz)
    Source code(zip)
  • 0.9.1(Feb 18, 2018)

  • 0.9(Sep 2, 2017)

    What's new in v0.9

    • fixed appearance for the files that are larger than 10 MB

    Special thanks to @carmocca for PR with the fix and @soqman who was the first, who found the source of the problem

    Source code(tar.gz)
    Source code(zip)
  • 0.8(Feb 18, 2017)

    What's new in v0.8

    • fixed RecyclerView bug
    • added the ability to turn off animated expansion

    TODO

    • gravity
    • different colors for filled/empty chunks
    Source code(tar.gz)
    Source code(zip)
  • 0.7(Dec 7, 2016)

    What's new in v0.7

    • fix of the nasty bug in downsampling algorithm(it also became 10x faster)

    TODO

    • gravity
    • different colors for filled/empty chunks
    Source code(tar.gz)
    Source code(zip)
  • 0.6(Nov 26, 2016)

    What's new in v0.6

    • more event listeners, better API for Java side
    • seeking functionality

    TODO

    • gravity
    • different colors for filled/empty chunks
    Source code(tar.gz)
    Source code(zip)
  • 0.5(Nov 5, 2016)

    First public version of audiowave

    • async data binding
    • color setting
    • animated shape updating

    TODO

    • seeking
    • gravity
    • different colors for filled/empty chunks
    Source code(tar.gz)
    Source code(zip)
Owner
Alexey Derbyshev
Alexey Derbyshev
A download progressbar with cool animation

FreshDownloadView ##About FreshDownloadView is a java library for Android,It's a good way to show download progress with a cool animtion.some inspirat

null 747 Nov 23, 2022
A lightweight non intrusive app rate reminder for Android

Discreet App Rate A lightweight non intrusive app rate reminder for Android Download repositories { mavenCentral() } dependencies { compile '

Nicolas POMEPUY 469 Nov 10, 2022
Celebrate more with this lightweight confetti particle system 🎊

Konfetti ?? ?? Celebrate more with this lightweight confetti particle system. Create realistic confetti by implementing this easy to use library. Demo

Dion Segijn 2.7k Jan 2, 2023
:balloon: A lightweight popup like tooltips, fully customizable with an arrow and animations.

Balloon ?? A lightweight popup like tooltips, fully customizable with arrow and animations. Including in your project Gradle Add below codes to your r

Jaewoong Eum 2.8k Jan 5, 2023
Simple and lightweight UI library for user new experience, combining floating bottom navigation and bottom sheet behaviour. Simple and beautiful.

Simple and lightweight UI library for user new experience, combining floating bottom navigation and bottom sheet behaviour. Simple and beautiful.

Rizki Maulana 118 Dec 14, 2022
A Lightweight Framework for Code Generating

Codegen A lightweight framework for code generating. Why Codegen? In Java/Kotlin world, engineers usually use JavaPoet or KotlinPoet for code generati

Johnson Lee 38 Dec 20, 2022
Android library used to create an awesome Android UI based on a draggable element similar to the last YouTube graphic component.

Draggable Panel DEPRECATED. This project is not maintained anymore. Draggable Panel is an Android library created to build a draggable user interface

Pedro Vicente Gómez Sánchez 3k Dec 6, 2022
TourGuide is an Android library that aims to provide an easy way to add pointers with animations over a desired Android View

TourGuide TourGuide is an Android library. It lets you add pointer, overlay and tooltip easily, guiding users on how to use your app. Refer to the exa

Tan Jun Rong 2.6k Jan 5, 2023
Bubbles for Android is an Android library to provide chat heads capabilities on your apps. With a fast way to integrate with your development.

Bubbles for Android Bubbles for Android is an Android library to provide chat heads capabilities on your apps. With a fast way to integrate with your

Txus Ballesteros 1.5k Jan 2, 2023
View that imitates Ripple Effect on click which was introduced in Android L (for Android 2.3+)

RippleView View that imitates Ripple Effect on click which was introduced in Android L. Usage For a working implementation, Have a look at the Sample

Muthuramakrishnan Viswanathan 1.2k Dec 30, 2022
A new canvas drawing library for Android. Aims to be the Fabric.js for Android. Supports text, images, and hand/stylus drawing input. The library has a website and API docs, check it out

FabricView - A new canvas drawing library for Android. The library was born as part of a project in SD Hacks (www.sdhacks.io) on October 3rd. It is cu

Antwan Gaggi 1k Dec 13, 2022
MarkdownView is an Android webview with the capablity of loading Markdown text or file and display it as HTML, it uses MarkdownJ and extends Android webview.

About MarkdownView (Markdown For Android) is an Android library that helps you display Markdown text or files (local/remote) as formatted HTML, and st

Feras Alnatsheh 1k Dec 20, 2022
SwipeBack for Android Activities to do pretty the same as the android "back-button" will do, but in a really intuitive way by using a swipe gesture

SwipeBack SwipeBack is for Android Activities to do pretty the same as the android "back-button" will do, but in a really intuitive way by using a swi

Hannes Dorfmann 697 Dec 14, 2022
A backport of the SwitchPreference component that was introduced on Android 4 (ICS / level 14). This port works on Android 2.1+ (Eclair MR1 / level 7).

Android Switch Preference Backport A backport of the SwitchPreference component that was introduced on Android 4 (ICS / level 14). This port works on

Benoit Lubek 498 Dec 29, 2022
Wizard Pager is a library that provides an example implementation of a Wizard UI on Android, it's based of Roman Nurik's wizard pager (https://github.com/romannurik/android-wizardpager)

Wizard Pager Wizard Pager is a library that provides an example implementation of a Wizard UI on Android, it's based of Roman Nurik's wizard pager (ht

Julián Suárez 520 Nov 11, 2022
Make your native android Toasts Fancy. A library that takes the standard Android toast to the next level with a variety of styling options. Style your toast from code.

FancyToast-Android Prerequisites Add this in your root build.gradle file (not your module build.gradle file): allprojects { repositories { ... ma

Shashank Singhal 1.2k Dec 26, 2022
Make your native android Dialog Fancy. A library that takes the standard Android Dialog to the next level with a variety of styling options. Style your dialog from code.

FancyAlertDialog-Android Prerequisites Add this in your root build.gradle file (not your module build.gradle file): allprojects { repositories { ..

Shashank Singhal 350 Dec 9, 2022
Xamarin.Android provides open-source bindings of the Android SDK for use with .NET managed languages such as C#

Xamarin.Android Xamarin.Android provides open-source bindings of the Android SDK for use with .NET managed languages such as C#. Build Status Platform

Xamarin 1.8k Jan 5, 2023