我正在开发一个视频编码应用程序,我希望阻止在托管活动进入后台时停止,或者屏幕循环开/关.
我的编码器的架构源自出色的CameraToMpegTest示例,并在GLSurfaceView中添加了显示相机帧(请参阅下面的Github链接).我目前正在使用双态解决方案进行背景录制:
当托管活动是在前台,在每个呼叫中的一个视频帧编码到GLSurfaceView.Renderer
的onDrawFrame
.这允许我以突发方式访问GLSurfaceView的EGL状态,以便不阻止排队到渲染器线程的其他事件.
当托管活动进入后台时,停止onDrawFrame
编码并在循环内的另一个后台线程上编码帧.此模式与CameraToMpegTest示例相同.
但是,如果屏幕关闭,GLSurfaceView的EGLContext将丢失并发生新的调用onSurfaceCreated
.在这种情况下,我们必须重新创建连接到MediaCodec输入Surface的EGL窗口表面.不幸的是,第二次调用eglCreateWindowSurface
产生:
E/libEGL(18839): EGLNativeWindowType 0x7a931098 already connected to another API
Run Code Online (Sandbox Code Playgroud)
在致电之前,我发布了连接到Android Surface的所有EGL资源.
有没有办法交换连接到MediaCodec输入Surface的EGLSurface?
更新我根据MediaCodec和MediaMuxer类将此处学到的经验应用到Android的视频sdk中.希望能帮助到你!
我想以Periscope的方式进行直播.我在网上做了一个快速搜索,发现像ffmpeg一样的库使用本机库,但根据MediaCodec编码应该直接支持Android SDK吗?
https://developer.android.com/reference/android/media/MediaCodec.html
所以我想知道为什么编码需要外部本机库?
我也尝试了一些库,但它们似乎太慢了,特别是对于高比特率(我在Nexus 5X上获得16个fps,1280x720,2500Kbps,我希望达到1080),流行的广播应用程序如何做到这一点?
由于涉及如此多的处理,似乎不可能使用普通电话(不是顶级线路)实现高质量的流媒体.
编辑:
似乎问题是这个设备不需要16个维度的多个...但是32的倍数.事实是,我仍然不知道如何确定什么量化为有问题的设备.这似乎使用qcom(我已经看到在Android 4.X上有问题,但这是Android 5.1.1).
我正在Android应用中编码视频.我正在使用Android MediaCodec这样做,将每帧的RGB转换为YUV并传入像素.
我使用的代码已经存在了一段时间,并且适用于我遇到过的任何设备.
一位用户带着一个错误报告来找我说他们的MP4很奇怪.该设备是三星T337A(Galaxy Tab 4).
这是MP4出口的样子:
注 - 出于任何奇怪的原因,它不会在所有分辨率下发生.它确认发生在768x432和1280x720,但不会发生在640x352(例如我的应用程序确保所有分辨率都可以被16整除).
在Nexus 5X(使用相同的半平面YUV格式)上,输出适用于所有分辨率.
所以这是该设备的东西,也许是我不知道的其他设备?
我查看了所有输出,它看起来正常并且与我上面提到的Nexus 5X相同(100%的时间都可以工作).
正在使用的MediaCodecInfo是OMX.qcom.video.encoder.avc,使用的颜色格式是2135033992(这是COLOR_FormatYUV420Flexible).所以基本上没什么奇怪的.
代码有点广泛,我会在必要时发布,但只是寻找为什么会发生这种情况的一般想法.我知道它是否更常见,但相同的代码适用于大量其他设备,所以一些时髦的东西正在发生......
android video-encoding android-hardware galaxy-tab mediacodec
我正在编写一个Android应用程序,我需要缓存视频帧,以便我可以轻松地来回转移,几乎没有延迟.
现在我让android解码视频帧,方法是在MediaCodec
对象的Configure调用中提供一个Surface 并调用releaseOutputBuffer
render flag设置为true
.
的唯一方法,我发现访问解码表面数据(除了解码所返回的字节缓冲区,其格式似乎是依赖于设备的)是调用updateTeximage
在SurfaceTexture
链接到表面,附接这对GL_TEXTURE_EXTERNAL_OES
目标和它渲染到GL_TEXTURE2D
目标纹理我创建我自己为了缓存它.
我想优化这个缓存过程,并能够解码不同线程上的帧.使用我当前的方法,这意味着我将不得不为视频解码器创建另一个EGL上下文,共享上下文等...
我的问题是:是否可以在不调用的情况下访问与Surface关联的EGL图像或本机缓冲区数据 updateTexImage
?
这样我就可以缓存egl图像(根据不需要EGL上下文EGL_ANDROID_image_native_buffer
).这也将以YUV格式缓存,这比我现在缓存的原始RGB纹理更具存储效率.
我正在使用Android MediaCodec API来解码h264帧.我可以在视图上解码和渲染帧.我的问题是解码器错过了很多帧,特别是前几帧.DecodeMediaCodec.dequeueOutputBuffer()返回-1.a约150 h264帧,刚解码43帧.我找不到问题所在.这是我的代码.
/**
* init decoder
*/
private void initDecodeMediaCodec()
{
mDecodeMediaCodec = MediaCodec.createDecoderByType(MIME_TYPE);
MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE,
VIDEO_WIDTH_640,
VIDEO_HEIGHT_480);
mDecodeMediaCodec.configure(format,
new Surface(mRemoteVideoView.getSurfaceTexture()),
null,
0);
mDecodeMediaCodec.start();
mDecodeInputBuffers = mDecodeMediaCodec.getInputBuffers();
System.out.println("decode-----"
+ mDecodeMediaCodec.getCodecInfo().getName());
}
Run Code Online (Sandbox Code Playgroud)
解码器初始化后,我将启动解码器线程.
/**
*
* @param frameData
*/
private void decode()
{
new Thread(new Runnable()
{
@Override
public void run()
{
while (true)
{
ByteBuffer decodeDataBuffer = null;
try
{
//take h264 frame from cache queue
decodeDataBuffer = decodeDataQuene.take();
}
catch (InterruptedException e)
{ …
Run Code Online (Sandbox Code Playgroud) 我正在开发像whatsApp这样的聊天应用程序,我想在上传到服务器之前对媒体文件进行转码,我已经经历了这么多链接但是无法决定我应该使用哪种方法,是否有任何直接的转码方式在Android中?
FFMPEG我发现它是高度cpu密集的过程,它会消耗更多的电池电量
Media Codec 我想使用mediacodec进行转码,但无法获得正确的步骤来理解这个过程.
使用媒体编解码器转码的库(它有很多错误)
我正在尝试使用MediaCodec在onImageAvailable回调中记录ImageReader中的原始帧,但无法编写正常工作的代码.大多数示例都使用Camera 1 API或MediaRecorder.我的目标是捕获单个帧处理它并从中创建一个mp4
原始的YUV帧
@Override
public void onImageAvailable(ImageReader reader) {
Image i = reader.acquireLatestImage();
processImage(i);
i.close();
Log.d("hehe", "onImageAvailable");
}
};
Run Code Online (Sandbox Code Playgroud)
MediaCodec
MediaCodec codec = MediaCodec.createByCodecName(name);
MediaFormat mOutputFormat; // member variable
codec.setCallback(new MediaCodec.Callback() {
@Override
void onInputBufferAvailable(MediaCodec mc, int inputBufferId) {
ByteBuffer inputBuffer = codec.getInputBuffer(inputBufferId);
// fill inputBuffer with valid data
…
codec.queueInputBuffer(inputBufferId, …);
}
@Override
void onOutputBufferAvailable(MediaCodec mc, int outputBufferId, …) {
ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);
MediaFormat bufferFormat = codec.getOutputFormat(outputBufferId); // option A
// bufferFormat is equivalent to mOutputFormat
// …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用OnAudioFilterRead函数将Unity游戏音频录制到mp4文件.
function OnAudioFilterRead(var data:float[], var channels:int)
Run Code Online (Sandbox Code Playgroud)
我的解决方案概述.
步骤1.将从Unity获取的数据样本转换为bytes []
private void Convert2Bytes(float[] samples) {
Int16[] intData = new Int16[samples.Length];
//converting in 2 float[] steps to Int16[], //then Int16[] to Byte[]
Byte[] bytesData = new Byte[samples.Length * 2];
//bytesData array is twice the size of
//dataSource array because a float converted in Int16 is 2 bytes.
float rescaleFactor = 32767; //to convert float to Int16
for (int i = 0; i<samples.Length; i++) {
intData[i] = (short) ((samples[i] * gain) * rescaleFactor); …
Run Code Online (Sandbox Code Playgroud) 我正在使用Google的开源示例:Grafika.我正在使用它的ContinuousCaptureActivity.java此活动中演示了CircularBuffer的实现,但生成的视频文件中没有包含音频.
我想在此活动中添加音频录制功能,并将录制的音频以相同的CircularBuffered时尚添加到视频中.
为实现这一目标,我探索了MediaCodec库,该库已在4.3+版本中推出.我还使用MediaMuxer捕获视频和音频流,并将它们混合到一个视频中.
但是,我不确定如何在ContinuousCaptureActivity.java
课堂上实现录音功能.任何帮助都非常感谢.
我有一个屏幕录制应用程序,它使用MediaCodec编码器对视频帧进行编码.这是我检索视频编码器的一种方法:
videoCodec = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_VIDEO_AVC);
Run Code Online (Sandbox Code Playgroud)
然后我尝试确定此编码器支持的最佳比特率模式,我的优先顺序是"恒定质量"模式,可变比特率模式,恒定比特率模式.这是我尝试这样做的方式:
MediaCodecInfo.CodecCapabilities capabilities = videoCodec.getCodecInfo().getCapabilitiesForType(MediaFormat.MIMETYPE_VIDEO_AVC);
MediaCodecInfo.EncoderCapabilities encoderCapabilities = capabilities.getEncoderCapabilities();
if (encoderCapabilities.isBitrateModeSupported(MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CQ)) {
Timber.i("Setting bitrate mode to constant quality");
videoFormat.setInteger(MediaFormat.KEY_BITRATE_MODE, MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CQ);
} else if (encoderCapabilities.isBitrateModeSupported(MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_VBR)) {
Timber.w("Setting bitrate mode to variable bitrate");
videoFormat.setInteger(MediaFormat.KEY_BITRATE_MODE, MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_VBR);
} else if (encoderCapabilities.isBitrateModeSupported(MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CBR)) {
Timber.w("Setting bitrate mode to constant bitrate");
videoFormat.setInteger(MediaFormat.KEY_BITRATE_MODE, MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CBR);
}
Run Code Online (Sandbox Code Playgroud)
在我的三星Galaxy S7上运行它最终选择VBR模式,即据说不支持恒定质量模式.但是,如果我只是将BITRATE_MODE设置为恒定质量,它不仅可以工作,而且实际上可以产生比VBR模式更高质量的视频.
因此,如果此编码器显然支持恒定质量模式,为什么我会从isBitrateModeSupported()获得误报?我在这里错过了什么吗?
mediacodec ×10
android ×9
video ×3
audio ×1
caching ×1
decode ×1
egl ×1
galaxy-tab ×1
grafika ×1
h.264 ×1
mp4 ×1
rtmp ×1
transcoding ×1