在安卓中使用 FFmpegKit 剪切視頻并添加文字水印

在安卓中用到的三方庫:https://github.com/arthenica/ffmpeg-kit

這個庫很強大,支持很多平臺,每個平臺都有各自的分支代碼,用了一段時間,穩定性挺好的,

找到安卓下的分支:FFmpegKit for Android FFmpegKit Android 版

引入項目:

repositories {mavenCentral()
}dependencies {implementation 'com.arthenica:ffmpeg-kit-full:6.0-2'
}

每個平臺下,又分為多個庫,每個庫包含不同的功能,因為功能越豐富,導入到項目中編譯的包體積越大,盡量選擇適合自己功能的庫進行使用。


📦 FFmpeg 編譯配置選項(庫依賴分類)

配置項說明包含的庫
min最小化構建-
min-gpl最小化構建并啟用 GPL 庫vid.stab, x264, x265, xvidcore
https啟用 HTTPS 支持(使用非-GPL 依賴)gmp, gnutls
https-gpl啟用 HTTPS 支持(使用 GPL 兼容依賴)gmp, gnutls, vid.stab, x264, x265, xvidcore
audio啟用音頻相關編碼器/解碼器lame, libilbc, libvorbis, opencore-amr, opus, shine, soxr, speex, twolame, vo-amrwbenc
video啟用視頻相關編碼器/解碼器dav1d, fontconfig, freetype, fribidi, kvazaar, libass, libiconv, libtheora, libvpx, libwebp, snappy, zimg
full啟用所有非 GPL 第三方庫dav1d, fontconfig, freetype, fribidi, gmp, gnutls, kvazaar, libass, libiconv, libilbc, libtheora, libvorbis, libvpx, libwebp, libxml2, opencore-amr, opus, shine, snappy, soxr, speex, twolame, vo-amrwbenc, zimg
full-gpl啟用所有庫(包括 GPL)dav1d, fontconfig, freetype, fribidi, gmp, gnutls, kvazaar, lame, libass, libiconv, libilbc, libtheora, libvorbis, libvpx, libwebp, libxml2, opencore-amr, opus, shine, snappy, soxr, speex, twolame, vid.stab, vo-amrwbenc, x264, x265, xvidcore, zimg

比如你如果只需要保存 rtsp 視頻流 和 推流的話,只需要導入 min-gpl即可:

 implementation 'com.arthenica:ffmpeg-kit-min-gpl:6.0-2'

如果你想要更多,比如添加水印,就涉及到 FFmpeg 濾鏡相關功能,就需要引入full-gpl

 implementation 'com.arthenica:ffmpeg-kit-full-gpl:6.0-2'

具體需要什么功能,可以進去看說明,說明沒有涉及到的,并且你不想用全功能庫,你也可以一個一個試試,也許就能滿足你。

正文開始


由說明可知,使用方式為:

import com.arthenica.ffmpegkit.FFmpegKit;FFmpegSession session = FFmpegKit.execute("-i file1.mp4 -c:v mpeg4 file2.mp4");
if (ReturnCode.isSuccess(session.getReturnCode())) {// SUCCESS} else if (ReturnCode.isCancel(session.getReturnCode())) {// CANCEL} else {// FAILURELog.d(TAG, String.format("Command failed with state %s and rc %s.%s", session.getState(), session.getReturnCode(), session.getFailStackTrace()));}

或者異步調用:

FFmpegKit.executeAsync("-i file1.mp4 -c:v mpeg4 file2.mp4", new FFmpegSessionCompleteCallback() {@Overridepublic void apply(FFmpegSession session) {SessionState state = session.getState();ReturnCode returnCode = session.getReturnCode();// CALLED WHEN SESSION IS EXECUTEDLog.d(TAG, String.format("FFmpeg process exited with state %s and rc %s.%s", state, returnCode, session.getFailStackTrace()));}
}, new LogCallback() {@Overridepublic void apply(com.arthenica.ffmpegkit.Log log) {// CALLED WHEN SESSION PRINTS LOGS}
}, new StatisticsCallback() {@Overridepublic void apply(Statistics statistics) {// CALLED WHEN SESSION GENERATES STATISTICS}
});

與正常 ffmpeg 命令不同的是,在傳入命令時,前面不需要加 “ffmpeg” 關鍵字,只需傳入后面的具體命令即可,加上會報錯哦!

關鍵代碼:

搞了好久才湊齊的正確代碼,這東西真不能聽 AI 的一面之辭,不然就被 AI 一條路領到黑,

    private static String buildWatermarkCommand(VideoFile file, VideoTimeRange timeRange, String outputPath, String fontPath) {FFmpegKitConfig.setFontconfigConfigurationPath(fontPath);String drawtextFilter = String.format("drawtext=text='%s':fontfile=%s:fontcolor=white:fontsize=20:x=0:y=30",DEFAULT_WATERMARK, fontPath);List<String> commandList = new ArrayList<>();commandList.add("-ss");                              // 指定輸入文件的開始時間,格式:HH:MM:SScommandList.add(timeRange.startTime);commandList.add("-i");                               // 輸入文件路徑commandList.add(file.filePath);commandList.add("-t");                               // 指定持續時間,格式:HH:MM:SScommandList.add(timeRange.durationStr);commandList.add("-vf");                              // 視頻濾鏡,用于添加水印文字commandList.add(drawtextFilter);commandList.add("-c:v");                             // 視頻編碼器設置commandList.add(VIDEO_CODEC);                        // 使用H.264軟件編碼器commandList.add("-preset");                          // 編碼速度預設commandList.add(VIDEO_PRESET);                       // ultrafast:最快編碼速度,文件稍大commandList.add("-crf");                             // 恒定質量因子(0-51,越小質量越好)commandList.add(String.valueOf(VIDEO_CRF));          // 23:平衡質量和文件大小的推薦值commandList.add("-c:a");                             // 音頻編碼器設置commandList.add("copy");                             // 直接復制音頻流,不重新編碼commandList.add("-r");commandList.add("20");                               // 每秒20幀commandList.add("-avoid_negative_ts");               // 避免負時間戳問題commandList.add("make_zero");                        // 將負時間戳調整為0commandList.add(outputPath);                         // 輸出文件路徑return String.join(" ", commandList);}

簡單介紹下命令作用:對一段現有的視頻文件進行剪輯,-ss指定開始時間,比如要剪切的原視頻時長為兩分鐘,所以開始時間到結束時間就是:00:00:00 - 00:02:00 , 假設要剪輯中間一分鐘的視頻,那么 -ss指定的開始時間為:00:00:30 , -t持續時間就是:00:01:00 , 截取的時間段為:00:00:30 - 00:01:30 ,-c:v設置編碼器,一般 H.264 就夠了,如果設置其他的編碼器,要看你的設備支持不支持了,-r設置幀率,如果你想要剪切的視頻大小小一點,一方面就可以通過降低幀率,另一方面就可以降低碼率來實現(上述命令碼率未指定默認按原視頻碼率)。

如果你指定的時間范圍,超過原視頻時長會報錯,這很正常,只是報錯內容可能看不懂,這是一個問題點!

設置 FFmpegKitConfig.setFontconfigConfigurationPath的作用是 https://github.com/arthenica/ffmpeg-kit/wiki/Tips 參考第四條:ffmpeg 需要有效的 fontconfig 配置才能在使用 drawtext filter 時渲染文本。

這里指定一個存在的字體路徑即可 比如:/system/fonts/NotoSansCJK-Regular.ttc

注意:有的字體不支持中文,寫入中文水印的時候會亂碼!


視頻處理性能測試(A133,Android 10)

測試環境

  • 設備平臺:A133
  • 操作系統:Android 10
  • 測試內容:視頻加水印 vs 無水印處理
  • 加水印幀率:15fps
  • 視頻格式:H.264 (寬高:720x576)(位率:512Kbps)

性能對比數據

視頻時長處理方式耗時(ms)耗時(秒)輸出文件大小
30s加水印52145.211.5M
30s加水印(15幀)38133.811.5M
30s不加水印1680.170.9M
60s加水印1201312.012.5M
60s加水印(15幀)73927.392.5M
60s不加水印2080.211.5M
120s加水印2200622.015.03M
120s加水印(15幀)1840418.405.03M
120s不加水印2770.282.8M
240s加水印5054750.5510.57M
240s加水印(15幀)3785737.8610.57M
240s不加水印4480.455.24M

在 A133 平臺上,加水印操作是性能瓶頸,視頻重編碼操作對cpu要求比較高。


補充

在低端設備使用FFmpeg處理視頻顯然是不推薦的,更是不明智的,除非無可選擇,可以選擇的替代方式為在手機或者在服務器進行視頻處理操作,這樣速度和體驗感更好。

在手機處理發現 不設置 FFmpegKitConfig.setFontconfigConfigurationPath也可以正常添加水印,這個操作應該是可有可無的!或者在特殊地方才會使用到它,有待發現。

開發中發現,只有full-gpl庫,才能進行加水印重編碼操作,其他庫均不行,沒辦法,只有一個加水印操作也要引入全功能,apk包體積大概增加13M左右,而且這只是在應用只支持arm64-v8a的情況下,多一個就翻一倍!

而且full-gpl:6.0-2最低要求sdk 24,如果你的應用之前最小sdk 小于23,然后改為24時你會發現,包體積大小劇增,這是因為minSdkVersion >= 23 默認不壓縮so 大小 ,導致apk體積會變大,大于23 就在清單文件的application標簽下設置 android:extractNativeLibs="true" 壓縮so ,就正常了。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/917621.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/917621.shtml
英文地址,請注明出處:http://en.pswp.cn/news/917621.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Flask + HTML 項目開發思路

Flask HTML 項目開發思路&#xff1a;以公共資源交易信息展示為例 一、開篇明義——為什么選 Flask 框架 在眾多 Python Web 框架&#xff08;如 Django、Tornado 等&#xff09;里&#xff0c;本次項目堅定選擇 Flask&#xff0c;背后有清晰的技術考量&#xff1a; 1. 輕量…

Vue中:deep()和 ::v-deep選擇器的區別

在 Vue.js 中&#xff0c;:deep()和 ::v-deep都是用于穿透組件作用域的深度選擇器&#xff0c;但它們在語法、適用場景和版本支持上存在區別。以下是兩者的核心差異&#xff1a;一、??語法與用法? &#xff1a;Vue2中用 ::v-deep&#xff0c;Vue2中不支持:deep()&#xff0c…

Deep learning based descriptor

1、DH3D: Deep Hierarchical 3D Descriptors for Robust Large-Scale 6DoF Relocalization 論文鏈接 代碼鏈接 這是一篇訓練點云的文章&#xff0c;在訓練出local descriptor之后&#xff0c;通過聚類的方法得出global descriptor&#xff0c;并且提出了hierarchical network&…

PandasAI連接LLM對MySQL數據庫進行數據分析

1. 引言 在之前的文章《PandasAI連接LLM進行智能數據分析》中實現了使用PandasAI連接與DeepSeek模型通過自然語言進行數據分析。不過那個例子中使用的是PandasAI 2.X&#xff0c;并且使用的是本地.csv文件來作為數據。在實際應用的系統中&#xff0c;使用.csv作為庫表的情況比…

FloodFill算法——DFS

FloodFill算法就是用來尋找性質相同的連通快的算法&#xff0c;這篇博客都是用dfs來實現FloodFill算法 1.圖像渲染 題目鏈接&#xff1a;733. 圖像渲染 - 力扣&#xff08;LeetCode&#xff09; 題目解析&#xff1a;將和&#xff08;sr,sc&#xff09;相連的所有像素相同的…

【BUUCTF系列】[極客大挑戰 2019]LoveSQL 1

本文僅用于技術研究&#xff0c;禁止用于非法用途。 Author:枷鎖 文章目錄一、題目核心漏洞分析二、關鍵解題步驟與技術解析1. 確定列數&#xff08;ORDER BY&#xff09;2. 聯合查詢獲取表名3. 爆破字段名4. 提取Flag三、漏洞根源與防御方案1. 漏洞成因2. 防御措施四、CTF技巧…

AI時代,童裝銷售的“指路明燈”

別看現在AI、大數據這些詞眼花繚亂的&#xff0c;當年我剛入行那會兒&#xff0c;也跟你一樣&#xff0c;對著一堆庫存和銷量數據發愁&#xff0c;不知道勁兒該往哪使。童裝銷售這行&#xff0c;看著簡單&#xff0c;其實水挺深。不過呢&#xff0c;這二十多年摸爬滾打下來&…

Swin-Transformer從淺入深詳解

第一部分&#xff1a;出現背景在 Swin Transformer 出現之前&#xff0c;計算機視覺&#xff08;Computer Vision, CV&#xff09;領域主要由 CNN (卷積神經網絡) 主導。后來&#xff0c;NLP&#xff08;自然語言處理&#xff09;領域的 Transformer 模型被引入 CV&#xff0c;…

如何手動打包 Linux(麒麟系統)的 Qt 程序

gcc版本 gcc版本確保目標系統&#xff08;運行環境&#xff09;的 GCC 版本 高于或等于開發環境的版本&#xff0c;否則程序無法在目標平臺運行。通過 gcc -v 可查看當前版本。cmake生成可執行文件 強烈建議在cmakelists添加設置運行時 rpath 為 $ORIGIN/…/lib&#xff08;相對…

解決 “crypto.hash is not a function”:Vite 從 6.x 升級至 7.x 后 `pnpm run dev` 報錯問題

&#x1f680; 作者主頁&#xff1a; 有來技術 &#x1f525; 開源項目&#xff1a; youlai-mall ︱vue3-element-admin︱youlai-boot︱vue-uniapp-template &#x1f33a; 倉庫主頁&#xff1a; GitCode︱ Gitee ︱ Github &#x1f496; 歡迎點贊 &#x1f44d; 收藏 ?評論 …

我的創作紀念日____在 CSDN一年來的成長歷程和收獲

365 天創作札記&#xff1a;在代碼與文字的褶皺里&#xff0c;遇見 1300 束光一年來。點開csdn網站后臺粉絲數的那一刻&#xff0c;1327 這個數字在屏幕上微微發燙。原來那些在深夜敲下的字符、調試到凌晨的代碼示例、反復修改的技術拆解&#xff0c;真的在時光里悄悄織成了一張…

VirtualBox 的 HOST 鍵(主機鍵)是 右Ctrl 鍵(即鍵盤右側的 Ctrl 鍵)筆記250802

VirtualBox 的 HOST 鍵&#xff08;主機鍵&#xff09;是 右Ctrl 鍵&#xff08;即鍵盤右側的 Ctrl 鍵&#xff09;筆記250802 VirtualBox 的 HOST 鍵&#xff08;主機鍵&#xff09;是什么?HOST鍵 是 右Ctrl 鍵VirtualBox 的 主機鍵&#xff08;Host Key&#xff09; 是一個…

Zama的使命

全同態加密&#xff08;Fully Homomorphic Encryption&#xff0c;FHE&#xff09;實現互聯網端到端加密的使命的重要里程碑。(FHE) 是一種無需解密即可處理數據的技術。它可用于在公共、無需許可的區塊鏈上創建私人智能合約&#xff0c;只有特定用戶才能看到交易數據和合約狀態…

Go語言流式輸出技術實現-服務器推送事件(Server-Sent Events, SSE)

目錄引言背景與技術概述實現技術細節1. HTTP 頭部配置2. 事件格式與發送3. 保持連接與刷新4. 處理連接關閉4.1 使用上下文管理連接生命周期4.2 使用通道管理客戶端連接5. 客戶端交互6.demo7.Go轉發大模型流式輸出demo引言 服務器推送事件&#xff08;Server-Sent Events, SSE&…

高端房產管理小程序

系統介紹1、用戶端地圖找房&#xff1a;對接地圖API&#xff0c;地圖形式顯示周邊房源,支持新盤和租房兩種模式查詢房價走勢&#xff1a;城市房價走勢&#xff0c;由后臺每月錄入房源搜索&#xff1a;搜索房源&#xff0c;支持多維度篩選房源類型&#xff1a;新盤銷售、房屋租賃…

文本轉語音(TTS)腳本

文本轉語音(TTS)腳本 概述 generate_voice.py 是一個用于生成語音的Python腳本。該腳本提供了文本轉語音(TTS)功能&#xff0c;可以將文本內容轉換為語音文件。 功能特性 文本轉語音: 將輸入的文本轉換為語音文件多種語音選項: 支持不同的語音類型和參數批量處理: 可以處理多個…

磁盤管理與分區

磁盤管理 一、磁盤類型 SATA,SCSI,SAS類型的磁盤&#xff0c;在Linux中用sd來表示。 其中第一塊硬盤為sda&#xff0c;第二塊二sdb&#xff0c;以此類推。 第一塊硬盤的第一個分區為sda1。 nvme類型的磁盤&#xff0c;在Linux中使用nvmeXnYpZ進行表示。 X&#xff1a;數字&…

Linux 邏輯卷管理

練習創建物理卷(pv->vg->lv)物理卷&#xff08;PV&#xff09;就像把一塊塊獨立的硬盤&#xff0c;標記成 "可用于搭建 LVM 的積木"&#xff0c;讓系統知道這些硬盤可以被 LVM 管理。#把sdb這塊硬盤標記為物理卷&#xff08;相當于給這塊積木蓋章&#xff0c;說…

向日葵參考基因組

向日葵參考基因組升級多個版本 向日葵基因組為油脂代謝、開花調控及菊類植物進化提供新見解-文獻精讀151-CSDN博客 官網 https://www.sunflowergenome.org/annotations-data/

什么是爬蟲協議?

什么是爬蟲協議&#xff1f; 爬蟲協議&#xff08;Crawl Protocol&#xff09;是指為了有效地收集網頁內容而建立的一些規定和標準&#xff0c;用以指導網絡爬蟲如何在互聯網上抓取信息。 爬蟲協議主要指的是Robots協議&#xff08;Robots Exclusion Protocol&#xff09;&am…