|
|
这一步会用到tools文件夹下面的工具脚本,
pull-repo-base.sh
,将ffmpeg
源码clone
到extra/ffmpeg
文件夹,
|
|
pull-repo-base.sh
脚本
简化一下,就是
将上一步clone下来的ffmpeg源码,不同arm处理器架构的(armv5 armv7 arm64 x86 x86_64)的文件相应文件夹下面android/contrib/
,
pull-repo-ref.sh
脚本
简化一下(以arm64为例),
--reference
的作用就是会clone
之前上一步的仓库缓存,达到节省不必要的clone
时间,
|
|
这一步是配置编译ffmpeg的参数,配置文件我们可以自己编写,config/
文件夹下面有已经预设的,module-defualt.sh
是ffmpeg官方默认的编译参数,module-lite.sh
包含通用的编译参数,module-lite-hevc.sh
在通用的基础之上添加了hevc解码,也就是俗称的H265
|
|
下载libyuv
的库,简单来表述就是:
首先清除源码中可能存在的编译缓存
然后开始编译ffmpeg
compile-ffmepg.sh
后面的参数代表编译哪个arm建构的版本,默认编译armv7a
,编译选项,后面执行的compile-ijk.sh
后面的选项也是同样的道理。
|
|
编译的过程中,
确认编译的相应处理器架构版本
例如会汇编armv7a,输出的确认信息如下:
do-pcompile-ffmeg.sh
开始执行编译,脚本路径:android/contrib/tools/do-compile-ffmepg.sh
以编译arm64
为例,简要表述这一步,
check env
这一步会检测,我们执行编译脚本compile-ijk.sh
时,有没有添加all armv5 armv7a arm64 x86 x86_64
等选项,否则会提醒:You must specific an architecture 'arm, armv7a, x86, ...
make NDK standalone toolchain
这一步调用tools/do-detect-env.sh
,脚本路径:android/contrib/tools/do-detect-env.sh
检测编译环境,用于检测NDK是否在环境变量中存在,包括NDK中的gcc版本和arm-linux-androideabi的版本,
会添加一些编译的参数,这里我们会关注一个编译参数,FF_CFG_FLAGS
:编译ffmpeg添加的额外的参数(config/module.sh中已经添加了一部分参数),FF_PREFIX
编译之后输出的文件目录,例如arm64输出目录是:android\contrib\build\ffmpeg-arm64\output
这一步加载fffmpeg的配置文件,这个文件就是我们之前配置的init-config.sh中配置的文件
这一步是配置ffmepg的编译参数,脚本代码块如下:
FF_CFG_FLAGS
就是前两步配置的编译参数。
这一步是编译正式开始编译ffmpeg,脚本代码如下:
|
|
这一步之后就完成了FFmpeg的编译过程,cp config.* $FF_PREFIX
这一字段,就是在编译之前,把我们的编译的配置信息log都被复制到了相应的moudle文件夹,路径:android/contrib/build/ffmpeg-arm64/output/
关键的一步来了,正常情况下,我们编译出来的ffmpeg的包含有libavcodec.a libavfilter.a libavformat.a libavutil.a libswresample.a libswscale.a
,这六个输出库,ijkplayer
将这六个库编译成一个独立ijkplayer.so
的共享库,
以编译arm64版本为例,
这一步将生成的库文件拷贝到相应的共享文件夹,
mysedi()
函数中注意几个命令的使用方法:bansename $f
表示去掉文件f
的路径和后缀名;sed
表示查找替换功能,sed 's/\output/\/output\/shared/g'
是将/output/
替换成/output/shared/
这一步之后完成了对ffmpeg的编译,并且通过android的standalone-toolchain编译完成了ffmpeg的共享库-libijkffmpeg.so
|
|
这一步进入ijkplayer/
下相应版本的文件夹下面执行ndk-build
命令,将打包编译生成ijkplayer.so
,ndk-build
命令将打包编译三部分的源码:ffmepg
:之前打包编译的SRC_FILES:ijkffmpeg.so
,ffmepg
的include
android-ndk-prof
:编译ijkprof
中的c源码,生成android-ndk-profiler
的静态库,主要作用的打印ndk-build
的log信息。ijkmedia
:编译ijkmedia/
下面的源码,其中主要包括了ijk4a,jkplayer,ijksdl,ijksoundtouch,ijkyuv
这5个模块
这一步完成之后,ndk
根据上面列出的模块下面的Android.mk
文件进行编译,最后生成ijkplayer
的共享库
DirectShow框架是多媒体播放框架上一个非常经典的框架,现在已经十多年了,在Windows平台上依然无法替代,非常值得去学习研究。个人觉得从设计模式的角度上看,directshow框架的灵活性、复用性、可维护性、可拓展性这些方面做得非常不错,也是它经久不衰历久弥新的一个原因,现在的很多第三方的decoder和filter都基于directshow框架开发,可以很灵活的移植到directshow视频框架中,例如视骏开发的HEVC/H.265
解码器,都可以直接挂载在directshow框架中进行视频解码。
推荐一款工具GraphStudio,了解DirectShow框架必备工具,软件截图如下:
我们点击Graph
可以插入我们在电脑系统中注册的Filter
Render
,默认情况下,我们将播放的视频加到GraphStudio中,会自动生成directshow
的整个播放流程,然后就可以播放视频了。一般的播放效果流程如下:
GraphStudio
会自动采用系统默认的一套Filter
和Render
,如果安装了K-Lite Codec Pack,就可以修改系统默认的这一套,如下图:
我们想测试我们自己的Filter
和Render
,都可以自定义插入,下面就以DirectShow中植入视骏的HEVC
解码器为例子,了解DirecShow的整个播放流程,如下图所示:
可以参考雷老师关于DirectShow
的介绍,地址:http://blog.csdn.net/leixiaohua1020/article/details/42372419
播放的流程如下:
整个播放我们可以抽象出三个步骤:
Strongene Mpeg-4 Demultiplexor
,Lentoid HEVC Decoder
,Video Renderer
GraphStudio
图中的链接箭头首先获取到这些Filter的Object name
、CLSID
、Filename
和FilePath
如果已经将filter注册进Windows的系统中,就只需要用到Object Name
,为了避免重新注册导致冲突;
|
|
|
|
|
|
|
|
查找空闲的filter的接口
|
|
查找空闲的splitter的空闲指针接口
|
|
|
|
|
|
MediaInfo是一款专门用来分析音频和视频的文件编码和内容信息的开源软件,通过MediaInfo可以快捷明了的获取多媒体文件信息,支持多平台(windows、mac、linux等),我们平时常用的K-Lite Codec Pack就集成MediaInfo的功能,相比FFmpeg
,MediaInfo
获取多媒体信息的方式更加快捷丰富。
MediaInfo获取的文件信息有:
支持的文件格式有:
主要特点
源码下载:https://mediaarea.net/zh-CN/MediaInfo/Download
编译生成库文件都很简单,下载的源码会有两个第三方库:ZenLib
和zlibstate
,以及源码的主角MediaInfoLib
,在windows环境下用Visual Studio就可以打开相应版本的工程文件就可以进行编译了,如VS2015的工程文件在目录libmediainfo_0.7.93_AllInclusive\MediaInfoLib\Project\MSVC2015
下面,编译完成可以生成相应的MediaInfo.lib
和MediaInfo.dll
两个文件,放在我们自己新建的工程文件就可以使用了,新建的工程文件需要将MediaInfoDLL.h
的头文件放在工程当中,使用了MediaInfoDLL
的命名空间,和声明了两个类:MediaInfo
和MediaInfoList
声明对象:
查看使用的MediaInfo版本:
查看MediaInfo所有参数说明
查看所有解码器说明
打开视频文件
|
|
显示视频的所有基本信息
查看所有信息
查看自定义信息
关闭对象
例如一个视频文件的所有信息如下:
点此处可以下载已经写好的MediaInfoDemo
]]>
|
|
|
|
|
|
|
|
修改之后如下:
|
|
hardware/rockchip/hwcomposer
下的文件转换文本格式:find . -type f -exec dos2unix {} \;
先来几个参考网站,
1、官方编译网站
编译需要的原料:
1、FFmpeg源码 —————– 官方下载
2、MSYS2(编译环境) ————-MSYS2官方下载
3、YASM ————————官方下载地址
4、gas-preprocessor ————下载地址
msys2类似于cygwin(可以在windows上配置linux环境)和mingw(git的bash环境),安装完成之后,先需要把安装目录下的msys2_shell.cmd
中注释掉的rem set MSYS2_PATH_TYPE=inherit
,改成set MSYS2_PATH_TYPE=inherit
,主要是将vs的环境继承给msys2
;接着打开msys2的shell,安装4个编译工具,
如果之前安装了cygwin,这里的安装可能会出现冲突问题,导致cygwin的bash窗口中没法使用一些命令,如:ls等等,一般会报错:
1234567 1 [main] ls (138392) D:\msys64\usr\bin\ls.exe: *** fatal error - cygheap base mismatch detected - 0x180305408/0x1802FE408.This problem is probably due to using incompatible versions of the cygwin DLL.Search for cygwin1.dll using the Windows Start->Find/Search facilityand delete all but the most recent version. The most recent version *should*reside in x:\cygwin\bin, where 'x' is the drive on which you haveinstalled the cygwin distribution. Rebooting is also suggested if youare unable to find another cygwin DLL.
这时候我们需要在我的电脑中改变一下环境变量,在Path中将D:\cygwin64\bin
提到D:\msys64\usr\bin
前面,没有的话可以先配置
将下载的yasm-**-win64.exe
改成yasm.exe
,替换msys安装目录x:\msys64\usr\bin\yasm.exe
,可以做个备份把原来的改成yasm.bak
将下载的gas-preprocessor.pl放到msys2安装目录下面x:\msys64\usr\bin\gas-preprocessor.pl
这一步没有把握正确,编译很容易出错,例如cl is unable to create an executable file.
正确的启动步骤是:先去打开VS的工具命令提示符,C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio 2015\Visual Studio Tools\Windows Desktop Command Prompts
,然后在命名窗口中使用命令符打开msys2的bash窗口,
我安装在D盘,依次执行命令如下:
在bash窗口中先检查,安装环境是否已经正确配置:
|
|
正确配置之后就可以进行编译了。
编译ffmpeg,有两种方式,
可以按照微软官方的Demo教程来编译,先使用git下载,
下载完成之后,目录结构如下:
直接在bash窗口中进入,执行执行编译相应版本的命令就行了
首先步骤是./configure
配置编译参数,可以参考微软Demo中的脚本FFmpegConfig.sh
,先进入下载的FFmepg源码目录,
比如编译Win10的x64版本,
编译完成之后,ffmpeg的编译库就在Build/Windows10/x64
目录下面,目录结构如下:
|
|
|
|
下载ffmpeg和libyuv的源码
从远程仓库下载编译所需要的源码,
|
|
|
|
官方Android工程的文件夹在android/ijkplayer中,结构如下:
Android的官方Demo在ijkplayer-example中,后面文章会详细一点分析ijkplayer的编译过程和调用过程
]]>SDL(Simple Directmedia Layer)是一套开源的跨平台多媒体开发库,集成了音视频的许多底层的API,介绍Windows平台下的例子已经很多了,例如:雷老师的 最简单的视音频播放示例7:SDL2播放RGB/YUV,既然SDL是跨平台的,自己有参考了雷老师的这篇文章 最简单的基于FFmpeg的移动端例子附件:SDL Android HelloWorld,下面将介绍下Android平台上播放视频的简单的例子
SDL4Android中接口都是使用c语言写的,接口调用使用的是java,android调用c的接口需要用到jni(java native interface)技术,需要先将c接口编译成共享库.so
文件,目前可以使用两种工具进行编译:ndk和cmake(android-studio2.2以后的版本才支持cmake编译),下面的框图显示的是使用ndk工具编译SDL的接口:
SDL的文件源码主要分为两部分,一部分是java代码,主要包含有Android上层使用的SDLActivity上层接口调用函数;另一部分就是SDL-jni,包含所有SDL底层的源码、自定义的接口源码以及将这些源码编译成共享库所需的Android.mk文件。
如图中所示,SDL_android.c
和SDL_android_mian.c
是官方demo中编译官方接口的c源文件,其中SDL_android.c
编译21个接口放在libSDL2.so
共享库中;在此次使用SDL播放视频的Demo中,SDL_android_mian.c
配合我们自定义的Custom.c
(可以定义多个或者一个文件)只编译一个nativeInit()
接口放在libmain.so
共享库中
SDL的介绍就不多说了,详细可以访问SDL官方网站,推荐一个中文学习网站SDL中文教程,但是里面的API版本是1.2的,可以了解一下,还有就是外文的教程网站Lazy Foo,利用SDL播放视频,推荐访问CSDN雷老师的博客。
截至2017年2月,SDL版本已经更新到2.05,点击官方下载地址
github上也可以下载github下载地址
在android工程中我需要用到的源码,android-project、include、src三个文件夹
android-project中主要是官方的demo:jni文件夹中需要配置.mk
编译文件,src文件夹中包含官方的android上层java代码;
include和src中就是SDL的底层C代码,编译之后方可被上层java调用。
因为我们解码用到的是ffmepg,所以此次还要集成ffmpeg的源码,不了解ffmpeg的移植的话,可以查看我前面写的文章:第一次完成FFmepg的移植,编译ffmpeg4Android
为了减少代码的层级,我把SDL的源码和FFmepg的源码混合了在一起了
SDL打开视频播放的过程实际上是创建一个SDLActivity
的过程,SDLActivity
会创建一个SDLSurface
和一个layout布局,然后将SDLSurface
添加到布局上面,视频画面就是在SDLSurface
上显示出来,正如上图中,SDLSurface
要调用nativeInit函数,必须先通过JNI实现图像解码显示功能
我们对nativeInit
函数稍作修改,在SDLActivity
中把视频的URI传给nativeInt
函数,
SDLActivity.java
声明中,
SDL_android_main.c
中,
先看下FFmpeg的解码和SDL的显示流程:
先新建一个自定义的c源文件convexd_native_render.c
,我们的视频的解码和显示都会在这里面实现。
此工程中的Android.mk
文件在移植ffmepg的Android.mk
文件的基础上增加了编译libSDL2main.so
和libSDL2.so
的配置,如下:
可以根据自己的路径配置mk文件
|
|
在手机根目录下新建一个convexd
的文件夹,把播放视频放进去,打开我们打包的demo,选择视频就可以实现视频的播放功能。
|
|
此时会获取到远程版本仓库到本地
|
|
|
|
|
|
就不多废话了,终于找了卸载VS2013以后版本的卸载神器了,github地址:https://github.com/Microsoft/VisualStudioUninstaller
一看居然是微软自己出品!!也是醉了,微软你这不是瞎折腾么??找了这么长时间,之前还用命令符卸载:vs_community.exe /uninstall /force
,发现白忙活了,还是卸载不干净。
以管理员方式运行强制卸载工具,提醒一下这个软件会卸载vs2012及以前版本的更新,
卸载之后终于清爽了,可以安装我们需要的VS版本了
]]>我们以加水印功能为例,
例如,
我新建了一个图片样式名称为WaterMark
,
样式的分隔符为中划线-
,
现在我获取的图片的原始URL为http://of6x0sb2r.bkt.clouddn.com/separator.png
那么加水印的图片的URL就写成http://of6x0sb2r.bkt.clouddn.com/separator.png-WaterMark
图片就会自动加上我们新建的图片水印样式。
]]>
|
|
Pitch
表示纹理表面一行所包含的byte,也就是一行纹理的长度,在使用的过程当中我们会发现这个长度必须是位宽的整数倍,也就保证和显存位宽对齐,这个和显卡有关系,常见的有64bit、128bit和256bit等;pBits
表示一个指针,指向我们锁定表面纹理的数据;
如果不考虑图片的宽和LockedRect.Pitch之间的关系,会很容易出现纹理最终显示出来的图片乱码
首先通过一个例子,已知我们有图像的RGB数据,存储在imgData数组里面,我们要将RGB数据生成图片,该如何做?
解题流程:创建纹理 —> 锁定纹理表面 —> 对表面进行填充 —> 解锁表面 —> 生成纹理
|
|
其实以上代码是有错误的,
所以我们要将上面for循环里面的代码进行修改:
这里要注意几点,
注意一: 在创建纹理的时候,我们明明使用的纹理格式是R8G8B8,但是最后生成纹理的时候,每个像素点仍然占用4个字节,所以我们如果有alpha通道的数值可以填充进去,因此代码可以再进行修改如下;
|
|
注意二: 不能错误地把创建纹理表面的宽度和图片的宽度划等号,他们并不相等,他们之间的关系使用公式 LockedRect.Pitch = 128*ceil(imgWidth*4/128)
。
以我电脑显卡为例,创建表面的宽度是128的倍数,即LockedRect.Pitch
是128的倍数,
那么问题来了,假如我现在的图片宽度是2160,按正常的4通道图片来算应该是2160 * 4 = 8640
,但是我们锁定的纹理表面的宽度LockedRect.Pitch = 8704 = 128 * ceil(2160*4/128)
,
这样就多出了64字节的空间,怎么办?其实不用管,不用进行任何操作。
下面是通过图片创建纹理,这个例子更简单,只要保证每次拷贝一行数据到纹理对应的一行就行了,
Android.mk
文件是NDK
构建系统用来描述C
和C++
源文件,是轻量级的Makefile
片段,在构建系统中会被一次或多次解析,帮助我们将C
和C++
源文件打包成模块,包括静态库和共享库等;要将C\c++
编译成.so
文件,除了android.mk
文件,还需要Application.mk
文件,Application.mk
是用来描述应用程序需要的模块。可以将这两个.mk
文件理解成C\C++
源文件编译成.so
库文件的配置文件。
构建系统利用LOCAL_PATH来定位源文件,并提供了一个my-dir的宏功能,通过该宏功能的返回值,放在当前目录下
LOCAL_PATH := $(call my-dir)
CLEAR_VARS,清除除了LOCALPATH以外的LOCAL
include $(CLEAR_VARS)
给模块设置一个唯一的名称,该模块会生成一个libname.so的名字
LOCAL_MODULE := name
指定用来构建和组装这个模块的源文件列表,多文件的之间用空格隔开
LOCAL_SRC_FILES :=
*.cpp
*.h
为了构建主程序能够使用的模块,必须将模块变成共享库
include $(BUILD_SHARED_LIBRARY)
Android应用程序并不直接使用静态库,应用程序包中也不包含静态库,但是静态库可以用来构建共享库,一般第三方的源代码不是直接包含在原生项目中,而是将他们先编译成静态库,然后在并入共享库中
include $(BUILD_STATIC_LIBRARY)
使用其他NDK项目的共享模块,调用函数宏import-module,放在Android.mk文件的末尾,以免构建系统冲突
$(call import-module, path/to/shared-libname)
使用Prebuild库,特点:1. 不发布源代码的情况下共享自己的模块;2. 想使用预建版模块来加速构建过程
LOCAL_SRC_FILES := libname.so
include $(PREBUILD_SHARED_LIBRARY)
构建可执行文件
include $(BUILD_EXECUTABLE)
构建系统定义的其他变量
变量名 | 说明 |
---|---|
TARGET_ARCH | 目标CPU的体系结构,例如:arm |
TARGET_PLATFORM | 目标android平台的名称,例如:android-24 |
TARGET_ARCH_ABI | 目标CPU的体系结构和相应的abi名称,例如:armeambi-v7a |
TARGET_ABI | 目标平台的名称和abi串联,例如:android-23-armeabi-v7a |
变量名 | 说明 |
---|---|
LOCAL_MODULE_FILENAME | 用来重新定义模块的输出名 |
LOCAL_CPP_EXTENSION | 为C++源码添加其他拓展名,默认为.cpp |
LOCAL_CPP_FEATURES | 指明模块所依赖的具体的C++特性,例如:rtti |
LOCAL_C_INCLUDE | NDK的安装目录为相对路径,用来搜索头文件 |
LOCAL_CFLGS | 编译器标志,编译C/C++源文件时传给编译器 |
LOCAL_CPP_FLAGS | 只编译c++源文件时传送给编译器 |
LOCAL_WHOLE_STATIC_LIBRARY | 用来指明包含在所生成的共享库中的所有静态库 |
LOCAL_LDLIBS | 用于传送要动态链接的系统库列表 |
LOCAL_ALLOW_UNDEFINDE_SYBOLS | 用于禁止生成文件的过程中使用符号检查 |
LOCAL_ARM_MODE | 指定要生成的ARM二进制类型,默认情况下使用16位指令生成,当该值被设置成arm就是指定使用32指令生成,构建文件添加.arm 后缀名可以指定arm模式下构建指定文件 |
LOCAL_ARM_NEON | 用来指定在源文件中应该使用arm的高级单指令多数据流(SIMD)内联函数,该值设置为true时,用.neon后缀名指定只构建带有NEON内联函数的特定文件 |
LOCAL_DISABLE_NO_EXECUTE | boolean类型,用来禁止NX Bit(永不执行)安全特性,该安全特性用来隔离应用程序代码区和存储区,以防止恶意软件通过植入存储区代码来控制软件 |
LOCAL_EXPORT_CFLAGS | 记录一组编译器标志,如果其他模块通过变量LOCAL_STATIC_LIBRARIES或者LOCAL_SHARED_LIBRATIES使用本模块,该flag会被添加到这些其他模块的LOCAL_CFLAGS当中 |
LOCAL_EXPORT_CPPFLAGS | 和LOCAL_EXPROT_CFLAGS一样,作用于c++代码上 |
LOCAL_EXPORT_LDFLAGS | 和LOCAL_EXPORT_CFLAGS一样,作用于链接器上 |
LOCAL_EXPORT_C_INCLUDES | 允许记录路径集,添加到LOCAL_C_INLCUDES当中 |
LOCAL_SHORT_COMMANDS | 对于有大量资源或独立的共享库/静态库,应该设置为true |
LOCAL_FILTER_ASM | 过滤来自LOCAL_SEC_FILES的资源文件的应用程序 |
和Android.mk一样是放在jni文件夹下面,描述应用程序需要哪些模块,定义了所有模块的通用变量
变量名 | 说明 |
---|---|
APP_MODULES | 声明构建的所有模块 |
APP_OPTIM | 可以设置为release或者debug,改变生成二进制文件的优化级别 |
APP_CFLAGS | 列出编译器标志,在编译时传给编译器 |
APP_CPPFLAGS | 和APP_CLAGS相同,作用于C++源文件 |
APP_BUILD_SCRIPT | 查找Android.mk构建文件 |
APP_ABI | 默认为armeabi,可以添加mips,all等变量 |
APP_STL | NDK默认使用最小的stl库,该变量可以选择不同的STL实现 |
APP_GNUSTL_FORCE_CPP_FEATURES | 表明所有模块都依赖于具体的C++特性,如RTTI,exceptions等 |
APP_SHORT_COMMANDS | 大量源码时使用更短指令 |
/usr/share/applications
这个文件夹下面,这些配置文件的后缀名都是.desktop,首先进入这个目录下,
sudo su
cd /usr/share/applications
ls
这里我自定义了android-studio2.2的应用程序的快捷方式,
1. 先在其他的文件夹中新建一个快捷方式的配置文件,比如`AndroidStudio2.2.desktop`,
2. 编辑这个配置文件,推荐使用vim编辑,因为在编辑代码的时候我们可以看到语法上是不是存在错误,
vim AndroidStudio2.2.desktop
![shortcut-param](http://of6x0sb2r.bkt.clouddn.com/linuxlink_param.png "快捷方式配置")
3. 配置文件参数简要
|
|
4. 对这个文件保存,并添加执行权限
chmod a+x AndroidStudio2.2.desktop
这样我们就添加成功了快捷方式,
]]>作为日常使用,还是希望以官方为主,加一些第三方的系统工具,比如去广告之类的软件,但是我们又想不破坏官方的系统服务,毕竟还是要用到小米的一些系统服务,
比如,小米公交卡、小米支付之类的,一般以这样的一些简单的目的来root手机,推荐还是使用官方的原生MIUI开发版
系统,下面讲一下root方法。
root分两步:一是解锁,二是获取系统root权限,官方的开发版系统
是提供了root的权限管理的
首先,解锁,解锁也分两步,一是解锁bootloader,二是解锁system
解锁bootloader,官方提供了工具,使用自己的小米账号申请解锁就行了
解锁system,但是这一步的前提是你的开发版系统权限管理里已经勾选可root,手机连上电脑(电脑已经安装好手机驱动和adb程序),打开命令窗口,依次输入命令
adb devices 检测设备是否连上
adb root
adb disable-verity
adb reboot
这样手机重启就实现解锁system了,而且实现了不破坏系统的轻量级的root系统,手机可以继续OTA更新官方的miui,只是每次OTA都会下载整个系统包,
有个缺点就是每次OTA更新系统之后都必须再次开启root权限,然后执行上述解锁system的操作,不过还是比较简单的
参考文章:手把手图文并茂教你用Android Studio编译FFmpeg库并移植
下面是我自己在ubuntu下编译
Git,NDK
安装git,检查本地git,git --version
直接用命令符安装: sudo apt install git
也可以去官网下载,git官网下载
如果已经有了git,想更新到最新版,可以输入 git clone https://github.com/git/git
,再进行编译安装
然后下载NDK(现在已经有13的版本了),推荐使用android studio安装ndk,下载的ndk路径默认在AndroidSDK的ndk-boudle文件中
使用terminal配置电脑的环境,(个人电脑,我直接以管理员权限配置的系统环境变量)
sudo gedit /etc/profile
打开之后,把我们的ndk路径配置进来,
新建一个ffempeg的工作文件夹,例如 mkdir workplace
git clone https://git.ffmpeg.org/ffmpeg.git
也可以直接去官网下载:ffmpeg官网下载
为了保证我们编译出的文件是以.so的后缀名
将文本中的3209-3212这4行:
修改改为:
写脚本的直观上的好处就是省去了一步步的执行编译命令,通常的在编译之前都需要进行配置,设置相应的环境变量,比如指定编译工具、编译平台等等,查看所有的配置选项可以在ffmpeg目录执行如下命令:
./configure –help
当然此脚本中,我们只需要设置几个我们比较关心的配置。
1. NDK的路径:
NDK=/path/to/ndk
2. 编译的ndk plaform版本:
SYSROOT=$NDK/platforms/android-23/arch-arm/
3. 交叉编译工具:
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
4. CPU平台:
CPU=arm
5. 编译完成后安装目录(当前目录下的android文件夹):
PREFIX=./android/$CPU
确定我们需要的配置之后,在ffmpeg的目录下面新建一个脚本 build4android.sh
|
|
这里增加一个方便的脚本技巧,便于修改自己的配置,我们将这些configure配置参数写进一个脚本function,建议如下语法:
另外一种一种语法(这种可能会报找不到function的错误,不推荐使用):
还有就是脚本编辑推荐使用vim非常方便,变量参数一目了然
进入我们的FFmpeg的源码目录,执行刚才的脚本:
(先增加执行权限 sudo chmod +x build4android.sh
,以防权限不够)
./build4anroid.sh
脚本执行中:
脚本执行完成:
生成的android/arm/
目录中的文件,图中标出的为链接文件可以删除:
在android-studio中切换成project工程目录模式,在app/src/main
目录下面新建一个jni
文件夹,将上面第6步中的include
文件夹拷贝到此文件夹中,再在jni
文件夹中新建一个lib
文件夹,将.so
文件拷贝进来,新建Android.mk
,Application.mk
和c文件目录结构如下:
|
|
|
|
|
|
在上面编写的Android.mk中,我们制定了c文件的名字为ffmpeg-jni.c
,所以c文件的与此保持一致,
函数申明语法:JNIEXPORT jstring Java_包名activity名函数名,包名中间的点号.
全部变成下划线_
例如:我在包名com.righere.ffmpegndkbuild
下面的MainActivity
中要使用avcodecInfo这个函数,
JNIEXPORT jstring Java_com_righere_ffmpegndkbuild_MainActivity_avcodecInfo
|
|
build.gradle
).mk
文件的路径(在android{–}里面添加):
|
|
.so
文件在哪个目录下面(在android{–}里面添加):这里我编译的armeabi
版本的生成的.so
文件自动会放在了’src/main/libs/armeabi’这个目录下面,其他的版本只需要把armeabi
名字变一下就行了
这一步其实可以看做是对.mk
文件的补充
|
|
编译完成main文件夹下会增加libs
和obj
两个文件夹,其中libs/armeabi
下就是我们需要的.so
文件
切换回Android结构的工程试图,系统会自动把生成的.so
文件放入jniLibs
中,看到这个FFmpeg的移植基本就成功了
在MainActivity中添加测试代码,
|
|
参照官网:Hexo官网
新建一个文件夹,这里就是我们本地的Hexo目录了,比如新建Myblogs
文件夹,然后进入这个目录,
cd Myblogs
然后用执行安装Hexo的命令:
npm install hexo-cli -g
此时会出现一些WARN,不过不会影响hexo使用
npm install hexo –save
初始化Hexo
hexo init
安装hexo相关组件
npm install
先生成一个helloworld的demo网页
hexo g
本地测试生成的网页
hexo d
打开浏览器输入 http://localhost:4000/
可以看到生成的demo网页
新建自己的blog
hexo n “MyBlog”
这样就新建了一个自己的blog,页面编辑/source/_posts/
目录下面会生成markdown文件
新建远程github仓库,仓库命名规则:你的名字.github.io
修改全局配置文件
配置主题:网上可以找到很多好看的主题,推荐next,很简洁,配置简单,next项目地址
部署到github,修改_config.yml文件中的Deployment,
使用git的方式部署,需要执行
npm install hexo-deployer-git –save
执行部署
hexo d
打开自己的写的blog,打开网页
https://yourname.github.io
如果在其他电脑上或者系统上编辑自己的博客也很简单:
接着将hexo的分支设为默认,
注意这里有个巨大的坑!!!如果你用的是第三方的主题theme,是使用git clone下来的话,要把主题文件夹下面把.git文件夹删除掉,不然主题无法push到远程仓库,导致你发布的博客是一片空白
初始化本地仓库: git init
添加本地所有文件到仓库:git add -A
添加commit:git commit -m "blog源文件"
添加本地仓库分支hexo:git branch hexo
添加远程仓库:git remote add origin git@github.com:yourname/yourname.github.io.git
将本地仓库的源文件分支hexo强制推送到远程仓库hexo分支:git push origin hexo -f
上传完成之后,我们就拥有了两个远程的分支:master和hexo,其中master是部署成博客的分支;hexo是我们可以clone到其他电脑或其他系统的hexo源文件的分支,而且我们已经将它设置成默认仓库;
git clone -b hexo git@github.com:yourname/yourname.github.io.git
进入本地仓库执行hexo安装:npm install
依次执行git add .
,git commit -m "改了啥"
, git push origin hexo
,同步本地仓库到远程
部署发布博客: hexo g
,hexo d
这样就生成静态网页部署到了github中
关于第三方主题next的问题以及解决办法
症状: 今天使用github将next的主题文件进行了更新,使用hexo g
生成静态网页,然后hexo s
本地调试成功,也没什么问题,当我hexo d
发布到远程仓库的之后,在线浏览的时候发现一片空白,这时候使用其他主题都没问题,网上找到了答案。
解决办法: 将主题文件夹下面的source/vendors
,全部改成source/lib
1. 先把主题文件夹下面`source/`下的`vendors`改成`lib`;
2. 将主题配置文件中`_internal: vendors`改成`_internal: lib`
3. 将主题文件夹下面其他文件中的`source/vendors`改成`source/lib`
创建一个videolistview.xml线性布局
每一个videoitem.xml的布局:
这里使用了androidstudio2.2新增的布局ConstraintLayout
使用了一个imageview用显示视频的略缩图,两个textview分别显示视频的名字和视频长度,上图直接用图形化界面直接创建的,所以代码可能有点长
每一个视频列表的videoitem由两部分组成,一是Video的缩略图,二是video的名字和时长等属性,
先创建缩略图的LoadImage.java类,再创建VideoItem.java类
LoadImage.java
VideoItem.java
重点在适配器中添加缩略图方法addthumbnail,和getview方法
|
|
需要创建以上两步只是配置好了布局,后面我们需要从内存中获取视频的文件,首先我们获取到视频文件然后放入List
先实现获取视频list的接口:
AbstractProvider.java
再实现获取所有视频方法
VideoProvider.java
开始视频列表主界面的主体工程,将前面的视频列表的部件组装成完整的视频播放列表
VideoListActivity.java
|
|
完成后的主界面效果图: