Android Visualizer 实现崩溃

Posted

技术标签:

【中文标题】Android Visualizer 实现崩溃【英文标题】:Android Visualizer implementation crash 【发布时间】:2012-01-25 14:40:37 【问题描述】:

我正在尝试实现 android Visualizer 类。我查找了其他问题线程,但仍然遇到致命错误。在我看来,这一切都应该正常工作,无论出于何种原因,AVD 不断崩溃。

首先,我正在使用权限:

<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>

这是我的日志:

12-21 15:10:46.983: D/dalvikvm(642): Not late-enabling CheckJNI (already on)
12-21 15:10:48.823: D/MediaPlayer(642): Couldn't open file on client side, trying server     side  
12-21 15:10:53.603: E/AudioEffect(642): set(): AudioFlinger could not create effect,    status: -22
12-21 15:10:53.603: E/visualizers-JNI(642): Visualizer initCheck failed -4
12-21 15:10:53.613: E/Visualizer-JAVA(642): Error code -4 when initializing Visualizer.
12-21 15:10:53.613: E/Visual Ex(642): Cannot initialize Visualizer engine, error: -4
12-21 15:10:53.964: D/gralloc_goldfish(642): Emulator without GPU emulation detected.

还有我的代码:

package MediaPlayer.namespace;

import java.io.IOException;

import android.app.Activity;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.media.audiofx.Visualizer;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;

public class MediaPlayerActivity extends Activity 

Visualizer      visual;
int             formattedVizData[];
byte            rawWaveForm[];
int             cont = 0xFF;

public void onCreate(Bundle savedInstanceState) 

    //start
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);


    ///start media player & visualizer.
    MediaPlayer mediaPlayer = new MediaPlayer();
    mediaPlayer = MediaPlayer.create(this, Uri.parse("http://vprbbc.streamguys.net:80/vprbbc24.mp3"));
    mediaPlayer.start();
    // Create the Visualizer object and attach it to our media player.
    try
        visual = new Visualizer(mediaPlayer.getAudiosessionId()); // this line causing Exception 
        visual.setEnabled(true);
        visual.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);
        
        catch(Exception ex)
        
            Log.e("Visual Ex", ex.getMessage());
        
    

【问题讨论】:

你解决了吗?我有同样的问题,我自己的代码和 SDK 的 ApiDemos 中的示例。我已经在我的 2.3 手机和 4.0.3 模拟器上试过了。 【参考方案1】:

我有同样的问题,所以尝试添加 AndroidManifest.xml 文件中的权限

另外,如果你不想看到那个 audi wave,你应该在画布或其他东西上展示它......

工作示例:

//android.permission.MODIFY_AUDIO_SETTINGS for audio settings and also
//android.permission.INTERNET for internet streaming

package com.janilemy;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.audiofx.Visualizer;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;

import java.io.IOException;

public class AudioFxDemoActivity extends Activity 

    //Here is your URL defined
String url = "http://vprbbc.streamguys.net/vprbbc24.mp3";

    //Constants for vizualizator - HEIGHT 50dip
private static final float VISUALIZER_HEIGHT_DIP = 50f;

    //Your MediaPlayer
MediaPlayer mp;

//Vizualization
private Visualizer mVisualizer;

    private LinearLayout mLinearLayout;
    private VisualizerView mVisualizerView;
    private TextView mStatusTextView;


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    //Info textView
    mStatusTextView = new TextView(this);

    //Create new LinearLayout ( because main.xml is empty )
    mLinearLayout = new LinearLayout(this);
    mLinearLayout.setOrientation(LinearLayout.VERTICAL);
    mLinearLayout.addView(mStatusTextView);

    //set content view to new Layout that we create
    setContentView(mLinearLayout);

    //start media player - like normal
    mp = new MediaPlayer();
    mp.setAudioStreamType(AudioManager.STREAM_MUSIC);

    try 
        mp.setDataSource(url); // set data source our URL defined
     catch (IllegalArgumentException e) 
        // TODO Auto-generated catch block
        e.printStackTrace();
     catch (IllegalStateException e) 
        // TODO Auto-generated catch block
        e.printStackTrace();
     catch (IOException e) 
        // TODO Auto-generated catch block
        e.printStackTrace();
           

    try    //tell your player to go to prepare state
        mp.prepare(); 
     catch (IllegalStateException e) 
        // TODO Auto-generated catch block
        e.printStackTrace();
     catch (IOException e) 
        // TODO Auto-generated catch block
        e.printStackTrace();
    
            //Start your stream / player
    mp.start();

    //setup your Vizualizer - call method
    setupVisualizerFxAndUI();        

            //enable vizualizer
            mVisualizer.setEnabled(true);

            //Info text
    mStatusTextView.setText("Playing audio...");


    //Our method that sets Vizualizer
private void setupVisualizerFxAndUI() 
    // Create a VisualizerView (defined below), which will render the simplified audio
    // wave form to a Canvas.

    //You need to have something where to show Audio WAVE - in this case Canvas
    mVisualizerView = new VisualizerView(this);
    mVisualizerView.setLayoutParams(new ViewGroup.LayoutParams(
            ViewGroup.LayoutParams.FILL_PARENT,
            (int)(VISUALIZER_HEIGHT_DIP * getResources().getDisplayMetrics().density)));
    mLinearLayout.addView(mVisualizerView);

    // Create the Visualizer object and attach it to our media player.
    //YOU NEED android.permission.RECORD_AUDIO for that in AndroidManifest.xml
    mVisualizer = new Visualizer(mp.getAudioSessionId());
    mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);
    mVisualizer.setDataCaptureListener(new Visualizer.OnDataCaptureListener() 
        public void onWaveFormDataCapture(Visualizer visualizer, byte[] bytes,
                int samplingRate) 
            mVisualizerView.updateVisualizer(bytes);
        

        public void onFftDataCapture(Visualizer visualizer, byte[] bytes, int samplingRate) 
    , Visualizer.getMaxCaptureRate() / 2, true, false); 


@Override
protected void onPause() 
    super.onPause();

    if (isFinishing() && mp != null) 
        mVisualizer.release();
        mEqualizer.release();
        mp.release();
        mp = null;
    


/**
 * A simple class that draws waveform data received from a
 * @link Visualizer.OnDataCaptureListener#onWaveFormDataCapture 
 */
class VisualizerView extends View 
    private byte[] mBytes;
    private float[] mPoints;
    private Rect mRect = new Rect();

    private Paint mForePaint = new Paint();

    public VisualizerView(Context context) 
        super(context);
        init();
    

    private void init() 
        mBytes = null;

        mForePaint.setStrokeWidth(1f);
        mForePaint.setAntiAlias(true);
        mForePaint.setColor(Color.rgb(0, 128, 255));
    

    public void updateVisualizer(byte[] bytes) 
        mBytes = bytes;
        invalidate();
    

    @Override
    protected void onDraw(Canvas canvas) 
        super.onDraw(canvas);

        if (mBytes == null) 
            return;
        

        if (mPoints == null || mPoints.length < mBytes.length * 4) 
            mPoints = new float[mBytes.length * 4];
        

        mRect.set(0, 0, getWidth(), getHeight());

        for (int i = 0; i < mBytes.length - 1; i++) 
            mPoints[i * 4] = mRect.width() * i / (mBytes.length - 1);
            mPoints[i * 4 + 1] = mRect.height() / 2
                    + ((byte) (mBytes[i] + 128)) * (mRect.height() / 2) / 128;
            mPoints[i * 4 + 2] = mRect.width() * (i + 1) / (mBytes.length - 1);
            mPoints[i * 4 + 3] = mRect.height() / 2
                    + ((byte) (mBytes[i + 1] + 128)) * (mRect.height() / 2) / 128;
        

        canvas.drawLines(mPoints, mForePaint);
    

这是一个完整的 android 媒体播放器音频波形可视化示例......我希望它对您的解决方案有所帮助......

贾尼·L

【讨论】:

谢谢,但我已经将这些权限添加到 XML 文件中。就可视化器而言,我几乎拥有您所拥有的东西,尽管我不需要显示它,我只是使用该类从正在播放的音乐中获取一些原始数据。我感谢您的努力。 @janilemy 你能帮我吗?我想用波形播放音频。我阅读了可视化器类信息并按照您的代码实现,但我在日志猫中收到错误,例如“可视化器类不是”。 @janilemy 你能帮帮我吗..我想添加图像和按钮以及可视化工具,我该怎么做?通过编码..我试过这么膨胀,但我初始化失败了..请帮助我【参考方案2】:

使用 Visualizer 有一些重要事项。

    最小api level 必须等于或大于9。 Visualizer engine,错误:-1 表示 RECORD_AUDIO permission 是 不见了。 Visualizer engine,错误:-4 表示 Operation failed due to bad parameter。价值。 Visualizer 的配置有问题,您没有正确设置 Visualizer。

还可以查看我的answer here。

注意

参数(audioSession)系统范围内唯一的音频会话标识符。如果audioSession 不为0,则visualizer 将附加到同一音频会话中的MediaPlayer 或AudioTrack。否则,Visualizer 将应用于输出组合。

【讨论】:

后期评论但是:我发现添加权限后可能需要重新启动。看看我的回答***.com/questions/6971567/… @Kaushal28 你好,我也遇到-3错误代码,这个代码是什么意思?你有没有解决过这个错误?请给我一些建议 @ihsan,gaozp 我也收到了-3的错误代码,我还没有找到解决方案。你们中的任何一个都有吗?【参考方案3】:

@Kaushal28、@ihsan、gaozp、@大钱

-3 错误代码表示 ERROR_NO_INIT 注:https://developer.android.com/reference/kotlin/android/media/audiofx/Visualizer

我也有同样的经历,使用了 AudioRecorder 的 audioSesstionId。

如果查看 Visualizer 的文档,则只能使用 MediaPlayer 和 AudioTrack,如下所示。

If audioSession is not 0, the visualizer will be attached to the 
MediaPlayer or AudioTrack in the same audio session. Otherwise, 
the Visualizer will apply to the output mix.

【讨论】:

【参考方案4】:

您缺少 Internet 权限

<uses-permission android:name="android.permission.INTERNET" />

【讨论】:

【参考方案5】:

启用后,您无法对 visulizer 的对象进行任何更改。所以只需像 belove 代码中所示的那样交换行。

public class MediaPlayerActivity extends Activity 

    Visualizer visual;
    int formattedVizData[];
    byte rawWaveForm[];
    int cont = 0xFF;

    public void onCreate(Bundle savedInstanceState) 

        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Start media player & visualizer.
        MediaPlayer mediaPlayer = new MediaPlayer();
        mediaPlayer = MediaPlayer.create(this, Uri.parse("http://vprbbc.streamguys.net:80/vprbbc24.mp3"));
        mediaPlayer.start();

        // Create the Visualizer object and attach it to our media player.
        try 

            // this line is not actually causing Exception ,It is because u are
            // enabling the visulizer to capture data & and after that setting
            // the capture size of buffer. U can't make any changes after
            // enabling it. I tried this same code and it's working fine for me
            visual = new Visualizer(mediaPlayer.getAudioSessionId());

            visual.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);
            visual.setEnabled(true);
         
        catch (Exception ex) 
            Log.e("Visual Ex", ex.getMessage());
        

    


请参阅此链接以获取最佳示例https://github.com/felixpalmer/android-visualizer

【讨论】:

【参考方案6】:

完成所有操作后,如果没有开始可视化,请尝试visualizationview.startRendering()

【讨论】:

以上是关于Android Visualizer 实现崩溃的主要内容,如果未能解决你的问题,请参考以下文章

[译] Android Visualizer 可视化器的自定义实现

[译] Android Visualizer 可视化器的自定义实现

初始化 Visualizer 时的 Android 错误代码 -3

Android 音频可视化 Visualizer

如何在android中录制音频时做Visualizer

android.media.audiofx.Visualizer 每隔一段时间就会抛出异常