我有一堆本地图像保存为jpeg文件.我的图像是使用CameraPreview捕获的,而PreviewFormat是默认值:NV21.我想从固定数量的图像生成一个小视频.
我不打算使用FFMpeg因为它需要NDK并且会引入兼容性问题.
MediaCodec和MediaMuxer似乎很有效,但网上没有一个可行的解决方案.
有一些参考资料导致我目前的解决方案.
1. EncodeAndMuxTest:http://bigflake.com/mediacodec/EncodeAndMuxTest.java.txt
这个是由法登写的.它非常适合我的需要,除了他使用的是createInputSurface而不是queueInputBuffer.
我按照这个答案进行转换./sf/answers/1198188981/
这个问题看起来与我的很相似,但我不打扰使用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) 我正在尝试将MediaCodec一系列图像(保存为文件中的字节数组)保存到视频文件中.我已经测试了这些图像SurfaceView(在系列中播放),我可以看到它们很好.我看了很多使用的例子MediaCodec,这是我理解的(如果我错了请纠正我):
从MediaCodec对象获取InputBuffers - >用你的帧的图像数据填充它 - >将输入缓冲区排队 - >获取编码输出缓冲区 - >将其写入文件 - >增加显示时间并重复
但是,我已经对此进行了很多测试,最终我遇到了两种情况之一:
queueInputBuffer在第二次调用时导致Media服务器死机.codec.flush()在最后调用(在将输出缓冲区保存到文件之后,虽然我看到的所有示例都没有这样做)并且媒体服务器没有死,但是,我无法使用任何媒体播放器打开输出视频文件,所以出了点问题.这是我的代码:
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;
//loop …Run Code Online (Sandbox Code Playgroud) 我尝试在raw/assets文件夹中读取视频文件,我尝试了以下方法,但没有一个工作.我正在测试API 16.每种方法,我尝试使用和不使用mp4扩展.我真的很感激有人可以帮助我
所有方法都不会崩溃,MediaMetadataRetriever可以设置数据源,但不能获取宽度,高度和截图.VideoExtractor总是回来
06-04 16:44:10.519: E/FileSource(8695): Failed to open file FILE_PATH. (No such file or directory)
06-04 16:44:10.519: E/DecodeActivity(8695): Can't find video info!
Run Code Online (Sandbox Code Playgroud)
方法1:android.resource
String filePath = "android.resource://" + this.activity.getPackageName() + "/raw/green_backhand_slice";
videoExtractor.setDataSource(activity.getApplicationContext(), Uri.parse(filePath), null);
metaRetriever.setDataSource(act.getApplication(), Uri.parse(filePath));
Run Code Online (Sandbox Code Playgroud)
方法2:android_asset
this.filePath = "file:///android_asset/green_backhand_slice";
videoExtractor.setDataSource(activity.getApplicationContext(), Uri.parse(this.filePath), null);
metaRetriever.setDataSource(act.getApplication(), Uri.parse(filePath));
Run Code Online (Sandbox Code Playgroud)
方法3:资产文件描述符
AssetFileDescriptor assetFD = null;
try {
assetFD = getAssets().openFd("green_backhand_slice.mp4");
} catch (IOException e) {
e.printStackTrace();
}
metaRetriever.setDataSource(assetFD.getFileDescriptor());
Run Code Online (Sandbox Code Playgroud) 在我的Android应用程序中,我想通过更改其分辨率,比特率来压缩mp4视频.我不想使用FFmpeg(因为我不想使用NDK),所以我决定使用MediaCodec API.
以下是我的逻辑步骤:
我的问题是:我不知道如何设置解码器输出和编码器输入之间的连接.我可以将视频解码为Surface或从曲面编码新视频.但我不明白如何连接它们.
我读了这些链接:Android MediaCodec:使用新的MediaCodec库和Bigflake的示例减少mp4视频大小,Android上的视频压缩:https://android.googlesource.com/platform/cts/+/jb-mr2-release/tests /tests/media/src/android/media/cts/DecodeEditEncodeTest.java
谁能给我一个明确的解释我要做什么?
理想情况下,我想完成两个目标:
Camera预览将预览数据传递给MediaCodec编码器Surface.我可以创建Surface使用MediaCodec.createInputSurface()但是Camera.setPreviewDisplay()需要a SurfaceHolder,而不是a Surface. Camera预览数据传递给编码器之外,我还想在屏幕上显示预览(这样用户实际上可以看到他们编码的内容).如果编码器没有参与,那么我会使用a SurfaceView,但这似乎不适用于这种情况,因为SurfaceView创建了自己的编码器Surface,我认为我需要使用创建的编码器MediaCodec.我在网上搜索了很多解决方案,但没有找到解决方案.bigflake.com上的一些例子似乎是朝着正确方向迈出的一步,但他们采取了一种方法,增加了一堆我想避免的EGL/SurfaceTexture开销.我希望有一个简单的例子或解决方案,我能得到Camera并且MediaCodec不涉及EGL或纹理更直接交谈.
我正在尝试使用Android AudioRecord和MediaCodec编码aac音频.我创建了一个非常类似的编码器类(使用Android MediaCodec从相机编码H.264).通过这个类,我创建了一个AudioRecord实例,并告诉它将其byte []数据读出到AudioEncoder(audioEncoder.offerEncoder(Data)).
while(isRecording)
{
audioRecord.read(Data, 0, Data.length);
audioEncoder.offerEncoder(Data);
}
Run Code Online (Sandbox Code Playgroud)
这是我的AudioRecord设置
int audioSource = MediaRecorder.AudioSource.MIC;
int sampleRateInHz = 44100;
int channelConfig = AudioFormat.CHANNEL_IN_MONO;
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);
Run Code Online (Sandbox Code Playgroud)
我成功收集了一些byte []数组数据并将其写入本地文件.不幸的是,该文件无法播放.我做了一些在线搜索,发现了一个相关的帖子(如何使用Android MediaCodec生成AAC ADTS基本流).因此,遇到类似问题的其他人说主要问题是"MediaCodec编码器生成原始AAC流.原始AAC流需要转换为可播放格式,例如ADTS流".所以我尝试添加ADTS标头.然而,在我添加了ADTS头之后(我在下面的代码中注释掉了),我的AudioEncoder甚至都不会写输出音频文件.有什么我想念的吗?我的设置是否正确?
欢迎任何建议,意见和意见,非常感谢.多谢你们!
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.os.Environment;
import android.util.Log;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
public class AudioEncoder {
private MediaCodec mediaCodec;
private BufferedOutputStream outputStream;
private String mediaType = "audio/mp4a-latm";
public AudioEncoder() …Run Code Online (Sandbox Code Playgroud) 我正在开发一个记录屏幕视频和音频的Android应用程序.
我录制了这两个文件:mp3音频文件和mp4视频文件(没有声音).
现在我想混合它们并创建一个新的mp4视频文件(带声音).从Android 4.3开始,Google建议使用MediaMuxer该类来混合流音频和视频.我多次尝试都没有成功.
MediaMuxer从Google 解决我的API 问题的任何解决方案?任何帮助将不胜感激.
我正在修改一个Android Framework示例,将MediaCodec生成的基本AAC流打包成一个独立的.mp4文件.我正在使用MediaMuxer包含由MediaCodec实例生成的一个AAC轨道的单个实例.
但是,我总是在调用时始终收到错误消息mMediaMuxer.writeSampleData(trackIndex, encodedData, bufferInfo):
E/MPEG4Writer?timestampUs 0 < lastTimestampUs XXXXX for Audio track
当我将原始输入数据排队时,mCodec.queueInputBuffer(...)我提供0作为每个框架示例的时间戳值(我也尝试使用具有相同结果的单调增加的时间戳值.我已成功将原始相机帧编码为h264/mp4文件同样的方法).
最相关的片段:
private static void testEncoder(String componentName, MediaFormat format, Context c) {
int trackIndex = 0;
boolean mMuxerStarted = false;
File f = FileUtils.createTempFileInRootAppStorage(c, "aac_test_" + new Date().getTime() + ".mp4");
MediaCodec codec = MediaCodec.createByCodecName(componentName);
try {
codec.configure(
format,
null /* surface */,
null /* crypto */,
MediaCodec.CONFIGURE_FLAG_ENCODE);
} catch (IllegalStateException e) {
Log.e(TAG, "codec '" + …Run Code Online (Sandbox Code Playgroud) 因此,在我的应用程序中,我能够使用GPUImage库向来自Camera的视频显示效果(如模糊滤镜,高斯).
基本上,我(库)将来自摄像机的输入,获得真实的原始字节的数据,将其转换为从YUV格式RGBA格式,然后应用上的影响到该图像和显示器Surface的GLSurfaceView使用OpenGL.最后,对于用户来说,它看起来像是应用了效果的视频.
现在我想Surface使用MediaCodec API 将视频帧记录下来.
但是这个讨论说我们无法将预定义传递Surface给MediaCodec.
我在bigflake看到了一些他正在Surface使用的样品,MediaCodec.createInputSurface()但对我来说,Surface来自于GLSurfaceView.
那么,我如何录制Surface视频的帧?
我将并行录制音频,使用FFMPEG合并该视频和音频,并作为应用效果的视频呈现给用户.
我正在尝试解码文件中的视频,并使用API Level 21及更高版本(Android OS 5.0 Lollipop)支持MediaCodec的新异步模式将其编码为不同的格式.
在Big Flake,Google的Grafika等网站上以同步模式执行此操作有很多示例,并且StackOverflow上有许多答案,但它们都不支持异步模式.
我不需要在此过程中显示视频.
我相信一般的程序是用一个读取文件MediaExtractor作为MediaCodec(解码器)的输入,允许解码器的输出渲染成一个Surface也是共享输入到MediaCodec(编码器),然后最后写入编码器输出文件通过MediaMuxer.它Surface是在编码器设置期间创建的,并与解码器共享.
我可以将视频解码为a TextureView,但Surface与编码器共享而不是屏幕也没有成功.
我MediaCodec.Callback()为我的两个编解码器设置了s.我认为问题在于我不知道在Encoder的回调onInputBufferAvailable()函数中该怎么做.我不知道(或知道如何)将数据从Surface编码器复制到编码器中 - 这应该自动发生(就像在解码器输出上一样codec.releaseOutputBuffer(outputBufferId, true);).然而,我认为onInputBufferAvailable需要打电话codec.queueInputBuffer才能运作.我只是不知道如何设置参数而不从像MediaExtractorDecode端使用的那样获取数据.
如果您有一个打开视频文件MediaCodec的示例,对其进行解码,使用异步回调将其编码为不同的分辨率或格式,然后将其保存为文件,请分享您的示例代码.
=== 编辑 ===
下面是我在异步模式下尝试做的同步模式的一个工作示例:ExtractDecodeEditEncodeMuxTest.java:https://android.googlesource.com/platform/cts/+/jb-mr2-release/tests/tests/media /src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java这个例子在我的应用程序中工作
android video-encoding mediacodec android-5.0-lollipop android-5.1.1-lollipop
android ×10
mediacodec ×10
video ×2
aac ×1
audio ×1
audiorecord ×1
camera ×1
compression ×1
encoder ×1
ffmpeg ×1
mp4 ×1
opengl-es ×1
surfaceview ×1