带有AudioEffect的Android MediaPlayer:出错(-22,0)

时间:2012-05-02 07:00:27

标签: java android audio android-mediaplayer audioeffect

嗯,这只是我的要求..

我有一个WAV文件,我想打开它,添加一些效果,然后播放。

我使用MediaPlayer播放文件,PresetReverb添加一些效果。

这是我的代码

public void playSound(){
   String fullPath = MainActivity.this.filePath + "tmpaudio.wav";

   final MediaPlayer player = new MediaPlayer();
   player.setDataSource(this, Uri.parse(fullPath));

   PresetReverb pReverb = new PresetReverb(0,player.getAudioSessionId());
   pReverb.setPreset(PresetReverb.PRESET_LARGEROOM);
   pReverb.setEnabled(true);
   player.attachAuxEffect(eReverb.getId());
   player.setAuxEffectSendLevel(1.0f);

   //prepare for playback
   player.prepare();

   // Media prepared listener
   player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
      public void onPrepared(MediaPlayer mp) {
         //play
         player.start();
      } 
   });
}

当我运行此代码时,我正在登录logcat(我没有记录。)

  

05-02 12:02:42.356:E / MediaPlayer(17250):错误(-22,0)

但是当我评论这些行时

PresetReverb pReverb = new PresetReverb(0,player.getAudioSessionId());
pReverb.setPreset(PresetReverb.PRESET_LARGEROOM);
pReverb.setEnabled(true);
player.attachAuxEffect(eReverb.getId());
player.setAuxEffectSendLevel(1.0f);

MediaPlayer正在成功播放该文件。所以我的WAV文件没有错。

有点失望,我尝试了EnvironmentalReverb,而不是PresetReverb,

EnvironmentalReverb eReverb = new EnvironmentalReverb(1, player.getAudioSessionId());
eReverb.setDecayHFRatio((short) 1000);
eReverb.setDecayTime(10000);
eReverb.setDensity((short) 1000);
eReverb.setDiffusion((short) 1000);
eReverb.setReverbLevel((short) -1000);
eReverb.setEnabled(true);
player.attachAuxEffect(eReverb.getId());
player.setAuxEffectSendLevel(1.0f);

我也遇到了同样的错误(错误(-22,0))。

所以要么我错过了一些如此明显的东西,要么AudioEffect家庭类存在问题(在文档或api本身)。任何人都能解释一下吗?

编辑:我忘了添加,当我调试代码时,会记录错误

 player.start();

已执行。我在发布上面的代码段之前删除了异常处理部分。但我很肯定,我执行时也没有例外。

再次编辑:

this链接我开始明白错误-22是PVMFErrLicenseRequiredPreviewAvailable

/*
 Error due to the lack of a valid license for the content.  However
 a preview is available.
 */
const PVMFStatus PVMFErrLicenseRequiredPreviewAvailable = (-22);

我用PVMFErrLicenseRequiredPreviewAvailable搜索,我得到了this文件。并在第87页

  

14.10.5在没有有效许可证的情况下预览DRM内容

     

第14.10.3节中涵盖的场景的变体是这样的情况   没有有效的许可证可以完整播放一段内容,但是   那里可以预览。这种情况可能是一种常见的方式   最初分发内容以便消费者可以预览它   在决定购买完整许可证之前。在这种情况下,Init()   方法将返回代码   PVMFErrLicenseRequiredPreviewAvailable,   表示许可证   完全播放需要,但可以预览。为了   播放预览,应用程序必须删除当前的源   将其添加回本地数据源上设置的标志以指示   预览模式。

现在我播放的WAV文件是由我在android SDK本身使用SpeechToText工具生成的。我不知道什么牌照让我玩这个文件。

3 个答案:

答案 0 :(得分:13)

好吧,我终于开始工作了。我重读了文档,玩了代码,突然一切正常。这些是我的发现,以防将来帮助任何人。

在PresetReverb

的情况下

在presetReverb文档中

  

PresetReverb是输出混合辅助效果,应该是   在Audio session 0上创建为了MediaPlayer或   AudioTrack被赋予这种效果,它们必须是明确的   附加到它并且必须指定发送级别。使用效果ID   由getId()方法返回以指定此特定效果   将其附加到MediaPlayer或AudioTrack。

那说

PresetReverb pReverb = new PresetReverb(0,player.getAudioSessionId()); <== error

是不允许的。您只能使用全局音频会话0来构建PresetReverb。

PresetReverb pReverb  = new PresetReverb(1,0); <== correct

现在我们可以使用

将它与MediaPlayer或AudioTrack相关联
player.attachAuxEffect(pReverb.getId());
player.setAuxEffectSendLevel(1.0f);

我的完整PresetReverb代码是

PresetReverb pReverb    = new PresetReverb(1,0);
player.attachAuxEffect(pReverb.getId());
pReverb.setPreset(PresetReverb.PRESET_LARGEROOM);
pReverb.setEnabled(true);
player.setAuxEffectSendLevel(1.0f);

注意:如果您正在寻找良好的混响效果或回声,请更好地使用EnvironmentalReverb。我对PresetReverb的表现感到有些失望。

在EnvironmentalReverb

的情况下

来自EnvironmentalReverb的文档

  

EnvironmentalReverb是输出混合辅助效果,应在音频会话0上创建。为了MediaPlayer或   AudioTrack被赋予这种效果,它们必须是明确的   附加到它并且必须指定发送级别。使用效果ID   由getId()方法返回以指定此特定效果   将其附加到MediaPlayer或AudioTrack。

与PresetReverb完全一样,但是当我写下

Log.e("DEBUG","sessionId : " + player.getAudioSessionId()); <== printed "454"
EnvironmentalReverb  eReverb 
             = new EnvironmentalReverb(0,player.getAudioSessionId()); //should be error as per documentation
//player.attachAuxEffect(eReverb.getId());   <== Yes this one was commented

没有错误,我得到了良好的混响效果和回声。所以这似乎是文档中的一个错误。此外,当我们将播放器的会话ID传递给构造函数(player.getAudioSessionId())时,似乎不需要使用EnvironmentalReverb实例附加播放器。奇怪..

为了完整起见,这个也像文档说的那样工作。

EnvironmentalReverb  eReverb 
             = new EnvironmentalReverb(0,0); 
player.attachAuxEffect(eReverb.getId());     <== No,not comment this one

对于其他AudioEffect儿童(均衡器,BassBoost,虚拟器)

这些不属于我的问题。但对于将来看到这一点的每个人来说......

  

注意:将插入效果(均衡器,低音增强,虚拟器)附加到   不推荐使用会话0的全局音频输出组合。

请参阅documentation

关于错误(-22,0)

嗯,公平地说这不是一条信息性的错误信息。我不知道为什么当我们弄乱音频会话时会出现无效的许可错误。无论如何,当我更正音频会话参数时,此错误消失了。这就是我所知道的。

答案 1 :(得分:1)

我遇到了同样的问题,使用音频会话0你必须使用权限MODIFY_AUDIO_SETTINGS

答案 2 :(得分:0)

这一行本质上解决了其中一个问题,但它仍然需要权限。

PresetReverb pReverb = new PresetReverb(1,0);

因此,将以下行添加到AndroidManifest.xml实际上解决了根本问题:

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

OH,您还需要设置PresetReverb并将其附加到您的AudioTrack,以便之前执行AudioTrack.write()和AudioTrack.play()。