相关疑难解决方法(0)

MediaCodec和Camera:颜色空间不匹配

我一直在尝试使用新的低级MediaCodec,在Android平板电脑上使用H264编码来处理摄像头捕获的输入.我已经遇到了一些困难,因为MediaCodecAPI的文档很少,但我终于有了一些工作要做.

我按如下方式设置相机:

        Camera.Parameters parameters = mCamera.getParameters();
        parameters.setPreviewFormat(ImageFormat.YV12); // <1>
        parameters.setPreviewFpsRange(4000,60000);
        parameters.setPreviewSize(640, 480);            
        mCamera.setParameters(parameters);
Run Code Online (Sandbox Code Playgroud)

对于编码部分,我正在实例化MediaCodec对象,如下所示:

    mediaCodec = MediaCodec.createEncoderByType("video/avc");
    MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", 640, 480);
    mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 500000);
    mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 15);
    mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT,
            MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar); // <2>
    mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);
    mediaCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
    mediaCodec.start();
Run Code Online (Sandbox Code Playgroud)

最终目标是创建一个RTP流(并与Skype对应),但到目前为止,我只是将原始H264直接流式传输到我的桌面.在那里,我使用以下GStreamer管道来显示结果:

gst-launch udpsrc port=5555 ! video/x-h264,width=640,height=480,framerate=15/1 ! ffdec_h264 ! autovideosink
Run Code Online (Sandbox Code Playgroud)

一切都很好,除了颜色.我需要在计算机中设置2个颜色格式:一个用于摄像头预览(行标记<1>)和一个用于MediaCodec对象(标记为<2>)

确定<1>我使用的线的可接受值parameters.getSupportedPreviewFormats().据此,我知道相机上唯一支持的格式是ImageFormat.NV21ImageFormat.YV2.

<2>,我检索的MediaCodecInfo.CodecCapabilities -object类型视频/ AVC,作为整数值与对应19(MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar和2130708361(其不与任何值对应MediaCodecInfo.CodecCapabilities).

除上述之外的任何其他值都会导致崩溃.

结合这些设置会得到不同的结果,我将在下面展示.这是Android上的屏幕截图(即"真实"颜色): 在Android平板电脑上输入 以下是Gstreamer显示的结果:

<1> …

android colors rtp gstreamer h.264

32
推荐指数
2
解决办法
2万
查看次数

使用MediaCodec和MediaMuxer的图像到视频

我有一堆本地图像保存为jpeg文件.我的图像是使用CameraPreview捕获的,而PreviewFormat是默认值:NV21.我想从固定数量的图像生成一个小视频.

我不打算使用FFMpeg因为它需要NDK并且会引入兼容性问题.

MediaCodec和MediaMuxer似乎很有效,但网上没有一个可行的解决方案.

有一些参考资料导致我目前的解决方案.

1. EncodeAndMuxTest:http://bigflake.com/mediacodec/EncodeAndMuxTest.java.txt

这个是由法登写的.它非常适合我的需要,除了他使用的是createInputSurface而不是queueInputBuffer.

2. 将位图数组转换为YUV(YCbCr NV21)

我按照这个答案进行转换./sf/answers/1198188981/

3. 使用MediaCodec将一系列图像保存为视频

这个问题看起来与我的很相似,但我不打扰使用MediaMuxer.

我的代码如下:

public class EncodeAndMux extends Activity {
private static final String TAG = "EncodeAndMuxTest";

private static final boolean VERBOSE = false;

private static final File OUTPUT_DIR = Environment
        .getExternalStorageDirectory();

private static final String MIME_TYPE = "video/avc";

private static final int FRAME_RATE = 10;
// 10 seconds between I-frames
private static final int IFRAME_INTERVAL = 10;

private static final int NUM_FRAMES …
Run Code Online (Sandbox Code Playgroud)

android mediacodec

17
推荐指数
1
解决办法
1万
查看次数

MediaCodec.dequeInputBuffer/dequeOutputBuffer中的IllegalStateException

我正在尝试将PNG文件转换为单片视频片段,以便在项目中启动.

我有什么代码来实现它是: -

private boolean MediaConversion()
    {
        MediaCodec codec = MediaCodec.createEncoderByType(MIMETYPE);
        MediaFormat mediaFormat = null;
        if(CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_720P)){
            mediaFormat = MediaFormat.createVideoFormat(MIMETYPE, 1280 , 720);
        } else {
            mediaFormat = MediaFormat.createVideoFormat(MIMETYPE, 720, 480);
        }

        mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 700000);
        mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 10);
        mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar);
        mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);
        codec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);

        codec.start();

        ByteBuffer[] inputBuffers = codec.getInputBuffers();
        ByteBuffer[] outputBuffers = codec.getOutputBuffers();
        boolean sawInputEOS = false;
        int inputBufferIndex= -1, outputBufferIndex= -1;
        BufferInfo info=null;        

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        Bitmap bitmap = null;
        try {
        bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.image);                    
            Log.e("Uploaded", "Bitmap:" …
Run Code Online (Sandbox Code Playgroud)

android mediacodec

13
推荐指数
1
解决办法
1万
查看次数

MediaRecorder 和 VideoSource.SURFACE,停止失败:-1007(一个严重的 Android 错误)

我正在尝试MediaRecorder不使用Camera实例而是使用Surface视频源进行录制(是的,这是可能的,但事实证明它并不完美)-mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);

我只写什么问题:

下一个代码仅适用于某些设备,并在最近的设备重新启动后在某些设备上临时工作或根本不起作用

如果它不起作用 okMediaRecorder.stop()方法失败并出现下一个错误

E/MediaRecorder:停止失败:-1007 W/System.err:

java.lang.RuntimeException:停止失败。在

android.media.MediaRecorder.stop(本机方法)

录音机 mp4 文件太小(千字节),无法播放

测试设备:

适用于联想 P2、小米 A1

不适用于小米红米 5、索尼 Xperia、小米红米 4 Prime

您也可以阅读我的代码中的注释以更好地理解问题

new Thread(() -> {

    MediaRecorder mediaRecorder = new MediaRecorder();

    File file = new File(Environment.getExternalStorageDirectory()
            + File.separator + "test_media_recorder_surface_source.mp4");
    if (file.exists()) {
        file.delete();
    }

    mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
    mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    mediaRecorder.setOutputFile(file.getAbsolutePath());
    mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
    mediaRecorder.setVideoSize(1280, 720);
    mediaRecorder.setCaptureRate(24);

    try {
        mediaRecorder.prepare();

        int sleepTime = 1000 / 24;

        Surface surface = mediaRecorder.getSurface();

        mediaRecorder.start();

        // record something (we can …
Run Code Online (Sandbox Code Playgroud)

android surface android-canvas mediarecorder android-mediarecorder

8
推荐指数
1
解决办法
3648
查看次数

我们如何将动画/简单图像作为顶层添加到视频中,并将其作为Android中的单个视频导出?

我需要将图像合并为视频作为叠加层并导出它.我已经找到了使用javacv从图像创建视频的方法, 但是没有找到任何将图像添加为现有视频叠加层的jar或库,一些链接建议使用FFMPEG和JNI来实现这一点但遗憾的是我没有对JNI有任何了解.他们在IOS中使用avfoundation框架来实现同样的目标.

在此输入图像描述

上面的图像是我的要求的复制品,如果任何人可以指导我正确的方向并提供一些有用的东西开始将不胜感激.

到目前为止我所取得的成就是:1)编译的FFMPEG.2)生成的.so文件3)编译并能够运行Hello Jni项目.

我要搜索的是:1)将视频分割成帧.2)将我的叠加图像与视频帧合并3)用音频重新创建视频.

而且我知道JNI是实现这一目标的唯一方法,所以搜索了很多,但没有找到任何好的JNI开始.我不是要求整个代码,但如果有人可以指出我一些好的教程或博客将是很大的帮助.

谢谢!!

video java-native-interface android

7
推荐指数
1
解决办法
2255
查看次数

Android编码器复用器:原始h264到mp4容器

我创建了一个h264原始视频文件,我能够在Android 4.3及更高版本上与Android MediaMuxer进行复用.现在我需要支持Android版本4.1和4.2.我找到了Jcodec.这样做有一个例子:

https://github.com/jcodec/jcodec/blob/master/samples/main/java/org/jcodec/samples/mux/AVCMP4Mux.java

但是我在第70行得到了java.nio.ReadOnlyBufferException异常:

H264Utils.encodeMOVPacket(数据);

我想这段代码不适用于Android?我该如何解决.熟悉Jcodec的人可以帮忙解决这个问题吗?

android codec h.264 muxer jcodec

6
推荐指数
1
解决办法
7832
查看次数