① 有沒有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使用方法,因本人初次使用,指令意思都不了解,方法找了很久才找到。
以上功能已經再項目中使用