GithubHelp home page GithubHelp logo

alxrm / audiowave-progressbar Goto Github PK

View Code? Open in Web Editor NEW
489.0 22.0 83.0 1.4 MB

Lightweight audiowave progressbar for Android

License: MIT License

Kotlin 72.86% Java 27.14%
kotlin audio waveform progressbar android view milf

audiowave-progressbar's People

Contributors

alxrm avatar bernaferrari avatar carmocca avatar gounlaf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

audiowave-progressbar's Issues

Waveform incorrect

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,

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 .

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

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?

onProgressChanged

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

Integer Overflow

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.

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!

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.

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?

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`

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)
    }

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

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

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

Seek by user event

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?

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.

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
`

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?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.