我正在尝试将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) 我正在寻找一种"压缩"mp4视频的方法.为此,我想降低视频的分辨率和/或降低FPS.
经过长时间的研究,我认为这样做的方法是使用MediaCodec和相关的API,如下所示:
- > MediaExtractor从mp4文件中提取编码的媒体数据. - > MediaCodec(解码器):解码每个帧以供以后处理. - > MediaCodec(编码器):此时,我猜我们应该在哪里建立MediaFormat参数,例如视频分辨率,这应该有助于我们减少mp4文件的最终大小. - > MediaMuxer用于生成mp4文件(MinSDK 18,这可能是一个问题,但现在......好吧).
我不想使用SurfaceView/TextureView.关于音频,我不想处理它以降低质量.
我一直在看这里的所有例子:http: //bigflake.com/mediacodec/
我也看过CTS源代码模块.
我一直在研究以下几个项目:https: //github.com/vecio/MediaCodecDemo/blob/master/src/io/vec/demo/mediacodec/DecodeActivity.java
当然,我已经在stackoverflow上阅读了几十篇帖子.
问题是我还没有找到任何适合这个porpuse的代码示例.我尝试将各种代码片段放在一起放在一个项目中,但实际上并没有用.
谢谢.
我Camera使用MediaCodecmime-type"video/avc" 编码预览数据,并将编码数据(仅限视频,无音频)传递给MediaMuxer.复用器似乎运行正常并创建一个合理大小的输出文件(即,我记录的时间越长,越大).但是,当我尝试停止复用器时,我得到"无法停止复用器"错误:
10-21 10:39:40.755: E/AndroidRuntime(2166): Caused by: java.lang.IllegalStateException: Failed to stop the muxer
Run Code Online (Sandbox Code Playgroud)
在失败的停止之前有一些可疑的MPEG4Writer日志消息:
10-21 10:39:40.740: D/MPEG4Writer(2166): Stopping Video track
10-21 10:39:40.740: E/MPEG4Writer(2166): Missing codec specific data
10-21 10:39:40.740: W/MPEG4Writer(2166): 0-duration samples found: 122
10-21 10:39:40.740: I/MPEG4Writer(2166): Received total/0-length (123/1) buffers and encoded 123 frames. - video
10-21 10:39:40.740: D/MPEG4Writer(2166): Stopping Video track source
10-21 10:39:40.740: D/MPEG4Writer(2166): Video track stopped
10-21 10:39:40.740: D/MPEG4Writer(2166): Stopping writer thread
10-21 10:39:40.740: D/MPEG4Writer(2166): 0 chunks are written in …Run Code Online (Sandbox Code Playgroud) 我使用Android的MediaCodec API编写了H264流编码器.我在大约十个不同处理器的不同设备上进行了测试,除了Snapdragon 800驱动的设备(谷歌Nexus 5和索尼Xperia Z1)之外,它在所有设备上都有效.在这些设备上,我得到了SPS和PPS以及第一个Keyframe,但之后mEncoder.dequeueOutputBuffer(mBufferInfo,0)只返回MediaCodec.INFO_TRY_AGAIN_LATER.我已经尝试过不同的超时,比特率,分辨率和其他配置选项,但无济于事.结果总是一样的.
我使用以下代码初始化编码器:
mBufferInfo = new MediaCodec.BufferInfo();
encoder = MediaCodec.createEncoderByType("video/avc");
MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", 640, 480);
mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 768000);
mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, mEncoderColorFormat);
mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 10);
encoder.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
Run Code Online (Sandbox Code Playgroud)
所选颜色格式为:
MediaCodecInfo.CodecCapabilities capabilities = mCodecInfo.getCapabilitiesForType(MIME_TYPE);
for (int i = 0; i < capabilities.colorFormats.length && selectedColorFormat == 0; i++)
{
int format = capabilities.colorFormats[i];
switch (format) {
case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar:
case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedPlanar:
case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar:
case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedSemiPlanar:
case MediaCodecInfo.CodecCapabilities.COLOR_TI_FormatYUV420PackedSemiPlanar:
case MediaCodecInfo.CodecCapabilities.COLOR_QCOM_FormatYUV420SemiPlanar:
selectedColorFormat = format;
break;
default:
LogHandler.e(LOG_TAG, "Unsupported color format " + …Run Code Online (Sandbox Code Playgroud) 我正在开展视频会议项目.我的视频显示使用表面视图.现在,在视频通话期间,传入帧的宽高比可能会发生变化.所以我尝试了以下代码
public void surfaceResize() {
// WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Point size = new Point();
int screenWidth = 0;
//Get the SurfaceView layout parameters
float aspectRatio = (float) recv_frame_width / recv_frame_height;
if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)
{
//Get the width of the screen
getWindowManager().getDefaultDisplay().getSize(size);
screenWidth = size.x;
//Set the width of the SurfaceView to the width of the screen
surflp.width = screenWidth;
//Set the height of the SurfaceView to match the aspect ratio of the video
//be sure to cast these …Run Code Online (Sandbox Code Playgroud) 我有一个管理自己的GLSurfaceView的应用程序,现在我想使用Android 4.3的新MediaCodec功能,将Surface作为输入.
在我看过的所有示例中,使用MediaCodec.createInputSurface()创建Surface,然后为此Surface创建GL上下文.对于已经稳定的代码库进行改造,这感觉很单一,并且令人难以置信地具有破坏性.
是否可以使用MediaCodec.configure(format,a_predefined_Surface,null,MediaCodec.CONFIGURE_FLAG_ENCODE)?这允许我以即插即用的方式使用MediaCodec.MediaCodec.configure()采用Surface参数的事实表明这应该是可能的.但是,API指出"指定一个表面,在该表面上呈现此解码器的输出" http://developer.android.com/reference/android/media/MediaCodec.html#configure(android.media.MediaFormat,android). view.Surface,android.media.MediaCrypto,int)这是否意味着这仅用于解码而不是编码?如果是这样,有没有办法让MediaCodec使用预定义的Surface进行编码?
我传入的Surface已经创建,EGL_RECORDABLE_ANDROID设置为true,并且验证返回的GL上下文包含所需的EGL_RECORDABLE_ANDROID属性.尽管如此,MediaCodec.configure()失败并出现无用的异常'native_window_api_connect返回错误:无效的参数(-22)':
I/ACodec(32383): Now uninitialized
I/OMXClient(32383): Using client-side OMX mux.
I/ACodec(32383): [OMX.qcom.video.encoder.avc] Now Loaded
E/MediaCodec(32383): native_window_api_connect returned an error: Invalid argument (-22)
W/System.err(32383): java.lang.IllegalStateException
W/System.err(32383): at android.media.MediaCodec.native_configure(Native Method)
W/System.err(32383): at android.media.MediaCodec.configure(MediaCodec.java:259)
[...]
W/System.err(32383): at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1520)
W/System.err(32383): at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1248)
Run Code Online (Sandbox Code Playgroud)
这是来自Android 4.3的三星Galaxy S4.
我正在编写一个使用MediaCodec记录屏幕捕获和音频的应用程序.我使用MediaMuxer来混合视频和音频来创建mp4文件.我成功地分别编写了视频和音频,但是当我尝试将它们混合在一起时,结果出乎意料.音频播放时没有视频,或视频播放后立即播放.我的猜测是我在时间戳上做错了,但我无法弄清楚到底是什么.我已经看过这些例子:https://github.com/OnlyInAmerica/HWEncoderExperiments/tree/audiotest/HWEncoderExperiments/src/main/java/net/openwatch/hwencoderexperiments和bigflake.com上的那些并且无法找到回答.
这是我的媒体格式配置:
mVideoFormat = createMediaFormat();
private static MediaFormat createVideoFormat() {
MediaFormat format = MediaFormat.createVideoFormat(
Preferences.MIME_TYPE, mScreenWidth, mScreenHeight);
format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
format.setInteger(MediaFormat.KEY_BIT_RATE, Preferences.BIT_RATE);
format.setInteger(MediaFormat.KEY_FRAME_RATE, Preferences.FRAME_RATE);
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL,
Preferences.IFRAME_INTERVAL);
return format;
}
mAudioFormat = createAudioFormat();
private static MediaFormat createAudioFormat() {
MediaFormat format = new MediaFormat();
format.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm");
format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 44100);
format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
format.setInteger(MediaFormat.KEY_BIT_RATE, 64000);
return format;
}
Run Code Online (Sandbox Code Playgroud)
音频和视频编码器,复用器:
mVideoEncoder = MediaCodec.createEncoderByType(Preferences.MIME_TYPE);
mVideoEncoder.configure(mVideoFormat, null, null,
MediaCodec.CONFIGURE_FLAG_ENCODE);
mInputSurface = new InputSurface(mVideoEncoder.createInputSurface(),
mSavedEglContext);
mVideoEncoder.start();
if (recordAudio){
audioBufferSize = AudioRecord.getMinBufferSize(44100, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT);
mAudioRecorder …Run Code Online (Sandbox Code Playgroud) 我正在为Android开发视频录制和共享应用程序.该应用程序的规格如下: -
从研究中我做了SO和其他人的来源,我发现了以下内容(如果我错了请纠正我): -
这三个选项及其各自的特点是: -
1. Ffmpeg
2. MediaRecorder
3. MediaCodec
花了好几天后,我仍然无法弄清楚哪种方法适合我的特定用例.请详细说明我应该为我的申请做些什么.如果有一种完全不同的方法,那么我也对此持开放态度.
我最大的标准是视频编码过程尽可能高效,并且要存储在云中的视频应该具有尽可能低的空间使用率,而不会影响视频质量.
另外,如果您可以建议在Firebase存储中保存和分发视频的相应格式,我将不胜感激,并指出我建议方法的教程或示例.
先感谢您!很抱歉长时间阅读.
我正在使用mp4parser,视频需要是同一种类.我正在考虑使用Android的媒体编解码器来解码和编码预卷视频,以适应相机的相同编码输出(正面和背面)任何关于如何做到这一点的建议(如何获得特定的设备编码参数)?
在Android 4.4.2中,我MediaCodec用来解码mp3文件.我正在使用queueInputBuffer()输入mp3编码帧排队并dequeueOutputBuffer()获得解码帧.但是解码器从第8帧开始提供解码输出(基于bufferInfo.presentationTimeUs)并跳过最初的7帧.此方案仅针对少数流而不针对所有流发生.此外,这种行为在许多运行中都是一致的.
我想要所有帧的解码输出,我不希望任何帧被跳过.任何人都可以帮助我理解为什么帧被跳过?我保证流不会被破坏.因为我要INFO_TRY_AGAIN到第7帧,当`dequeueOutputBuffer'返回有效的缓冲区索引时,它的呈现时间总是第8帧.
以下是排队代码:
Log.e(TAG, "audptOffset = "+audptOffset+"input PT = "+audpt);
audcodec.queueInputBuffer(audInbufIndex, 0, audchunkSize, audpt, 0);
Run Code Online (Sandbox Code Playgroud)
以下是我如何调用dequeue并写入AudioTrack:
if(!audoutputDone ){
if(!waitForAudioRelease){
auoutBufIndex = audcodec.dequeueOutputBuffer(auinfo, 100);
Log.e(TAG, "Output PT = " + auinfo.presentationTimeUs+"auoutBufIndex = "+auoutBufIndex);
}
if (auoutBufIndex >= 0) {
waitForAudioRelease = true;
} else if (auoutBufIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
auddecOutBufArray = audcodec.getOutputBuffers();
} else if (auoutBufIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
MediaFormat newFormat = audcodec.getOutputFormat();
int sampleRate1 = newFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE);
int …Run Code Online (Sandbox Code Playgroud) android ×10
mediacodec ×10
video ×5
h.264 ×2
mp4 ×2
audio ×1
audiotrack ×1
encoder ×1
ffmpeg ×1
java ×1
mp4parser ×1
muxer ×1
resolution ×1
surfaceview ×1