① 有没有ffmpeg 开发的android demo求一例
转载 首先:
是要编译libjnivideo.so和libjniaudio.so 这两个so因为不同的版本或者修改过的framework是不一样的,所以需要在android源码中 编译出自己的so。我的android 2.1源码是从官网下载回来的,没有经过修改。
下载链接中的native目录下的源码到framework/base目录下具体看他的目录结构。https://github:com/havlenapetr/android_frameworks_base编译主要有3个错误
1.
library 'libjnigraphics.so' not in prelink map
当前目录下的Android.mk 加上
LOCAL_PRELINK_MODULE := false2.
frameworks/base/native/video/jni/surface.cpp:17:36: error: surfaceflinger/Surface.h: No such file or directory
修改头文件
#include <android/surface.h>
#include <ui/Surface.h>
#include <utils/Log.h>
#include <SkBitmap.h>
#include <SkCanvas.h>3.
make: *** 没有规则可以创建“out/target/proct/generic/obj/SHARED_LIBRARIES/libjnivideo_intermediates/LINKED/libjnivideo.so”需要的目标“out/target/proct/generic/obj/lib/libsurfaceflinger_client.so”。 停止。
当前目录下的Android.mk
LOCAL_SHARED_LIBRARIES := /
libskia /
libui /
libutils /
liblog
到这里如果幸运的话可以编译出so。其次是编译libffmpeg_jni.so
需要修改的地方:
1.
jni/jni/Android.mkLOCAL_C_INCLUDES += /
$(LOCAL_PATH)/../libffmpeg /
$(LOCAL_PATH)/../libmediaplayer /
$(LOCAL_PATH)/../include /
$(LOCAL_PATH)/../include/androidifeq ($(IN_NDK),true)
LOCAL_LDLIBS := -llog
else
LOCAL_PRELINK_MODULE := false
LOCAL_LDLIBS := -llog
LOCAL_SHARED_LIBRARIES := liblog
endif
2.
Vector.h#include <new>
#include <stdint.h>
#include <sys/types.h>#include <cutils/log.h>
#include <utils/VectorImpl.h>
#include <utils/TypeHelpers.h>
#include <android/Errors.h>
3.
<utils/TypeHelpers.h>4
VectorImpl.h#include <assert.h>
#include <stdint.h>
#include <sys/types.h>
#include <android/Errors.h>5.
VectorImpl.cpp
#include <string.h>
#include <stdlib.h>
#include <stdio.h>#include <cutils/log.h>
#include <android/Errors.h>
#include <utils/SharedBuffer.h>
#include <utils/VectorImpl.h>
同时也要把刚才两个编译出来的so放到obj/local/armeabi目录下,之后就可以了编译出libffmpeg_jni.so.
最后也要把刚才两个so放到libs/armeabi目录下。要不然运行的时候找不到。
播放的时候太卡了,声音也没有同步。
② ffmpeg录屏/录音/录摄像头----命令行实现
原文地址: https://blog.csdn.net/lailaiquququ11/article/details/80968272
ffmpeg在linux下支持的采集设备的种类比较多。
在操作设备之前,我们可以查看当前系统可以支持的操作设备:
ffmpeg -hide_banner -devices
///////////////////////////////////
采集设备fbdev的参数:我们能看出fb(FrameBuffer)的操作参数,指定帧率就行(默认值为25).
ffmpeg -h demuxer=fbdev
ffmpeg -framerate 30 -f fbdev -i /dev/fb0 out.mp4
/////////////////////////////////////
v4l2 即就是video4linux2的缩写,也是常见视频设备。获取摄像头的视频图片~
通过ffmpeg -h demuxer=v4l2 查看相关的操作参数
例子:
获取本电脑的v4l2摄像头所支持的色彩格式和分辨率:
ffmpeg -hide_banner -f v4l2 -list_formats all -i /dev/video0
接下来可以使用下面的命令行,用摄像头采集视频文件:
ffmpeg -hide_banner -s 1920*1080 -i /dev/video0 out2.avi
对应的输出信息为:
因为我的摄像头不支持1920 1080,默认还原成了前面他所支持的参数 1280 720,输出的视频编码采用了avi的默认编码和码率参数。
////////////////////////////////////////////////
ffmpeg在linux下桌面图形的时候,通常是用x11grab设备采集桌面图像。
ffmpeg -h demuxer=x11grab 可以获得操作的参数:
参数包括了,采集分辨率-video_size , 支持鼠标光标 -draw_mouse, 跟中鼠标轨迹 -follow_mouse, 指定采集区域 -region_border等参数。
例子:
1)录制桌面
ffmpeg -f x11grab -framerate 25 -video_size 1366*768 -i :0.0 out.mp4
图像的分辨率,以实际电脑的支持来,我的因为是1366*768,所刚好录制下整个屏幕
我设置的参数为: 帧率为25帧 ,分辨率为 1366*768,采集设备为 0.0,输出的文件为out.mp4
2)带鼠标的录制桌面
ffmpeg -f x11grab -framerate 25 -video_size 1366*768 -follow_mouse 1 -i :0.0 out.mp4
3)指定录制区域
ffmpeg -f x11grab -framerate 25 -video_size 352*288 -i :0.0+300,200 out4.mp4
-i :0.0+300,200 制定了x坐标为300 y坐标为200
这样就可以录制桌面了。
③ android ffmpeg视频添加字幕和配音
使用ffmpeg三方:https://github.com/abyuthup/mobile-ffmpeg
兼容处理android10的不能操作二进制文件流问题;
1、添加字幕
主要命令:-i videoPath.mp4 -q 5 -vf ass=subtitle.ass -y outPath.mp4
其中-q 5命令是为了生成的视频不会很模糊
2、添加字幕和配音
ffmpeg在特定的时间混合一个或多个音频,参考文章
如何在指定的时间点向视频插入配音文件即音频文件,参考文章
主要命令:ffmpeg -y -i video1.mp4 -i audio1.mp3 -i audio2.mp3 -filter_complex "[1]atrim=0:5,adelay=3000|3000[aud1];[2]atrim=0:6,adelay=10000|10000[aud2];[aud1][aud2]amix=2,apad,atrim=0:20[a]" -map 0:v -map "[a]" -c:v -ac 2 output.mp4
④ Android中使用FFmpeg得到视频中的PCM和YUV数据
使用FFmpeg获取PCM和YUV数据的流程基本上一样的,下面就以获取YUV数据的流程为例,说明这个过程:
⑤ Android使用FFmpeg播放视频(二):音频播放
Android使用FFmpeg播放视频(一):视频播放
Android NDK开发:利用OpenSL ES实现声音播放
这里我创建了两个JNI函数,一个是播放的,一个是释放的如下:
这里我在用于播放的JNI函数中依次初始化了FFmpeg和OpenSLES
其中初始化FFmpeg的函数中的逻辑其实和使用FFmpeg播放视频画面中的逻辑差不多,主要区别就是要找到音频的索引以及后面对于解析音频的一些配置;而初始化OpenSLES基本就和之前使用OpenSLES播放PCM数据是一样的,具体如下:
最后再加入释放资源的逻辑即可
这里的案例源码是和之前播放视频画面的分开了
https://gitee.com/itfitness/ffmpeg-audio-demo
⑥ Android FFmage 修改视频分辨率,帧率,区域裁剪
String ffmpeg ="-y -i " +filePath +" -strict -2 -vcodec libx264 -preset ultrafast -crf 24 -acodec aac -ar 44100 -ac 2 -b:a 96k -s " + (int)(videoWidth /bili) +"x" + (int)(videoHeight /bili) +" -aspect 5:3 "+savePath;
filePath = 原视频地址
(int)(videoWidth /bili) +"x" + (int)(videoHeight /bili) = 分辨率(1080 * 1920)
5:3 = 分辨率比例
savePath = 保存地址
详细参数参考 = https://blog.csdn.net/a11544/article/details/58156521?fps=1&locationNum=3
"ffmpeg -i " + filePath +" -r 25 -strict -2 -vcodec libx264 -preset ultrafast -acodec aac -ar 44100 -ac 2 -b:a 96k " +frameFilePath;
25 = 帧率
String ffmpeg = "ffmpeg -i " + filePath + " -strict -2 -vf crop=" + (int)(videoWidth / bili) + ":" + (int)(videoHeight / bili) + ":0:0 -preset fast " + savePath;
(int)(videoWidth / bili) + ":" + (int)(videoHeight / bili) = 裁剪的尺寸,分辨率
:0:0 = 从什么位置开始裁剪 x y 不输入从0.0开始
String[] commands = ffmpeg.split(" ");
RxFFmpegInvoke.getInstance().runCommandRxJava(commands).subscribe(new RxFFmpegSubscriber() {
@Override
public void onFinish() {
Log.i(TAG,"onFinish: ");
}
@Override
public void onProgress(int progress,long progressTime) {
Log.i(TAG,"onProgress: ");
}
@Override
public void onCancel() {
Log.i(TAG,"onCancel: ");
}
@Override
public void onError(String message) {
Log.i(TAG,"onError: "+message);
}
});
需要先导入FFmpge项目 github上一大堆。
文档用于记录ffmpge使用方法,因本人初次使用,指令意思都不了解,方法找了很久才找到。
以上功能已经再项目中使用