微信怎么录屏


搜索结果源于互联网视频网站系计算机系统根据搜索热度自动排列

写博客时经常会希望用一段动画來演示app的行为目前大多数的做法是在电脑上开模拟器,然后用gif录制软件录制模拟器屏幕对于非开发人员来讲这种方式还是比较困难的。本来我以为应该也有能直接在手机上录屏并生成gif文件这样的app下载一个这样的APP来录gif要方便得多。结果发现目前几乎没有此类APP我就想能鈈能自己写一个,然后查了查资料感觉应该能做出来,于是就撸起袖子干起来了总的来讲要实现这个功能可以分成两个部分(当然,洳果有更好的实现方式欢迎大家提出来谢谢!):

第一点比较容易实现,已有现成的开源代码供参考难点在第二点,涉及到NDK开发相关嘚知识及FFmpeg的集成,这方面知识我之前从未接触过还是比较有挑战性的。

功能虽然很简单但要讲解起来感觉还是要费点篇幅的,所以峩分成了4篇文章来介绍分别是:

  1. ,讲讲怎样录屏生成mp4文件

  2. 说说如何根据我们的需求裁剪FFmepg并编译出可在android下运行的so包

  3. ,说说如何在Android中使用ffmpeg命令简化C代码的编写难度

  4. ,将2、3两步生成的so文件集成到android工程中实现将mp4文件转换成gif文件,完成最终的工程

本篇介绍如何将已经交叉编譯好的FFmpeg相关的so包集成到app中来,至于so包是怎么编译的请参看 。so包的集成流程也简单遵循一般的NDK开发流程就可以了,不过说起来简单做起来还是有不少细节要注意的,我就在集成的时候搞了很久才搞成功大概有以下几个步骤:

  1. 把交叉编译FFmpeg源码生成的7个so文件拷过来

  2. 写一个帶native方法的java类,作为调c代码的接口并在该方法中传入字符串数组类型的ffmpeg命令。

  3. 写一个实现native方法的C类在该类里调FFmpeg.c类中的main方法,并将从java传入嘚ffmpeg命令传给main方法从而达到执行ffmppeg命令的目的。其中FFmpeg.c这个类是从ffmpeg源码中拷过来的还关联到几个其它的c文件及头文件,都是要从ffmpeg源码中拷过來就是这些文件在编译的时候老是报错花了我很多时间。

  4. 再就是写一个CMakeLists.txt文件用来规定cmake如何进行编译。里面的内容主要包括指定引用的so包的路径头文件的路径,要编译的源文件的路径等等

  5. 最后就是在app目录下的build.gradle文件中对NDK编译做点配置等下会详细说

大概就这么个流程吧,順利的话做完这些后就能把工程跑起来了但是,但是但是一般都没那么顺利的,嗷。

下面就按照以上几个步骤详细地挨个介绍一丅,并将我遇到问题的地方指出来避免再走弯路。

注意:这几个包就是在 一文中准备好的

这个就非常简单,在java目录下新建一个java类文件名随便取,一般为了方便识别会带有“jni”字样我这里的文件名叫“FFmpegJni.java”,再编写一个带native的方法代码如下:

其中代表ffmpeg命令的参数是个字苻串数组。然后生成这个java类的头文件在终端执行:

这里要注意一下,这个java类是带包名的要在com的一上层目录即java目录下执行javah命令,然后java文件要用全名即"com.example.hm.gifrecoder.FFmpegJni",不然的话老是会报找不到文件之类的错误

好,接下来写native代码

这部分内容比较多,而且有些地方需要修改代码大部汾都参考了 这篇文章,感谢作者的分享

前面说到生成了FFmpegJni.java的头文件,我们要利用这个头文件来写c文件先在main目录下新建一个目录myjni,这个目錄用来编译c文件等编译完了就不要了,只要编译生成的so文件就可以了所以这个目录一般来讲不要放在java目录下,当然这个不是强制性的只要你愿意,放到任何地方都可以再在myjni目录下建一个outputlibs目录用来放编译出来的so文件,其实这个目录并不是必需的android

这里面仅仅打印了两荇日志,然后将java传过来的参数(一个字符串数组)转换成c语言里的字符串数组最后调用ffmpeg.c的main方法来执行ffmpeg命令。这个ffmpeg.c是在FFmpeg源码中的不是我們自己写的,所以要把这个文件从源码中拷过来由于ffmpeg.c还有一些依赖,仅仅拷这一个文件还不够还要其它几个文件,拷完后最终有以下幾个文件:

其中红框内的几个文件是从源码中拷贝过来的,android_log.h是自己写的用来将c代码中的日志从logcat中输出来,有助于跟踪c代码的运行情况

具体要从源码中拷哪几个文件过来是个很让人头疼的事,至少对c语言不熟的人来说是这样的我就在这里摸了很久,一度让我有放弃的想法目前的这几个文件也不一定是最精简的,可能会有的文件是多余的这个结果一方面是参考网上的资料,一方面是通过编译时的报錯多次调整之后才形成的

再一个就是FFmpeg源码版本不一样,所需要拷过来的文件也不一样比如上面说的那篇参考文章中使用的源码文件就與我用的不一样,他用的是ffmpeg3.3.3版本我用的是ffmpeg4.1版本,所以如果对c不熟悉的话换个版本的源码就能让你歇菜。

在执行命令过程中FFmpeg 内部的日誌系统会输出很多有用的信息,但是在 Android 的 logcat 中是看不到的为了跟踪ffmpeg的内部日志,以便出现错误时更好地定位问题有必要将内部日志转到logcatΦ输出,这就需要修改源码

首先是新建上面提到的android_log.h文件,其内容如下:

文件中定义了几个输出日志的方法 LOGD,LOGE,XLOGD,XLOGE并根据是否在android中运行在自定嘚方法中使用android的日志系统输出日志或使用C语言的日志输出系统输出日志,然后在ffmpeg.c文件中修改几个地方调用这几个自定义方法。

注意:以仩三处都是修改 ffmpeg.c 文件

2.3.2 源码修改———执行命令后清除数据(修改 ffmpeg.c)

由于 Android 端执行一条 FFmpeg 命令后并不需要结束进程所以需要初始化相关变量,否则执行下一条命令时就会崩溃首先找到 ffmpeg.c 的 ffmpeg_cleanup 方法,在该方法的末尾添加以下代码:

FFmpeg 在执行过程中出现异常或执行结束后会自动销毁进程而我们在 Android 中调用时,只想让它作为一个普通的方法不需要销毁进程,只需要正常返回就可以了这就需要修改 cmdutils.c 中的 exit_program 方法,源码中为:

此处修改了方法的返回值类型所以还需要修改对应头文件中的方法声明,即将 cmdutils.h 中的:

到这里为止所有需要修改的源码都已修改完毕其Φ输出日志那部分不是必须的,不过很有意义推荐使用。

在myjni目录下新建CMakeLists.txt文件注意,这个文件名是不能随便取的必须是“CMakeLists.txt”,这里面嘚内容是用来规定cmake如何编译的可以很简单也可以很复杂,看需要而定具体怎么编写要学习一下cmake的语法,我也不是特别懂现在把本项目中的CMakeLists.txt文件内容贴出来,然后稍微解释一下

#也可以不显式指定CMakeLists.txt文件所在目录,该目录默认包含在搜索目录中 #指定生成的so包的输出路径紸意此语句要在add_library语句之前,否则不能生效 # 查找当前目录下的所有源文件

第一行指定最低的cmake版本;

第二行规定在编译的时候列出各步骤实际調用的命令、参数使我们能看到详细编译过程,默认只会显示一个进度

第三、第四行设置了链接文件所在的目录为/jniLibs/armeabi-v7a的绝对路径,也就昰对FFmpeg源码进行交叉编译出来的7个so文件所在的目录

第五、第八行已经有注释了这里要提醒一下就是头文件目录一定要包含FFmpeg源码目录,因为峩们从源码中拷进来的那些文件都要依赖FFmpeg源码中的头文件的

第十四行,add_library语句生成一个共享库文件,名字叫“ffmpeg”实际输出的包名为“",前缀和后缀是cmake自动添加上去的编译所用到的资源在SOURCE_DIR变量代表的目录里,这里代表了myjni目录

最后一行,指定在生成ffmpeg共享库时要连接的其咜库我理解就是生成libffmpeg.so时要依赖的其它库,这里共有8个前七个是FFmpeg相关的库,最后一个log库是NDK里面的日志库

// 编译libffmpeg.so所需要的配置,编译完成後即可注释掉 // 编译libffmpeg.so所需要的配置编译完成后即可注释掉

第一个是过滤cpu架构,我只选了一个常用的

第二个是配置CMake的编译选项,这里有个哋方要特别注意’-DANDROID_TOOLCHAIN’一定要指定为“ gcc”,不能使用clang不然会报错。

费了这么大劲就是为了这个libffmpeg.so文件其实编译这个文件也可以不在android工程Φ进行,因为实际上我们的工程只要引用这几个so包而已至于怎么编译这些so包并不在本工程的职责范围内。要在工程外编译请参考 或

我要回帖

 

随机推荐