如何在不使用FFmpeg或JCodec的情况下将图像转换为视频,仅使用android MediaCodec.视频图像是位图文件,可以是ARGB888或YUV420(我的选择).最重要的是视频必须可以在Android设备上播放,最大API是16.我知道API 18 MediaMuxer,我不能使用它.
请帮助我,我坚持了很多天.(JCodec要慢,FFmpeg使用起来很复杂).
我MediaCodec用来编码视频.帧通过相机预览回调到MediaCodec实例(没有使用Surface).我正在使用JCodec库进行多路复用,并且我能够流式传输视频(视频播放器显示正确的持续时间,我可以使用搜索栏更改视频位置).
今天我尝试使用MediaMuxer而不是JCodec和我有视频仍然看起来很好,但持续时间绝对不正确(几小时而不是一分钟)和搜索栏根本不工作.
mediaMuxer = new MediaMuxer("/path/to/video.mp4", MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
Run Code Online (Sandbox Code Playgroud)
我收到以下代码时会被懒惰地调用MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
videoTrackIndex = mediaMuxer.addTrack(encoder.getMediaFormat());
mediaMuxer.start();
Run Code Online (Sandbox Code Playgroud)
我用以下代码编码帧:
mediaMuxer.writeSampleData(videoTrackIndex, byteBuffer, bufferInfo);
Run Code Online (Sandbox Code Playgroud)
byteBuffer并且在一些定位之后bufferInfo直接来自MediaCodec:
byteBuffer.position(bufferInfo.offset);
byteBuffer.limit(bufferInfo.offset + bufferInfo.size);
Run Code Online (Sandbox Code Playgroud)
演示时间设置正确:
mMediaCodec.queueInputBuffer(inputBufferIndex, 0, getWidth() * getHeight() * 1.5, System.nanoTime() / 1000, 0);
Run Code Online (Sandbox Code Playgroud)
在记录的最后我做:
mediaMuxer.stop();
mediaMuxer.release();
Run Code Online (Sandbox Code Playgroud)
日志:
I/MPEG4Writer? setStartTimestampUs: 0
I/MPEG4Writer? Earliest track starting time: 0
D/MPEG4Writer? Stopping Video track
I/MPEG4Writer? Received total/0-length (770/0) buffers and encoded 770 frames. - video
D/MPEG4Writer? Stopping …Run Code Online (Sandbox Code Playgroud) 当谈到MediaCodec(以及一般的视频编码/解码)时,我有点新意,所以如果我在这里说的任何错误,请纠正我.
我想用VLC/ffplay播放MediaCodec的原始h264输出.我需要这个才能发挥,因为我的最终目标是将一些实时视频流传输到计算机,而MediaMuxer只在磁盘上生成一个文件,而不是我可以以非常低的延迟流式传输到桌面.(我对其他解决方案持开放态度,但我还没有发现任何符合延迟要求的其他解决方案)
这是我正在使用的代码对视频进行编码并将其写入文件:(它基于此处找到的MediaCodec示例,仅删除了MediaMuxer部分)
package com.jackos2500.droidtop;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.opengl.EGL14;
import android.opengl.EGLConfig;
import android.opengl.EGLContext;
import android.opengl.EGLDisplay;
import android.opengl.EGLExt;
import android.opengl.EGLSurface;
import android.opengl.GLES20;
import android.os.Environment;
import android.util.Log;
import android.view.Surface;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
public class StreamH264 {
private static final String TAG = "StreamH264";
private static final boolean VERBOSE = true; // lots of logging
// where to put the output file (note: /sdcard requires WRITE_EXTERNAL_STORAGE permission)
private static final …Run Code Online (Sandbox Code Playgroud) 我正在编写一个Android应用程序,在其中,我有一个VirtualDisplay镜像屏幕上的内容,然后我将帧从屏幕发送到一个实例MediaCodec.它有效,但是,我想添加一种指定编码视频的FPS的方法,但我不确定如何这样做.
根据我的阅读和实验,丢弃编码的帧(基于演示时间)不能很好地工作,因为它最终会产生块状/伪影的视频,而不是低帧率的平滑视频.其他阅读表明,做我想要的唯一方法(限制FPS)将限制传入的FPS到MediaCodec,但是VirtualDisplay刚收到一个Surface由MediaCodec下面构造的
mSurface = <instance of MediaCodec>.createInputSurface();
mVirtualDisplay = mMediaProjection.createVirtualDisplay(
"MyDisplay",
screenWidth,
screenHeight,
screenDensity,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
mSurface,
null,
null);
Run Code Online (Sandbox Code Playgroud)
我也试过子类Surface和限制被馈送到帧MediaCodec通过unlockCanvasAndPost(Canvas canvas),但该功能似乎从来没有对我的情况下被调用,因此,有可能是我如何延长一些古怪Surface以及与互动Parcel的writeToParcel功能被称为上我的实例,但这是在我的实例中调用的唯一函数(我可以告诉).
其他阅读建议我可以从编码器 - >解码器 - >编码器,并限制第二个编码器馈送帧的速率,但这是很多额外的计算,如果我可以避免它,我宁愿不做.
有没有人成功限制VirtualDisplay饲喂它的速度Surface?任何帮助将不胜感激!
我一直在通过MediaCodec将视频直接渲染到我的UI中从SurfaceView获取的Surface.这非常有效.
我现在正在尝试使用MediaCodec作为编码器.作为测试,我想渲染到Surface(如上所述)并通过配置为编码器的MediaCodec的不同实例进行环回.
我看到编码器的createInputSurface()方法.我想我希望编码器创建这个表面然后让解码器MediaCodec使用它作为要绘制的表面.首先,这可能吗?
其次,我不确定如何从编码器创建的Surface创建SurfaceView.我只从SurfaceView中提取了一个Surface,而我从文档中看不到如何反向执行此操作.
我尝试按照这个问题使用android的MediaMuxer连接多个mp4音频文件并连接视频文件.
但由于某种原因,当我调用readSampleData时,MediaExtractor会抛出IllegalArgumentException
在官方API中,此函数不应该抛出任何异常!这是怎么回事 ?
我发现了一个旧问题,表明ByteBuffer的大小可能是负责的:Android MediaMuxer readSampleData IllegalStateException
我已经尝试了大量的大小值,但没有一个让问题消失.我应该知道标准尺寸吗?
任何提示都可以提供帮助!
boolean VERBOSE = true;
private boolean concatenateFiles(File dst, List<File> sources) {
if ((sources == null) || (sources.size() == 0)) {
return false;
}
boolean result;
MediaExtractor extractor = null;
MediaMuxer muxer = null;
try {
// Set up MediaMuxer for the destination.
muxer = new MediaMuxer(dst.getPath(), MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
// Copy the samples from MediaExtractor to MediaMuxer.
boolean sawEOS = false;
int frameCount = 0;
int offset = 100; …Run Code Online (Sandbox Code Playgroud) 我需要检测android设备的芯片组.所以我可以在MediaTek芯片组上禁用某些功能.(此问题中讨论的1080p编码MediaCodec编码视频底部有绿色条,色度搞定了)
我已经看了http://developer.android.com/reference/android/os/Build.html,但似乎没什么关系.
有没有办法找出使用MediaCodec.createDecoderByType(type)接收的解码器是硬件解码器还是软件解码器?
android hardware-acceleration android-mediaplayer mediacodec
我有一个示例应用程序(完整源代码),使用MediaCodec对相机帧进行编码,同时在GLSurfaceView上显示它们.
Systrace确认每秒进行30次绘图调用:

但是,屏幕记录录制(.mp4,YouTube)显示明显的帧速率要低得多.
简而言之,我的编码和显示循环执行以下操作:
在Galaxy Nexus LTE和Nexus 7(均采用AOSP 4.4)上,应用程序按预期执行.到目前为止,只有Nexus 5在屏幕上绘制的帧数与明显的帧数之间存在差异......
我祈祷我不是疯了.
背景:我做视频文件解复用,解码视频轨道,对接收到的帧应用一些更改,再次解码和复用它们.
在Android中执行此操作的已知问题是供应商指定编码器/解码器颜色格式的数量.Android 4.3引入了表面以使设备独立,但我发现很难使用它们,因为我的帧更改例程需要Canvas写入.
自Android 5.0以来,使用灵活的YUV420颜色格式很有前途.与用于解码的getOutputImage和用于编码的getInputImage一起,Image对象可以用作从解码MediaCodec检索的格式.我使用getOutputImage进行解码工作,并可以在RGB转换后可视化结果.为了编码YUV图像并将其排队到MediaCodec(编码器),似乎缺少链接:
从MediaCodec中取出输入缓冲区后
int inputBufferId = encoder.dequeueInputBuffer (5000);
Run Code Online (Sandbox Code Playgroud)
我可以访问返回的正确图像
encoder.getInputImage (inputBufferId);
Run Code Online (Sandbox Code Playgroud)
我填写图像缓冲区 - 这也工作,但我没有看到一种方法将输入缓冲区排队回编解码器进行编码...只有一个
encoder.queueInputBuffer (inputBufferId, position, size, presentationUs, 0);
Run Code Online (Sandbox Code Playgroud)
方法可用,但没有任何匹配图像.可以使用检索呼叫所需的大小
ByteBuffer byteBuffer = encoder.getInputBuffer (inputBufferId);
Run Code Online (Sandbox Code Playgroud)
和
byteBuffer.remaining ();
Run Code Online (Sandbox Code Playgroud)
但是除了getInputImage()之外,这似乎会在调用时搞砸编码器.
另一个缺少的文档或者我错了什么?
android ×10
mediacodec ×10
encoding ×2
mediamuxer ×2
decoder ×1
encoder ×1
ffmpeg ×1
h.264 ×1
opengl-es ×1
surfaceview ×1
video ×1