我的目标是做几件事:
我有他们两个都在工作,但我必须实现2号的方式是荒谬的:
这有效,但它带来了许多缺点:在录制过程中帧率下降得无法忍受地低,并且拼接步骤每帧大约需要半秒钟,并且对于超过几秒钟的视频耗尽内存 - 这是在我降低相机的分辨率以确保图像尽可能小.即便如此,视频帧速率仍然与实际情况有关,视频看起来疯狂加速.
由于很多原因,这似乎很荒谬,所以我的问题是:有更好的方法吗?
如果有人想要运行它,这是一个小例子.这需要提供OpenCV的Android项目在这里,和JCodec Android项目可在这里.
的Manifest.xml:
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="22"
/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
<activity
android:name=".MainActivity"
android:screenOrientation="landscape"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Run Code Online (Sandbox Code Playgroud)
主要活动:
package com.example.videotest;
import java.io.File;
import java.util.List;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
import org.opencv.core.Mat;
import org.opencv.core.Scalar;
import org.opencv.imgproc.Imgproc;
import android.app.Activity;
import android.media.MediaScannerConnection;
import android.os.Bundle;
import android.os.Environment;
import …Run Code Online (Sandbox Code Playgroud) 我在使用MediaRecorder和Jcodec在Android上编写mp4文件时遇到了一些麻烦,这是我的代码
public class SequenceEncoder {
private final static String CLASSTAG = SequenceEncoder.class.getSimpleName();
private SeekableByteChannel ch;
private byte[] yuv = null;
private ArrayList<ByteBuffer> spsList;
private ArrayList<ByteBuffer> ppsList;
private CompressedTrack outTrack;
private int frameNo;
private MP4Muxer muxer;
ArrayList<ByteBuffer> spsListTmp = new ArrayList<ByteBuffer>();
ArrayList<ByteBuffer> ppsListTmp = new ArrayList<ByteBuffer>();
// Encoder
private MediaCodec mediaCodec = null;
public SequenceEncoder(File out) throws IOException {
this.ch = NIOUtils.writableFileChannel(out);
// Muxer that will store the encoded frames
muxer = new MP4Muxer(ch, Brand.MP4);
// Add video track to muxer …Run Code Online (Sandbox Code Playgroud) 我创建了一个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的人可以帮忙解决这个问题吗?
我正在使用JCODEC创建我的屏幕活动视频.我不想使用Android NDK,因为我想在JAVA中使用它.我正在运行for循环来使用SequenceEncoder对图像进行编码.问题是循环运行时间太长而log cat会释放GC_FOR_ALLOC消息.对于甚至5次迭代,循环需要很多秒.所以我无法拍摄我的活动的正确视频.我试图在代码中进行更改,但它没有帮助.请帮我解决一下这个.如果可用,建议其他选项.提前致谢.
File file = new File(Environment.getExternalStorageDirectory()+"/a.mp4");
SequenceEncoder encoder = new SequenceEncoder(file);
mview.setDrawingCacheEnabled(true);
// only 5 frames in total
for (int i = 1; i <= 5; i++) {
// getting bitmap from drawable path
mview.postInvalidate();
encoder.encodeNativeFrame(this.fromBitmap(mview.getDrawingCache()));
}
encoder.finish();
Run Code Online (Sandbox Code Playgroud) 好的,所以努力让我了解jcodec。基本上,我想将屏幕上的内容记录为BufferedImages,将缓冲的图像编码为H264帧,然后对其进行解码,然后将它们转换回缓冲的图像。
这是我拥有的代码,ScreenRecorder类扩展了线程并基本上在while true循环中捕获了屏幕。那部分起作用。然后,似乎也可以将ScreenRecorder中的BufferedImage编码为H264帧,但是当我尝试对其进行解码时,我得到了AIOBE
ScreenRecorder sc = new ScreenRecorder();
sc.start();
H264Encoder enc = H264Encoder.createH264Encoder();
ColorSpace cs = enc.getSupportedColorSpaces()[0];
System.out.println("cs= " + cs);
H264Decoder dec = new H264Decoder();
byte[][] buff = new byte[4096][4096];
while (true) {
BufferedImage bi = sc.getSnapshot();
System.out.println("Got bi " + bi);
if (bi != null) {
Picture pi = AWTUtil.fromBufferedImage(bi, cs);
int bufSize = enc.estimateBufferSize(pi);
ByteBuffer bb = ByteBuffer.allocate(bufSize);
VideoEncoder.EncodedFrame ef = enc.encodeFrame(pi, bb);
System.out.println("Data = " + Arrays.toString(ef.getData().array()));
Frame f = dec.decodeFrame(ef.getData(), buff);
System.out.println("Decoded frame = " …Run Code Online (Sandbox Code Playgroud) 我正在从 jcodec 的 android 上的 sd 卡上从图像和 mp4 声音创建视频。我正在获取输出视频,但没有语音和视频在 vlc 上播放,但在 android 播放器上连续循环,请帮助我
以下是我的代码段
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import org.jcodec.codecs.h264.H264Encoder;
import org.jcodec.codecs.h264.H264Utils;
import org.jcodec.common.NIOUtils;
import org.jcodec.common.SeekableByteChannel;
import org.jcodec.common.model.ColorSpace;
import org.jcodec.common.model.Picture;
import org.jcodec.containers.mp4.Brand;
import org.jcodec.containers.mp4.MP4Packet;
import org.jcodec.containers.mp4.TrackType;
import org.jcodec.containers.mp4.muxer.FramesMP4MuxerTrack;
import org.jcodec.containers.mp4.muxer.MP4Muxer;
import org.jcodec.scale.RgbToYuv420;
import android.graphics.Bitmap;
public class SequenceEncoder {
private SeekableByteChannel ch;
private Picture toEncode;
private RgbToYuv420 transform;
private H264Encoder encoder;
private ArrayList<ByteBuffer> spsList;
private ArrayList<ByteBuffer> ppsList;
private FramesMP4MuxerTrack outTrack;
private ByteBuffer _out;
private int frameNo;
private …Run Code Online (Sandbox Code Playgroud) 我搜索并阅读了大量资料,但似乎找不到答案。我认为这些“类型”是相等的,但是当我使用 jcodec 将 h264 解码为字节时,我假设数据输出是 YUV 4:2:O Planar (YUV420P);这是我的 VPX 编码器的预期输入类型。VPX 编码图像如下所示:

所以我必须假设虽然 YUVFormat.YUV_420 最有可能是 YUV420P,但 ColorSpace.YUV420 是 YUV420 的其他变体。有谁知道它是什么变体,以便我可以找到转换例程?