MediaCodec 将 WAV 转换为 AMR 的文件无法播放

2024-04-06

我在用MediaCodec转换一个.wav文件至.amr。我使用以下代码进行输入和获取编码缓冲区。我得到了编码文件,但它无法播放,我的输入是正确的,因为我能够在 Audacity 中播放该文件。我在用EncodeDecodeTest.java来自android API测试。任何有关潜在问题的指示都值得赞赏。

 MediaCodec codec = MediaCodec.createByCodecName(componentName);

    try {
        codec.configure(
                format,
                null /* surface */,
                null /* crypto */,
                MediaCodec.CONFIGURE_FLAG_ENCODE);
    } catch (IllegalStateException e) {
        AppLog.logString("codec '" + componentName + "' failed configuration.");

       // assertTrue("codec '" + componentName + "' failed configuration.", false);
    }

    codec.start();
    ByteBuffer[] codecInputBuffers = codec.getInputBuffers();
    ByteBuffer[] codecOutputBuffers = codec.getOutputBuffers();

    int numBytesSubmitted = 0;
    boolean doneSubmittingInput = false;
    int numBytesDequeued = 0;

    while (true) {
        int index =0 ;

        if (!doneSubmittingInput) {
            index = codec.dequeueInputBuffer(kTimeoutUs /* timeoutUs */);

            if (index != MediaCodec.INFO_TRY_AGAIN_LATER) {
                if (numBytesSubmitted >= filesize ){
                    codec.queueInputBuffer(
                            index,
                            0 /* offset */,
                            0 /* size */,
                            0 /* timeUs */,
                            MediaCodec.BUFFER_FLAG_END_OF_STREAM);

                    if (VERBOSE) {
                        AppLog.logString("queued input EOS.");
                    }

                    doneSubmittingInput = true;
                } else {
                    int inputsize = 0;
                    int size = 0;
                    if ((filesize - numBytesSubmitted) > codecInputBuffers[index]
                                .limit()) {
                            inputsize = codecInputBuffers[index].limit();
                        } else
                            inputsize = (int) (filesize - numBytesSubmitted);
                            size = queueInputBuffer(codec,
                                codecInputBuffers, index, in, inputsize);
                    numBytesSubmitted += size;
                    /*if (VERBOSE) {
                        AppLog.logString("queued " + size + " bytes of input data.");
                    }*/
                }
            }else
                 AppLog.logString("MediaCodec.INFO_TRY_AGAIN_LATER.");
        }

        MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
        index = codec.dequeueOutputBuffer(info, kTimeoutUs /* timeoutUs */);

        if (index == MediaCodec.INFO_TRY_AGAIN_LATER) {
        } else if (index == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
            AppLog.logString("INFO_OUTPUT_FORMAT_CHANGED");
            MediaFormat fmt = codec.getOutputFormat();
            AppLog.logString(fmt.getString(MediaFormat.KEY_MIME));
        } else if (index == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
            codecOutputBuffers = codec.getOutputBuffers();
        } else {
            dequeueOutputBuffer(codec, codecOutputBuffers, index, info, fos);

            numBytesDequeued += info.size;

            if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                if (VERBOSE) {
                    AppLog.logString("dequeued output EOS.");
                }
                break;
            }

            if (VERBOSE) {
                AppLog.logString("dequeued " + info.size + " bytes of output data.");
            }
        }
    }

    if (VERBOSE) {
        AppLog.logString("queued a total of " + numBytesSubmitted + "bytes, "
                + "dequeued " + numBytesDequeued + " bytes.");
    }

    codec.release();
    codec = null;

queueInputBuffer and dequeueOutputBuffer实施如下:

private int queueInputBuffer(
        MediaCodec codec, ByteBuffer[] inputBuffers, int index, FileInputStream in, int size) {
        ByteBuffer buffer = inputBuffers[index];
        buffer.clear();

       // int size = buffer.limit();
        AppLog.logString("Size is :" + size);
        byte[] data = new byte[size];
        try {
            in.read(data,0,size);
        } catch (IOException e) {
            e.printStackTrace();
        }
        buffer.put(data);
        buffer.flip();
        codec.queueInputBuffer(index, 0 /* offset */, size, 0 /* timeUs */, MediaCodec.BUFFER_FLAG_SYNC_FRAME);

        return size;
}

private void dequeueOutputBuffer(
        MediaCodec codec, ByteBuffer[] outputBuffers,
        int index, MediaCodec.BufferInfo info, FileOutputStream fos) {
    byte[] data= new byte[info.size];
    ByteBuffer out = outputBuffers[index];
    out.get(data);
    try {
        fos.write(data);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    codec.releaseOutputBuffer(index, false /* render */);
}

None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MediaCodec 将 WAV 转换为 AMR 的文件无法播放 的相关文章

随机推荐

  • 应该使用 unique_ptr 来更轻松地实现“移动”语义吗?

    Edit made Foo and Bar稍微不那么琐碎 直接替换为shared ptr lt gt 更加困难 Should unique ptr lt gt 用作实现移动语义的更简单方法 对于像这样的课程 class Foo int m
  • UIDatePicker 只显示周日的日期?

    我们如何设置 UIDatePicker 值以在 swift iOS 中仅显示星期日的日期 最后 我自己找到了解决方案 在 didSelectRow 方法中检查所选日期是否是星期日 如果是 则可以 但如果不是 则重新加载组件以选择最近星期日的
  • 使用curl命令将文件保存到特定文件夹

    在 shell 脚本中 我想从某个 URL 下载文件并将其保存到特定文件夹 我应该使用什么特定的 CLI 标志来将文件下载到特定文件夹curl命令 或者我怎样才能得到这个结果 我不认为你可以给出curl的路径 但你可以CD到该位置 下载并C
  • PropertyAccessor.GetProperty( PR_ATTACH_DATA_BIN) Outlook 附件失败

    我需要创建一个 OutLook 加载项 用于捕获带有大附件的电子邮件 并将附件替换为可用于下载附件的 URL I found this https msdn microsoft com en us library office hh2908
  • git pull 忽略图像文件

    我是一个存储库的贡献者 偶尔会发布图像 图片确实不是必需的 但其他贡献者将继续add and push他们到存储库 我想表演pull忽略图像文件后缀的操作 例如 png git 目录占用了太多空间 我真的不需要拉这些图像文件 我怎能不pul
  • Android Eclipse 启动委托调试会话卡在 27%

    Eclipse 似乎停留在 27 启动 MyProject 27 Eclipse 可能会解释更多 我真的没有30分钟的时间看这个 我的意思是 如果有什么东西在它的方式可能喜欢它需要的资源 它在哪里表明在这么长的时间内问题是什么 see 尝试
  • Java Mockito-如何模拟参数数量不确定的方法

    我尝试使用 Mockito 来模拟getDeclaredMethod 爪哇的 但该方法的参数是不确定的 如何模拟这样的方法 public Method getDeclaredMethod String name Class paramete
  • 重音字符的问题

    I have a search box on my site and i need to replace all the Spanish characters that user types in to equivalent English
  • 使用计时器和游戏循环

    我正在构建一个简单的控制台游戏 玩家会移动当按键按下时 并且有移动的敌人自动 每种类型的敌人在 X 毫秒内移动一次 据我了解我应该使用timer 但我真的不知道如何在游戏循环中做到这一点 尚未构建 因为我不知道如何使用计时器 但它应该是wh
  • jQuery ajax 回调类成员? [复制]

    这个问题在这里已经有答案了 可能的重复 有没有办法让 JQuery ajax 成功函数访问它所包含的对象 https stackoverflow com questions 5378622 is there a way for a jque
  • 使用 GDI+ 创建透明背景的图像?

    我正在尝试创建一个具有透明背景的图像以显示在网页上 我尝试了几种技术 但背景总是黑色的 如何创建一个透明图像 然后在其上绘制一些线条 Call Graphics Clear Color Transparent 好 清晰图像 不要忘记使用具有
  • JTree 在应用程序启动时添加节点

    我想使用文件浏览器创建文本编辑器 因此当我启动应用程序时 我希望我的程序在 JTree 上添加节点 以便它向我显示所有文件和文件夹 例如 我的文档 文件夹中的所有文件和文件夹 并让我能够访问这些文件和文件夹 尤其是文件夹 我试图弄清楚安德鲁
  • 具有 contenteditable 的 onChange 事件[重复]

    这个问题在这里已经有答案了 代码如下 text span blah blah span text onChange 事件不起作用 至少在火狐浏览器中 我不想使用文本区域 输入标签 因为必须可以仅更改文本中的特定单词 并且必须内联显示 而不是
  • 使用 SQL 代理运行 SSIS 包时出现问题 - 失败并显示“DTSER_FAILURE(1)”

    我有一个存储在 MSDB 数据库中的 SSIS 包 当我执行它时它工作正常 它将在 SA 帐户下运行或使用 Windows 安全性 我想安排此作业与 SQL Agent 一起运行 但是当我这样做时 我收到一个奇怪的错误 并且我尝试的任何配置
  • Discord Webhook 消息无法发送

    所以我有一段不久前有人发布的代码 到现在已经完美运行一年了 它采用谷歌表单答案并将其作为网络钩子发布到不和谐频道 现在从昨天开始就不再起作用了 脚本没有任何改变 function onSubmit e var form FormApp ge
  • 为什么我无法导入 folium python 包?

    我已经 pip 安装了 folium 当我在主目录中工作时尝试导入它时 出现此错误 ImportError Traceback most recent call last
  • 使用程序员 dvorak 键盘布局(移位数字)在 xmonad 中切换工作区

    好吧 我实际上并没有使用德沃夏克 但是Neo2 http neo layout org 但由于我使用的是矩阵式键盘 真正符合人体工程学 http www trulyergonomic com 我也改变了数字 因此我的这个结构xmonad h
  • MSVC 直接构造函数调用扩展

    In 这个回应 https stackoverflow com a 23274182 420683 没有手套的 https stackoverflow com users 1902313 tloveless指出可以在 MSVC 中使用thi
  • 停止 Safari 4 窗口中的按键事件冒泡

    在 Safari 4 窗口中 似乎无法阻止某些关键事件在 Javascript 中冒泡到浏览器 This question https stackoverflow com questions 1492080 disable f5 key i
  • MediaCodec 将 WAV 转换为 AMR 的文件无法播放

    我在用MediaCodec转换一个 wav文件至 amr 我使用以下代码进行输入和获取编码缓冲区 我得到了编码文件 但它无法播放 我的输入是正确的 因为我能够在 Audacity 中播放该文件 我在用EncodeDecodeTest jav