当前位置: 首页 > 知识库问答 >
问题:

带AudioEffect的Android MediaPlayer:获取错误(-22,0)

太叔鸿
2023-03-14

我有一个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);
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();
/*
 Error due to the lack of a valid license for the content.  However
 a preview is available.
 */
const PVMFStatus PVMFErrLicenseRequiredPreviewAvailable = (-22);

我用PVMFErrLicenseRequiredPreviewAvailable搜索了一下,得到了这份文档。在第87页

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

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

现在我播放的WAV文件是我使用android SDK本身的SpeechToText工具生成的。我不知道是什么许可证阻止我播放这个文件。

共有1个答案

喻元龙
2023-03-14

好吧,我终于把它弄好了。我重读了文档,玩了一下代码,突然间一切都正常了。这些是我的发现,以防将来对任何人有帮助。

在预置混响文档中

PresetReverb是一种输出混音辅助效果,应该在音频会话0上创建。为了将MediaPlayer或AudioTrack输入到该效果中,必须明确地将它们附加到该效果中,并且必须指定发送级别。在将此特定效果附加到MediaPlayer或AudioTrack时,使用getId()方法返回的效果ID来指定此特定效果。

上面写着

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 pReverb    = new PresetReverb(1,0);
player.attachAuxEffect(pReverb.getId());
pReverb.setPreset(PresetReverb.PRESET_LARGEROOM);
pReverb.setEnabled(true);
player.setAuxEffectSendLevel(1.0f);

来自EnvironmentalReverb的文档

EnvironmentalReverb是一种输出混音辅助效果,应在音频会话0上创建。为了将MediaPlayer或AudioTrack输入到该效果中,必须明确地将它们附加到该效果中,并且必须指定发送级别。在将此特定效果附加到MediaPlayer或AudioTrack时,使用getId()方法返回的效果ID来指定此特定效果。

和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
EnvironmentalReverb  eReverb 
             = new EnvironmentalReverb(0,0); 
player.attachAuxEffect(eReverb.getId());     <== No,not comment this one

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

参见文档

好吧,公平地说,这不是一个信息性的错误消息。我不知道为什么当我们搞乱音频会话时会出现无效许可证错误。不管怎样,当我更正音频会话参数时,这个错误消失了。我只知道这些。

 类似资料:
  • 问题内容: 好吧,这只是我的要求。 我有一个WAV文件,我想打开它,添加一些效果,然后播放。 我正在使用MediaPlayer播放文件,并使用PresetReverb添加一些效果。 这是我的代码 当我运行此代码时,我将获得logcat登录(我未登录。) 05-02 12:02:42.356:E / MediaPlayer(17250):错误(-22,0) 但是当我评论这些话 MediaPlayer

  • 而且 但这似乎不起作用,因为中没有可用的默认构造函数。我不熟悉龙目岛注释。有什么好的方法可以扩展基类,同时使用lombok注释吗?

  • 问题内容: 更新-自行回答 我看到必须确保从计算机正确解析了DNS,请查看节点文档以确保域是可解析的。 原始问题 我正在编写一个基于节点的程序,用户可以要求我代表他们执行一次httprequest {当然,他们向我提供一些数据和调用方法},但是每次我执行一次httprequest,都会给我一个错误 getaddrinfo ENOENT这是我的代码的外观 问题答案: 我已经看到,当您的主机(您通过h

  • 使用Maven生成JavaDoc时,我收到一条错误消息“错误获取链接:”,指的是一个文件javadoc-bundle-选项。其中包含带有目录的javadocResourcesDirectory。即使我创建了那个目录,我仍然会得到相同的错误。如何更正错误?

  • 下面的代码在javascript工作,它返回的响应的付款方式,例如'PM_1HZDPTHMQMK5H2YU0KAI****',我用这个付款方式收取付款,下面是条带的响应。 “提供的PaymentMethod以前与没有客户附件的PaymentIntent一起使用,与没有客户附件的连接帐户共享,或者与客户分离。它不能再次使用。若要多次使用PaymentMethod,必须先将其附加到客户”。 问题是,我