使用 FFmpeg 进行 Android 相机捕捉
Posted
技术标签:
【中文标题】使用 FFmpeg 进行 Android 相机捕捉【英文标题】:Android Camera Capture using FFmpeg 【发布时间】:2013-02-23 05:08:10 【问题描述】:我正在尝试获取android相机生成的预览帧并将data[]
传递给ffmpeg输入管道以生成flv视频。
我使用的命令是:
ffmpeg -f image2pipe -i pipe: -f flv -vcodec libx264 out.flv
我也尝试将输入格式强制为yuv4mpegpipe
和rawvideo
,但没有成功...
android-camera 生成的预览帧默认格式为NV21
。
调用 ffmpeg 的方式是通过Process API
并将预览帧data[]
写入进程'stdin
...
onPreviewFrame()
定义如下:
public void onPreviewFrame(byte[] data, Camera camera)
try
processIn.write(data);
catch(Exception e)
Log.e(TAG, FUNCTION + " : " + e.getMessage());
camera.addCallbackBuffer(new byte[bufferSize]);
processIn
连接到ffmpeg
进程stdin
和buffersize
是根据为addCallbackBuffer()
提供的文档计算的。
有什么做错了吗...?
谢谢...
【问题讨论】:
你能解释一下你是如何使用进程api调用ffmpeg进程的吗? 永远不要尝试camera.addCallbackBuffer(new byte[bufferSize])
:您应该返回(即addCallbackBuffer()
)您从相机回调收到的数据数组。
【参考方案1】:
有点让它完美地工作......
似乎发生的错误与图像流的vcodec
有关。
似乎 ffmpeg 没有规定解码NV21
格式图像或图像流。
为此必须将NV21
格式预览帧转换为JPEG
,并且由于图像必须实时流式传输到ffmpeg
进程,因此转换必须为On the Fly
。将On the Fly
转换为JPEG
的最接近可靠的解决方案如下:
public void onPreviewFrame(byte[] data, Camera camera)
if(isFirstFrame)
Camera.Parameters cameraParam = camera.getParameters();
Camera.Size previewSize = cameraParam.getPreviewSize();
previewFormat = cameraParam.getPreviewFormat();
frameWidth = previewSize.width;
frameHeight = previewSize.height;
frameRect = new Rect(0, 0, frameWidth, frameHeight);
isFirstFrame = false;
previewImage = new YuvImage(data, previewFormat, frameWidth, frameHeight, null);
if(previewImage.compressToJpeg(frameRect, 50, processIn))
Log.d(TAG, "Data : " + data.length);
previewImage = null;
camera.addCallbackBuffer(new byte[bufferSize]);
而使用的ffmpeg
命令是:
ffmpeg -f image2pipe -vcodec mjpeg -i - -f flv -vcodec libx264 out.flv
【讨论】:
嗨,你能分享你的代码吗?我想知道你如何使用processIn
。谢谢
当我使用 ffmpeg 的静态构建尝试此代码时,我在 Android 上得到了不受支持的格式“mjpeg”。解决方案是什么?
您是在 Android 上静态构建的 ffmpeg 上运行命令还是在桌面上尝试过此命令?以上是关于使用 FFmpeg 进行 Android 相机捕捉的主要内容,如果未能解决你的问题,请参考以下文章