Code Monkey home page Code Monkey logo

audio-visualizer-android's Introduction

Audio Visualizer

API Download Build Status Android Arsenal Android Weekly

A light-weight and easy-to-use Audio Visualizer for Android using the Android Canvas.

Demos

CircleLine Hifi
CircleLine Hifi
Blob Blast
Blob Blast
Wave Bar
Wave Bar

Available Visualizers:

  • BlobVisualizer - Gives blob like effect, good for low bpm audio
  • BlastVisualizer - Gives a blast like effect, very random, good for high bpm audio
  • WaveVisualizer - Gives a nice wave like effect, good for all kinds of audio
  • BarVisualizer - Gives the contemporary bar effect, good for all kinds of audio
  • CircleLineVisualizer - Gives the circular bar like effect, good for all kinds of audio
  • HifiVisualizer - Gives a unique circular wave like effect, good for all kinds of audio

Usage

Note: Use of the visualizer requires the permission android.permission.RECORD_AUDIO so add it to your manifest file. Also for Android 6.0 and above you will need request permission in runtime.

Check out the Sample app, to see how its implemented.

  • This library is available on JCenter. To use it, add the following to build.gradle
dependencies {
    implementation 'com.gauravk.audiovisualizer:audiovisualizer:0.9.2'
}
  • Add the com.gauravk.audiovisualizer.visualizer.BlastVisualizer to your XML Layout file:
<com.gauravk.audiovisualizer.visualizer.BlastVisualizer
            xmlns:custom="http://schemas.android.com/apk/res-auto"
            android:id="@+id/blast"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            custom:avDensity="0.8"
            custom:avType="fill"
            custom:avColor="@color/av_dark_blue"
            custom:avSpeed="normal"/>
  • Get the reference to this view in you Java Class
        //get reference to visualizer
        mVisualizer = findViewById(R.id.blast);

        //TODO: init MediaPlayer and play the audio
        
        //get the AudioSessionId from your MediaPlayer and pass it to the visualizer
        int audioSessionId = mAudioPlayer.getAudioSessionId();
        if (audioSessionId != -1)
            mVisualizer.setAudioSessionId(audioSessionId);
        

Alternatively, you can pass the raw audio bytes to the visualizer

        //get reference to visualizer
        mVisualizer = findViewById(R.id.blast);

        //TODO: get the raw audio bytes
        
        //pass the bytes to visualizer
        mVisualizer.setRawAudioBytes(bytes);

Now, release the visualizer in your onDestroy() or onStop()

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mVisualizer != null)
            mVisualizer.release();
    }

If you want to hide the view upon completion of the audio, use

            //TODO: check for completion of audio eg. using MediaPlayer.OnCompletionListener()
            if (mVisualizer != null)
                mVisualizer.hide();

Similarly, include other visualizer

Attributes

attr Description
avType Changes the Visualization type - outline or fill. (N/A for Bar Visualizer)
avColor Defines the color that is used in the visualizer
avDensity Sets the density of the visualization between (0,1)
avSpeed Defines the speed of the animation - slow, medium and fast
avGravity Updates position of the visualizers - top and bottom (N/A for Blob and Blast Visualizers)
avWidth Describes the width of the line if avType is outline, in case of Bar Visualizer, defines width of the bar

Contribute

Found a bug or have an idea/feature request or any other help needed. Please suggest or report them here

I am always open to new suggestions and good contributions.

Thanks to @wangfengye for CircleLineVisualizer and HifiVisualizer.

License:

    Copyright 2018 Gaurav Kumar

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

audio-visualizer-android's People

Contributors

gauravk95 avatar wangfengye 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

audio-visualizer-android's Issues

new Style....

can u make a new style in it of simple material sinusoidal wave ? not to much flickering or distortion

HIFI index out of bounds error

Trying to use this library to implement the HiFiVisualizer. Everything works well with the CirlcleLineVisiualizer. Simply switching to HiFi causes an index out of bounds error. Code below..

<com.gauravk.audiovisualizer.visualizer.HiFiVisualizer xmlns:custom="http://schemas.android.com/apk/res-auto"
            android:id="@+id/blast"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginStart="16dp"
            android:layout_marginTop="16dp"
            android:layout_marginEnd="16dp"
            android:layout_marginBottom="16dp"
            custom:avColor="@color/dark_blue"
            custom:avDensity="0.8"
            custom:avSpeed="normal"
            custom:avType="outline"
            custom:avWidth="0dp"
            custom:layout_constraintBottom_toTopOf="@id/gpsLocation"
            custom:layout_constraintEnd_toEndOf="parent"
            custom:layout_constraintStart_toStartOf="parent"
            custom:layout_constraintTop_toBottomOf="@id/quecount" />
    </android.support.constraint.ConstraintLayout>

private HiFiVisualizer visualizer;
visualizer = findViewById(R.id.blast);

MediaPlayer is in a background service and passes sessionId to MainActivity through Interface like so

 player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    @Override
                    public void onPrepared(MediaPlayer mp) {
                        if (MI != null) MI.setSession(mp.getAudioSessionId());
                        if (!mute) {
                            gainFocus();
                            mp.setVolume(volumeA, volumeA);
                        }
                        mp.start();
                        updateDisplay();
                    }
                });
   @Override
    public void setSession(int id) {
           if (id != -1) visualizer.setAudioSessionId(id);
    }

Like I said before, everything works great when using CircleLine or Blast. Changing the XML from CirlcleLine to HiFi along with the global variable in the MainActivity to match compliles fine, runs, and causes the following crash.

E: FATAL EXCEPTION: main
    Process: com.cb3g.channel19, PID: 27644
    java.lang.ArrayIndexOutOfBoundsException: length=192; index=-1
        at com.gauravk.audiovisualizer.visualizer.HiFiVisualizer.onDraw(HiFiVisualizer.java:102)
        at android.view.View.draw(View.java:19192)
        at android.view.View.updateDisplayListIfDirty(View.java:18142)
        at android.view.View.draw(View.java:18920)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4236)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4022)
        at android.support.constraint.ConstraintLayout.dispatchDraw(ConstraintLayout.java:1873)
        at android.view.View.draw(View.java:19195)
        at android.view.View.updateDisplayListIfDirty(View.java:18142)
        at android.view.View.draw(View.java:18920)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4236)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4022)
        at android.support.constraint.ConstraintLayout.dispatchDraw(ConstraintLayout.java:1873)
        at android.view.View.updateDisplayListIfDirty(View.java:18133)
        at android.view.View.draw(View.java:18920)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4236)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4022)
        at android.view.View.updateDisplayListIfDirty(View.java:18133)
        at android.view.View.draw(View.java:18920)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4236)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4022)
        at android.view.View.updateDisplayListIfDirty(View.java:18133)
        at android.view.View.draw(View.java:18920)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4236)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4022)
        at android.view.View.updateDisplayListIfDirty(View.java:18133)
        at android.view.View.draw(View.java:18920)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4236)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4022)
        at android.view.View.updateDisplayListIfDirty(View.java:18133)
        at android.view.View.draw(View.java:18920)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4236)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4022)
        at android.view.View.updateDisplayListIfDirty(View.java:18133)
        at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:669)
        at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:675)
        at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:783)
        at android.view.ViewRootImpl.draw(ViewRootImpl.java:2992)
        at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2806)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2359)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1392)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6752)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
        at android.view.Choreographer.doCallbacks(Choreographer.java:723)
        at android.view.Choreographer.doFrame(Choreographer.java:658)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

Am I missing something here? The audio format is M4A (MPEG_4_Audio)

mVisualizer.setRawAudioBytes(data) not showing proper data in it..

Hey,

I have a recording app and want to use this as visualizer, but when receiving audio and setting into it, i am not able to find the proper blast form or any thing nicer in that..

![image](https://user-images.githubusercontent.com/24537492/51698235-b1cc0380-202f-11e9-921e-6a133b1534c6.png)

    public int RECORDER_SAMPLERATE = 44100;
    private final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_MONO;
    private final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;

 BufferElements2Rec = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE,
                RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING);

   audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
                RECORDER_SAMPLERATE, RECORDER_CHANNELS,
                RECORDER_AUDIO_ENCODING, BufferElements2Rec * 2);



Thread recordingThread = new Thread("recorder") {
                @Override
                public void run() {
                    super.run();
                    if (Looper.myLooper() == null) {
                        Looper.prepare();
                    }
                    audioRecord.setRecordPositionUpdateListener(recordPositionUpdateListener, new Handler(Looper.myLooper()));
               
                    audioRecord.setPositionNotificationPeriod((int) BufferElements2Rec);
                    //We need to read first chunk to motivate recordPositionUpdateListener.
                    //Mostly, for lower versions - https://code.google.com/p/android/issues/detail?id=53996
                    bufferReadResult = audioRecord.read(buffer, 0, BufferElements2Rec);
                    Looper.loop();
                }
            };
audioRecord.startRecording();

recordingThread.start();

  private AudioRecord.OnRecordPositionUpdateListener recordPositionUpdateListener = new AudioRecord.OnRecordPositionUpdateListener() {
        @Override
        public void onMarkerReached(AudioRecord recorder) {
            //empty for now
        }

        @Override
        public void onPeriodicNotification(AudioRecord recorder) {
            if (audioRecord.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING
                    && audioRecord.read(buffer, 0, buffer.length) != -1) {
//                mHorizon.updateView(buffer);
                byte[] data = new byte[buffer.length];
                for (int j = 0; j < buffer.length; j++) {
                    byte tmp = (byte) (buffer[j]);
                    data[j] = tmp;
                }
                  mVisualizer.setRawAudioBytes(data);
            }
        }
    };

Help is really appreciate asap.

Already spent almost two for combo..
![screenshot_10](https://user-images.githubusercontent.com/24537492/51698343-eb9d0a00-202f-11e9-9efa-e5404547f185.png)



java.lang.RuntimeException: Cannot initialize Visualizer engine, error: -3

I am using exoplayer to play my audio file in Activity. I used the below code to get audio session id.

exoPlayer.addAudioListener(this);
@Override
public void onAudioSessionId(int audioSessionId) {
Timber.tag(TAG).d("audio session id: %d", audioSessionId);
binding.visualizer.setAudioSessionId(audioSessionId);
}

Above code gives an error for all visualizers.

java.lang.RuntimeException: Cannot initialize Visualizer engine, error: -3 at android.media.audiofx.Visualizer.<init>(Visualizer.java:218) at com.gauravk.audiovisualizer.base.BaseVisualizer.setAudioSessionId(BaseVisualizer.java:196) at com.andruid.magic.makeitspeak.activity.DetailsActivity.onAudioSessionId(DetailsActivity.java:146) at com.google.android.exoplayer2.SimpleExoPlayer$ComponentListener.onAudioSessionId(SimpleExoPlayer.java:1306) at com.google.android.exoplayer2.audio.AudioRendererEventListener$EventDispatcher.lambda$audioSessionId$5$AudioRendererEventListener$EventDispatcher(AudioRendererEventListener.java:164) at com.google.android.exoplayer2.audio.-$$Lambda$AudioRendererEventListener$EventDispatcher$a1B1YBHhPRCtc1MQAc2fSVEo22I.run(Unknown Source:4) at android.os.Handler.handleCallback(Handler.java:790) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:7000) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)

how to use this library for live streaming

Hi,

I'm working on a project where we live stream a channel and I'm looking for an equalizer animation on screen to run. Will this library work fine without performance issues?

TimeoutException

"java.util.concurrent.TimeoutException: android.graphics.Path.finalize() timed out after 10 seconds"

Everytime i use CircleLineVisualizer, it crashes after 10 seconds with above error. Please resolve the issue, i want this issue to be resolved ASAP.

Changing the speed doesn't seem to work

I tried to set the speed to slow but it looks as fast as normal or fast on the same audio file. I'm playing a very slow guided meditation where there is not much sound and still the CircleLineVisualizer is moving like crazy. Is there any way to change the speed manually? And thanks for a great library!

How to use this library with live recording

Hi,

I am working on an Audio recording function. I want the recorded Audio to be saved into the internal cache directory of my app so that I can later process it and send it to my server. I have taken the RECORD_AUDIO_PERMISSION in my Android Manifest.

Below is the code I am using for recording audio and save it to a file.

    String uuid = UUID.randomUUID().toString();
    fileName = getExternalCacheDir().getAbsolutePath() + "/" + uuid + ".3gp";


    recorder = new MediaRecorder();
    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    recorder.setOutputFile(fileName);
    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);


    try {
        recorder.prepare();
        recorder.start();
    } catch (IOException e) {}

The above code to work fine but I am facing another issue. I want to create a Waveform effect for my app for which I am using this library. I know the below code can be used to pass on bytes to the visualizer.

//get reference to visualizer
 mVisualizer = findViewById(R.id.blast);

 //TODO: get the raw audio bytes
 
 //pass the bytes to visualizer
 mVisualizer.setRawAudioBytes(bytes);

Now, my question is how can I get the Bytes in real-time of the Audio which is being recorded and being saved? Should I read the file and extract recent bytes from it at regular intervals or is there any other method to achieve this?

Any help would be appreciated

Thanks.

How to resume the animation

Hi guys! I have apreciatted your plugin, but I need to know how to resume the process after stop the same.

Audio visualizer not showing the visualization even when audio session Id passed

audioVisualizer = binding.audioVisualizer
        var audioSession = playerViewModel.audioSessionId
        if (audioSession != -1)
            audioVisualizer?.setAudioSessionId(audioSession)
        audioVisualizer?.setColor(getAudioVisualizerColor())

The visualizer is showing up but is not matching with the song, it's just a circle I am using blobVisualizer

Circle Line Visualiser effect in Swift for iOS

Just opening an issue here to see if this already exists. I am attempting to create one, but meanwhile let me know if anyone here already has done it or if something similar exists in iOS.

App crashed while trying to get reference of java class

xml code :-
<com.gauravk.audiovisualizer.visualizer.BlastVisualizer
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:id="@+id/wave"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_alignParentBottom="true"
custom:avDensity="0.8"
custom:avType="outline"
custom:avColor="@color/av_dark_blue"
custom:avSpeed="normal"/>

java code :-
BarVisualizer barVisualizer;
barVisualizer = findViewById(R.id.wave);

visualizer not working

thnaks for great library in case it is of use to anyone this is simle implementation using just java

  public MediaPlayer mediaPlayer;
    BarVisualizer barVisualizer;
    RelativeLayout rel;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       // setContentView(R.layout.activity_main);
        rel=new RelativeLayout(this);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) ==
                    PackageManager.PERMISSION_GRANTED) {
                // put your code for Version>=Marshmallow
            } else {
                if (shouldShowRequestPermissionRationale(Manifest.permission.RECORD_AUDIO)) {
                    Toast.makeText(this,
                            "App required access to audio", Toast.LENGTH_SHORT).show();
                }
                requestPermissions(new String[]{Manifest.permission.RECORD_AUDIO
                }, 100);
            }

        } else {
            // will do later
        }



        mediaPlayer = MediaPlayer.create(this, R.raw.sample);
        mediaPlayer.start();
       int id= mediaPlayer.getAudioSessionId();
       if (id !=-1){
           System.out.println("aaaaaaaaaaaaaa   "+id);
           barVisualizer=new BarVisualizer(this);
           barVisualizer.setPlayer(id);//(mediaPlayer.getAudioSessionId());
           barVisualizer.setVisibility(View.VISIBLE);
           barVisualizer.setColor(Color.RED);
           barVisualizer.setDensity(80);
           rel.addView(barVisualizer);
           System.out.println("bbbbbbbbbbbbbb   "+id);
        }else{
           System.out.println("mediaplay id is null");
       }
       setContentView(rel);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if (requestCode == 101) {
            if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(getApplicationContext(),
                        " record", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

Failed to instantiate one or more classes

The following classes could not be instantiated:
- com.gauravk.audiovisualizer.visualizer.BarVisualizer (Open Class, Show Exception, Clear Cache)
Tip: Use View.isInEditMode() in your custom views to skip code or show sample data when shown in the IDE. If this is an unexpected error you can also try to build the project, then manually refresh the layout. Exception Details java.lang.ClassNotFoundException: android.media.audiofx.Visualizer$OnDataCaptureListener

Increase Height of Size of a bar

Hi ,Thanks for this greate library.In my app hight of bar visualizing too short, Is there any way to show hight of bars size like 300dp .Thanks in advance.

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.