【问题标题】:Android MediaPlayer with AudioEffect : Getting Error (-22,0)带有 AudioEffect 的 Android MediaPlayer:出现错误 (-22,0)
【发布时间】:2012-05-02 07:00:26
【问题描述】:

好吧,这就是我的要求..

我有一个 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 工具生成的。我不知道播放这个文件的许可证是什么。

【问题讨论】:

  • 嗨 Krishnabhadra 我已经尝试过您的解决方案,但在我的设备中我没有发现任何回声效果。你能把你的示例代码发给我吗。提前谢谢。
  • 我的情况有错误 (1, -22)。这是同一个问题吗?

标签: java android audio android-mediaplayer audioeffect


【解决方案1】:

好吧,我终于让它工作了。我重新阅读了文档,使用了代码,突然一切都正常了。这些是我的发现,以防将来对任何人有所帮助。

在 PresetReverb 的情况下

在 presetReverb 文档中

PresetReverb 是一种输出混音辅助效果,应该是 在音频会话 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 是一种输出混合辅助效果,应在音频会话 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)

好吧,公平地说,这不是一条信息丰富的错误消息。我不知道为什么当我们搞砸音频会话时会出现Invalid license error。无论如何,当我更正音频会话参数时,此错误消失了。我知道的就这些了。

【讨论】:

  • 非常好的解释。我将实现均衡器。正如你所说的那样做了,但它在均衡器的构造上崩溃了。那么应该怎么解决呢。请帮我。我的代码与 AudioFxDemo 的示例代码相同
  • 嗨 Krishnabhadra 我已经尝试过您的解决方案,但在我的设备中我没有发现任何回声效果。你能把你的示例代码发给我吗?提前谢谢。
  • 为什么要写 PresetReverb(1,0) 。我到处都能看到 PresetReverb(0,0)。解释写 1 作为参数的目的。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    PresetReverb pReverb = new PresetReverb(1,0);
    

    所以在您的 AndroidManifest.xml 中添加以下行实际上解决了根本问题:

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

    哦,另外,您需要设置 PresetReverb 并将其附加到您的 AudioTrack 以在您执行 AudioTrack.write() 和 AudioTrack.play()之前发生。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-18
      相关资源
      最近更新 更多