我想对音频文件进行一些处理而不播放它们,只是数学。我怀疑我的做法是否正确,并且有几个问题。我读了一些示例,但大多数都是关于视频流的,根本没有处理原始数据。
我准备了一个 mp3 文件,它有 2 个相同的通道,即它是立体声的,但左右声道相同。解码后,我期望获得具有相同数字对的缓冲区,因为 PCM-16 交替存储通道样本,例如 { L R L R L R...},对吗?例如:
{ 105 105 601 601 -243 -243 -484 -484...}。
但我得到了一对接近但不相等的数字:
{ -308 -264 -1628 -1667 -2568 -2550 -4396 -4389}
mp3 算法是否对相同的值进行不同的编码?为什么?
我想处理 1024 个样本包中的数据。如果没有足够的样本用于另一个包,我想保存其余的直到下一批原始数据(参见mExcess代码)。是否能保证订单得以保留?
我曾经将“样本”理解为音频数据的每个值。这里我看到了MediaExtractor::readSampleData和MediaExtractor::advance方法。第一个返回约 2000 个值,在第二个的描述中表示“前进到下一个样本”。这只是命名的重叠吗?我看到了几个示例,其中这些方法在循环中成对调用。我的用法正确吗?
这是我的代码:
public static void foo(String filepath) throws IOException {
final int SAMPLES_PER_CHUNK = 1024;
MediaExtractor mediaExtractor = new MediaExtractor();
mediaExtractor.setDataSource(filepath);
MediaFormat mediaFormat = mediaExtractor.getTrackFormat(0);
mediaExtractor.release();
MediaCodecList mediaCodecList = new …Run Code Online (Sandbox Code Playgroud) 使用 FFMPEG 视频处理库和 MediaCodec 处理 Lottie 动画有一些独特的概念。在这方面,我想从 Lottie 动画制作视频并将该视频叠加在其他原始视频上。
但问题是我无法从 Lottie 动画制作具有透明背景的视频。因此,我使用 MediaCodec 和 MediaMuxer 从 Lottie 动画制作了简单的视频,它从 Lottie Drawable 中一帧一帧地将其附加到视频(Lottie Video)。这是有关此概念的链接 - https://engineering.21buttons.com/how-to-generate-videos-using-lottie-in-android-2db6ecceb2a
然后我使用 FFmpeg 库将此视频叠加到原始视频上。这里 FFmpeg 执行两个任务,首先它在 Lottie Video 中制作透明背景,其次它将这个 Lottie Video 覆盖在原始视频之上。
这里实际的问题就出来了,FFmpeg 在处理 25 秒的视频时需要超过 8 到 9 分钟,所以我想找到这个问题的解决方案,因为我的时间限制只有 1 到 2 分钟。任何人都有解决方案或实现此概念的新IDE,那么请告诉我,我将不胜感激。
我正在尝试使用 MediaCodec 从我拥有的一组位图生成 mp4 文件。
经过大量编码和测试后,我注意到互联网上不存在任何示例,也没有在 Android Studio 模拟器上进行任何工作,但它们确实可以在我的两部真实手机(android 7 和 9)中工作...所以我一直只进行测试真正的手机。
经过大量编码和测试后,我得到了一个有效的编码(适用于我的两部手机,但适用于 Android 模拟器)并部署到生产中。
我的网站已经上线几个月了,大约有 150 个日常用户,但其中大约 30% 的用户遇到了我在 Android 模拟器上注意到的同样的崩溃问题。所以这不是模拟器的限制。
E/ACodec:[OMX.google.h264.encoder] configureCodec 返回错误 -38 signalError(omxError 0x80001001,internalError -2147483648) E/MediaCodec:编解码器报告错误 0x80001001,actionCode 0,而处于状态 3 E/MediaCodec:配置失败错误 0x80001001,正在重置...
private static MediaCodecInfo selectCodec(String mimeType) {
int numCodecs = MediaCodecList.getCodecCount();
for (int i = 0; i < numCodecs; i++) {
MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
if (!codecInfo.isEncoder()) {
continue;
}
String[] types = codecInfo.getSupportedTypes();
for (String type : types) {
if (type.equalsIgnoreCase(mimeType)) {
return codecInfo;
} …Run Code Online (Sandbox Code Playgroud) 我正在开发使用 MediaCodec 录制视频并使用 MediaMuxer 将其转换为 Mp4(h.264+aac) 的应用程序。我想对该 mp4 进行加密,但我无法找到在录制时加密视频的方法。因此,目前我必须在创建视频后对视频进行加密。由于解码时使用 MediaCrypto 还有其他方法吗?
CameraX我想从(预览用例)获取图像并使用 .h.264 视频将它们编码为 h.264 视频MediaCodec。我怎样才能做到这一点?我正在尝试的是,通过使用.in来使用Surface返回的值。我从该设置中继承了一个类,并配置我的编码器和覆盖以从. 这预计会起作用吗?我真的可以共享这样的 Surface 并期望 CameraX 写入此 Surface 并填充我的编码器的输入吗?MediaCodec.createInputSurface()Preview.Builder()Preview.setSurfaceProvider()Preview.SurfaceProvideronSurfaceRequested()SurfacecreateInputSurface()
是否有更有效的方法来对实时 CameraX 源进行编码?
注意:我使用的是 KOTLIN
android kotlin-android-extensions android-mediacodec android-camerax
我正在尝试记录我无权访问的摄像机流。我只能访问自定义 SurfaceView,它从相机预览中获取图像并渲染图像。
我想将表面\相机视频保存到文件中。我正在使用 SDK 进行流式传输 (Amazon Chime),但我无权访问相机组件来添加用于录制的持久表面。
虽然我确实可以访问每个新图像“VideoRenderer.I420Frame”,但不确定如何将其积累到视频中。
我想到的另一种方法是使用“MediaRecorder”中的表面,但是当我使用这个表面(此视图)时,我得到了这个异常:
java.lang.IllegalArgumentException:不是 PercientSurface
我可以以某种方式创建一个 PersistentSurface 并将当前表面复制到新表面中,同时获取新图像吗?或者以其他方式解决这个问题?
这个类目前看起来像这样:
class RecordingVideoRenderView : SurfaceViewRenderer, VideoRenderView {
private var recording: Boolean = false
private val logger = ConsoleLogger(LogLevel.DEBUG)
private val TAG = "RecordingVideoRenderView"
private lateinit var recorder: MediaRecorder
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
override fun renderFrame(frame: Any) {
this.renderFrame(frame as VideoRenderer.I420Frame)
}
override fun initialize(initParams: Any?) {
this.init((initParams as EglBase).eglBaseContext, null)
}
override fun finalize() {
this.release()
}
fun startRecording() …Run Code Online (Sandbox Code Playgroud) 我正在接收一些 RTP 流,我只知道每个数据包的 AMR-WB 八位字节对齐 100 毫秒。某些第 3 方可以接收相同的流及其“可听”,因此这是正确的。现在我正在接收这些数据并尝试解码,但没有运气......
在里面:
val sampleRate = 16000
val mc = MediaCodec.createDecoderByType(MediaFormat.MIMETYPE_AUDIO_AMR_WB)
val mf = MediaFormat.createAudioFormat(MediaFormat.MIMETYPE_AUDIO_AMR_WB, sampleRate, 1)
mf.setInteger(MediaFormat.KEY_SAMPLE_RATE, sampleRate) // is it needed?
mc.configure(mf, null, null, 0)
mc.start()
Run Code Online (Sandbox Code Playgroud)
分别解码每个数据包:
private fun decode(decoder: MediaCodec, mediaFormat: MediaFormat, rtpPacket: RtpPacket): ByteArray {
var outputBuffer: ByteBuffer
var outputBufferIndex: Int
val inputBuffers: Array<ByteBuffer> = decoder.inputBuffers
var outputBuffers: Array<ByteBuffer> = decoder.outputBuffers
// input
val inputBufferIndex = decoder.dequeueInputBuffer(-1L)
if (inputBufferIndex >= 0) {
val inputBuffer = inputBuffers[inputBufferIndex]
inputBuffer.clear()
inputBuffer.put(rtpPacket.payload)
// …Run Code Online (Sandbox Code Playgroud) 在我的 Android 应用程序中,我使用 MediaCodec 以 webm (vp8) 格式编码一些媒体。编码按预期工作。但是,我需要确保偶尔创建一个同步帧。这是我所做的:
encoder.queueInputBuffer(..., MediaCodec.BUFFER_FLAG_SYNC_FRAME);
Run Code Online (Sandbox Code Playgroud)
在代码的后面,我检查同步帧:
encoder.dequeueOutputBuffer(bufferInfo, 0);
boolean isSyncFrame = (bufferInfo.flags & MediaCodec.BUFFER_FLAG_SYNC_FRAME);
Run Code Online (Sandbox Code Playgroud)
问题是 isSyncFrame 永远不会得到真正的值。
我想知道我是否在编码配置中犯了错误。可能有更好的方法告诉编码器偶尔创建一个同步帧。
我希望这不是 MediaCodec 中的错误。预先感谢您的帮助。
我从Grafika开始了一个项目并对其进行了修改。我有一个框架(与原始框架没有太大区别),它可以从 中捕获预览Camera并同时以不同的分辨率将其连续编码为视频。
MediaCodec(用于编码)配置为使用COLOR_FormatSurface,以便我们能够渲染到getInputSurface()使用 GLES查询的 Surface 。
媒体格式设置为 MIME 类型 video/avc
对于大多数手机,此设置非常有效。
但对于一些手机,编码视频的色度值略微倾斜,底部有一个绿色条。
目前编码器表面的分辨率为 640x360。选择渲染到表面的 EGLConfig 支持 32 位 RGBA 格式。
该预览是完美的所有手机。
所以我假设应用程序端或操作系统框架端的编码器参数有问题。
它发生在 Android 4.4 上。- 不确定,是否可以在 5.* 上重现。
] 2
实际上我正在使用 OpenGL,我想将我所有的纹理都放在 MP4 中以压缩它们。
然后我需要从我的 Android 上的 MP4 中获取它
我需要以某种方式解码 MP4 并根据请求逐帧获取。
我找到了这个 MediaCodec
https://developer.android.com/reference/android/media/MediaCodec
和这个 MediaMetadataRetriever
https://developer.android.com/reference/android/media/MediaMetadataRetriever
但是我没有看到如何逐帧请求的方法......
如果有人用过MP4,请给我一个去哪里的方法。
PS我正在使用本机方式(JNI),所以怎么做都无所谓..Java或本机,但我需要找到方法。
编辑1
我制作了某种电影(只有一个 3d 模型),所以我每 32 毫秒更改一次几何和纹理。因此,在我看来,将 mp4 用于 tex 似乎是合理的,因为每个新帧(32 毫秒)都与原始帧非常相似......
现在我为一个模型使用 400 帧。对于几何,我使用 .mtr,对于 tex,我使用 .pkm(因为它针对 android 进行了优化),所以我有大约 350 个 .mtr 文件(因为有些文件包含子索引)和 400 个 .pkm 文件......
这就是为什么我要为 tex 使用 mp4 的原因。因为一个 mp4 比 400 .pkm 小得多
编辑2
请看一下 Edit1
实际上,我需要知道的只是可以MP4按帧读取的Android API ?也许某种getNextFrame()方法?
像这样的东西
MP4Player player = new MP4Player(PATH_TO_MY_MP4_FILE);
void readMP4(){
Bitmap b;
while(player.hasNext()){ …Run Code Online (Sandbox Code Playgroud)