Search code examples
androidvisualizer

How to set AudioSessionId to visualizer?


I recreate mediaplayer each track with release and new. But how recreate visualizer? When i call release and creating new visualizer then i have new thread visualizer because old thread don't finalized automatically. If i don't recreating visualizer then his have wrong AudioSessionId. How use visualizer??? With mediaplayer if mediaplayer do recreate each track??

Some code for example (from my big app):

public class VisualizerView extends View {
  private static final String TAG = "VisualizerView";

  private byte[] mBytes;
  private byte[] mFFTBytes;
  private Rect mRect = new Rect();
  private static Visualizer mVisualizer;

  private static Set<Renderer> mRenderers;

  private Paint mFlashPaint = new Paint();
  private Paint mFadePaint = new Paint();

  public VisualizerView(Context context, AttributeSet attrs, int defStyle)
  {
    super(context, attrs);
    init();
  }


public void link(MediaPlayer player)
  {
    if(player == null)
    {
      throw new NullPointerException("Cannot link to null MediaPlayer");
    }
    // Pass through Visualizer data to VisualizerView
    Visualizer.OnDataCaptureListener captureListener = new Visualizer.OnDataCaptureListener()
    {
      @Override
      public void onWaveFormDataCapture(Visualizer visualizer, byte[] bytes,
          int samplingRate)
      {
        updateVisualizer(bytes);
      }

      @Override
      public void onFftDataCapture(Visualizer visualizer, byte[] bytes,
          int samplingRate)
      {
        updateVisualizerFFT(bytes);
      }
    };
    // Create the Visualizer object and attach it to our media player.
    if (mVisualizer==null) {
    mVisualizer = new Visualizer(player.getAudioSessionId());
    mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);
   mVisualizer.setDataCaptureListener(captureListener, Visualizer.getMaxCaptureRate() / 2, true, true);
   // Enabled Visualizer and disable when we're done with the stream
    mVisualizer.setEnabled(true);
    addBarGraphRenderers();
  } else {
   mVisualizer.setDataCaptureListener(captureListener,
   Visualizer.getMaxCaptureRate() , true, true);
   mVisualizer.setEnabled(true); 
  }}

Upd1: I'am rewrite visualizer for call finalize, but this not help me:

public class visualizer1 extends Visualizer {

    public visualizer1(int audioSession) throws UnsupportedOperationException,
            RuntimeException {
        super(audioSession);
    }
    @Override 
    public void finalize() {
            super.finalize();
    }
}

public void release() {
    if (mVisualizer!=null) {
        mVisualizer.release();
        mVisualizer.finalize();
        mVisualizer=null;
    }
}

And i have many visualizers: my problem


Solution

  • solved this problem. When i set mVisualizer.setEnabled(false); before release visualizer finalize automatically:

     public void release()
      {
        if (mVisualizer!=null) {
        mVisualizer.setEnabled(false);
        mVisualizer.release();
        mVisualizer=null;
       }
      }
    

    UPD: I tested my code for a very long time (about a year) and found out that if I did, then very rarely the application crashes with a fatal error on the line "mVisualizer.release ();". This can not be tracked using libraries, like crashlytics. So I removed "mVisualizer.setEnabled (false);". In Android 7.0, I have a maximum of 3-4 Visualizer threads and this does not cause a memory leak.

    UPD2: I found the reason for the crash application. The problem is that the mVisualizer.release () command; Sometimes it was executed at the time of visualization rendering. I added a boolean variable to avoid this and now the crash is gone. Enjoy!

    private boolean release = false;
    public void release() {
        if (mVisualizer != null) {
            if (cameraLed == true) {
                barGraphRendererBottom.stopCamera();
            }
            if (isShown())
                release = true;
            else {
                release = false;
                mVisualizer.setEnabled(false);
                mVisualizer.release();
                mVisualizer = null;
            }
        }
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (release) {
            release = false;
            mVisualizer.setEnabled(false);
            mVisualizer.release();
            mVisualizer = null;
        } else {
            mRect.set(0, 0, getWidth(), getHeight());
            if (mCanvasBitmap == null) {
                mCanvasBitmap = Bitmap.createBitmap(canvas.getWidth(),
                        canvas.getHeight(), Config.RGB_565);
            }
            if (mCanvas == null) {
                mCanvas = new Canvas(mCanvasBitmap);
            }
    
            canvas.drawBitmap(mCanvasBitmap, new Matrix(), null);
        }
    }