问题标签 [mediaextractor]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
3408 浏览

android - Android MediaCodec 解码器输入/输出帧数

我正在Android中进行视频转码,并使用标准方法作为这些示例来提取/解码视频。我在具有不同视频设备的不同设备上测试了相同的过程,我发现解码器输入/输出的帧数有问题。

对于this question中的一些时间码问题,我使用队列来记录提取的视频样本,并在得到解码器帧输出时检查队列,如下代码:(我省略了与编码相关的代码以使其更清晰)

在某些情况下,如果解码器给出错误值(例如很多 0),队列可以“纠正”PTS。但是,解码器输入/输出的帧数仍然存在一些问题。

在 HTC One 801e 设备上,我使用编解码器 OMX.qcom.video.decoder.avc 来解码视频(使用 MIME 类型 video/avc)。除了最后一帧,采样时间和 PTS 与帧匹配得很好。例如,如果提取器将 100 帧然后 EOS 馈送到解码器,则前 99 个解码帧具有完全相同的时间值,但最后一帧丢失了,我从解码器得到输出 EOS。我测试了由内置摄像头、ffmpeg muxer 或 Windows 上的视频处理 AP 编码的不同视频。他们所有的最后一帧都消失了。

在一些带有 OMX.MTK.VIDEO.DECODER.AVC 编解码器的打击板上,事情变得更加混乱。一些视频具有良好的解码器PTS,并且输入/输出帧数正确(即解码完成时队列为空)。一些视频具有一致的输入/输出帧数,解码器输出中的 PTS 错误(我仍然可以通过队列纠正它们)。对于某些视频,在解码过程中会丢失很多帧。例如,提取器在 7 秒的视频中得到 210 帧,但解码器只输出最后的 180 帧。使用相同的解决方法是不可能恢复 PTS 的。

有什么方法可以预期 MediaCodec 解码器的输入/输出帧数?或者更准确地说,要知道解码器丢弃了哪些帧,而提取器为它提供了具有正确采样时间的视频样本?

0 投票
1 回答
13068 浏览

android - SurfaceTexture 的 onFrameAvailable() 方法总是调用太晚

我正在尝试使以下 MediaExtractor 示例正常工作:

http://bigflake.com/mediacodec/ - ExtractMpegFramesTest.java(需要 4.1,API 16)

我遇到的问题是 outputSurface.awaitNewImage(); 似乎总是抛出 RuntimeException("frame wait timed out"),只要mFrameSyncObject.wait(TIMEOUT_MS)调用超时就会抛出。无论我设置什么TIMEOUT_MSonFrameAvailable()总是在超时发生后立即被调用。我尝试了 50 毫秒和 30000 毫秒,结果是一样的。

似乎onFrameAvailable()在线程忙时无法完成调用,一旦发生超时导致线程代码执行结束,它就可以解析onFrameAvailable()调用。

有没有人设法让这个例子工作,或者知道 MediaExtractor 应该如何处理 GL 纹理?

编辑:在具有 API 4.4 和 4.1.1 的设备上进行了尝试,两者都发生了同样的情况。

编辑2:

感谢fadden,让它在4.4上工作。问题是ExtractMpegFramesWrapper.runTest()调用的方法th.join();阻塞了主线程并阻止了onFrameAvailable()调用被处理。一旦我发表评论th.join();,它就可以在 4.4 上运行。我想也许它ExtractMpegFramesWrapper.runTest()本身应该在另一个线程上运行,所以主线程没有被阻塞。

在调用 4.1.2 时也有一个小问题codec.configure(),它给出了错误:

我通过在通话前添加以下内容解决了这个问题:

然而,我现在在 4.1.1 (Galaxy S2 GT-I9100) 和 4.1.2 (Samsung Galaxy Tab GT-P3110) 上遇到的问题是它们总是将所有帧的 info.size 设置为 0。这是日志输出:

所以没有图像被保存。然而,相同的代码和视频适用于 4.3。我使用的视频是带有“H264 - MPEG-4 AVC (avc1)”视频编解码器和“MPEG AAAC Audio (mp4a)”音频编解码器的 .mp4 文件。

我也尝试了其他视频格式,但它们似乎在 4.1.x 上死得更快,而两者都在 4.3 上工作。

编辑3:

我按照你的建议做了,它似乎正确保存了帧图像。谢谢你。

关于 KEY_MAX_INPUT_SIZE,我尝试不设置,或将其设置为 0、20、200、... 200000000,所有结果都与 info.size=0 相同。

我现在无法在我的布局上将渲染设置为 SurfaceView 或 TextureView。我尝试替换这一行:

有了这个,surfaceTexture我的 xml 布局中定义的 SurfaceTexture 在哪里:

但它getMessage()==null在第二行引发了一个奇怪的错误。我找不到任何其他方法让它在某种视图上绘制。如何更改解码器以在 Surface/SurfaceView/TextureView 上显示帧而不是保存它们?

0 投票
1 回答
657 浏览

android - android.media.MediaExtractor 示例标志

是什么意思 :

  1. SAMPLE_FLAG_SYNC
  2. SAMPLE_FLAG_ENCRYPTED

我很难理解音频文件的“同步采样”概念。

此外,请随时提出任何技术参考以了解“整个场景”。

0 投票
2 回答
3197 浏览

android - MediaMuxer 无法制作可流式传输的 MP4

我正在使用 MediaExtractor 在 Android 上编辑 MP4 以获取音频和视频轨道,然后使用 MediaMuxer 创建一个新文件。它工作正常。我可以在手机(和其他播放器)上播放新的 MP4,但无法在网络上流式传输文件。当我停止 MediaMuxer 时,它会生成一条日志消息

“mp4 文件将无法流式传输。”

我查看了底层的本机代码(MPEG4Writer.cpp),似乎作者在计算所需的 moov 框大小时遇到​​了问题。如果比特率没有作为参数提供给编写器,它会尝试使用一些启发式猜测。问题是 MediaMuxer 不提供设置 MPEG4Writer 参数的能力。我是否遗漏了某些东西,或者我是否一直在寻找其他生成文件(或标题)的方法?谢谢。

0 投票
1 回答
785 浏览

android - Android:通过 MediaExtractor 打开视频不包含任何曲目


我在使用 MediaExtractor 打开视频文件时遇到问题。
视频: http: //video.blendertestbuilds.de/download.blender.org/ED/ED_HD.avi

代码:

日志:

所以你可以看到我的主要问题是这个电影文件中没有曲目。
我用内置的 MoviePlayer App 播放了同一部电影,它播放得很好。
我还用上述代码(h.264)播放了其他视频,没有任何问题。
你能告诉我我做错了什么吗?
我在 Logcat 中没有看到任何错误消息。
这一切都在 Android 4.4 下运行 在此

先感谢您的帮助。

0 投票
1 回答
7596 浏览

android - 使用 MediaDrm 在 android 中解密受 Widevine DRM 保护的视频

我正在尝试使用 Android 的 MediaDrm API 解密受 Widevine DRm 保护的媒体文件。但是 MediaDrm 是使用 UUId(DRM 方案的)实例化的。Android开发者网站说

“应用程序访问识别 DRM 方案的 UUID,通常来自内容中的元数据,并使用此 UUID 来构造能够支持内容所需 DRM 方案的 MediaDrm 对象的实例”。(www.developer.android.com/reference/android/media/MediaDrm.html)。

所以我尝试使用 MediaExtractor.getpsshInfo() 获取 UUID,但它返回了一个空对象。然后我尝试了 DrmManagerClient.getMetadata(uri of media content) 但这个方法也返回了null

我在下面的 Widevine 演示 uri 上试过这个:

内容网址:http
://commondatastorage.googleapis.com/wvmedia/starz_main_720p_6br_tp.wvm 许可服务器:https ://license.uat.widevine.com/getlicense/widevine

尽管在使用 DrmManagerClient API 获得权限后,我可以在 Android 的本机 MediaPLayer(VideoView) 中播放视频,但我想使用 Android 的 MediaDrm API 解密媒体文件并希望获得未加密的数据,但我无法做到,因为我是没有得到正确的 UUID 值。有人可以指出我实现这一目标的正确方向。

或者有人可以帮助我访问 DRM 方案 - UUID 值吗?

谢谢

0 投票
1 回答
3470 浏览

android - 在 MediaExtractor seekTo 和 AudioTrack 刷新行为意外错误之后,Android MediaCodec 刷新

我正在使用 AudioTrack、MediaCodec 和 MediaExtractor 的组合来解码和播放音乐。

根据文件

为了开始解码与先前提交的数据不相邻的数据(即在搜索之后),必须刷新()解码器。客户端在刷新时可能拥有的任何输入或输出缓冲区都会立即被撤销,即在调用 flush() 之后,客户端不再拥有任何缓冲区。

我在寻找后调用flush,所以我也应该调用mAudioTrack.flush();

尽管调用了flush,但audioTrack会播放之前写入的数据的一部分,并从新写入的数据继续。

如果不调用decoder.flush,可能会在音频播放中听到明显的故障。那么如何实现这种瞬时刷新并继续播放新写入的数据呢?

代码片段:

更新代码

0 投票
0 回答
1575 浏览

android - 提取“.m4s”时,MediaExtractor 抛出 IOException“无法实例化提取器”

我正在尝试在 Android 4.4 上通过 mediaExtractor 实现“m4s”播放器。但是,当设置“m4s”数据源时,mediaExtractor 会引发 IOException。这是我下面的代码片段

异常是从本机方法引发的,这是否意味着 Android 不支持“m4s”?

我已经使用相同的代码成功提取了“mp4”。如果Android原生支持“m4s”,请帮忙指出需要配置的部分。

0 投票
1 回答
2427 浏览

android - 有没有办法获取Android上的视频帧总数?

我目前正在使用 Android 上的 MediaCodec 和 MediaExtractor 在 Android 上提取、解码、编辑和重新编码视频。在这个过程中,我想给用户一些关于进展的信息。我已经在计算提取、解码和编码的帧数。为了计算百分比并向用户显示该过程有多远,我需要原始流中的总帧数。但是,我无法在 MediaExtractor 中找到方法。

有人知道在开始提取之前如何获取视频中的总帧数吗?

0 投票
3 回答
9307 浏览

android - 如何使用 MediaCodec、MediaExtractor 或 MediaMetadataRetriever 确定视频文件的帧率?

如何提取录制的视频文件的帧速率?我知道有 MediaFormat.KEY_FRAME_RATE 并且我可以通过 MediaExtractor 访问 MediaFormat 对象。但是 KEY_FRAME_RATE 仅适用于编码器。相反,我想找出已录制视频的帧速率。

有任何想法吗?