ffmpeg實現視頻流抽幀

ffmpeg 實現視頻流抽幀

抽取實時視頻幀

如果你的實時視頻是通過 RTSP、UDP 或其他協議獲取的,可以直接調用 FFmpeg 命令來抽取幀。

ffmpeg 命令

示例 1

ffmpeg -i rtsp://your_rtsp_stream_url -vf fps=1 -update 1 output.jpg

說明:

  • -i rtsp://your_rtsp_stream_url:指定輸入的實時視頻流 URL。
  • -vf fps=1:使用視頻濾鏡,每秒抽取 1 幀(可根據需要調整幀率,例如 fps=1/5 表示每 5 秒抽取一幀)。
  • -update 1 output.jpg:參數 -update 1 表示不斷用最新的幀更新同一個輸出文件(output.jpg),適合用于監控場景;如果需要保存多張圖片,則可以使用類似 output_%04d.jpg 的命名格式保存為連續文件。

示例 2

ffmpeg -i "rtmp://ns8.indexforce.com/home/mystream" -vf fps=1 "frame_%03d.jpg"

說明:

  • -i "rtsp://your_rtsp_stream_url":指定 RTSP 視頻流的 URL。
  • -vf fps=1:設置幀率,每秒抽取一幀。您可以根據需要調整此值,例如 fps=1/5 表示每 5 秒抽取一幀。
  • "frame_%03d.jpg":指定輸出的圖像文件名,%03d 表示編號,生成的文件名將依次為 frame_001.jpgframe_002.jpg 等。

示例 3

ffmpeg -i "rtmp://ns8.indexforce.com/home/mystream" -ss 1 -frames:v 1 "C:\Users\26913\Videos\ffmpeg-img\frame.jpg"

說明:

  • 從指定的 RTSP 流中讀取數據,并只輸出一幀圖像,保存到 C:\Users\26913\Videos\ffmpeg-img 目錄下,文件名為 frame.jpg
  • -ss 1:表示設置時間偏移量為 1 秒。也就是說,從視頻的第 1 秒處開始處理。對于抽幀來說,FFmpeg 會在視頻的 1 秒處截取當前幀。
    • 不加這個參數的話,會獲取視頻開頭的第一幀。
    • 若視頻流開頭是黑屏或加載幀,可能會影響抓取效果。
    • 效率較低,因為 FFmpeg 需要解析部分流的關鍵幀來決定輸出。

代碼示例

引入依賴

        <!-- 集成javacv --><dependency><groupId>org.bytedeco</groupId><artifactId>javacv-platform</artifactId><version>1.5.11</version></dependency><!-- 集成ffmpeg:https://mvnrepository.com/artifact/org.bytedeco/ffmpeg --><dependency><groupId>org.bytedeco</groupId><artifactId>ffmpeg</artifactId><version>7.1-1.5.11</version></dependency>

1、javacv 寫法

public class LiveStreamFrameExtractor {private static final Logger log = LoggerFactory.getLogger(LiveStreamFrameExtractor.class);/*** javacv實時抓取視頻幀*/public static void main(String[] args) {String streamUrl = VideoConstant.RTSP_URL_2;String outputDirPath = VideoConstant.FRAME_FILE_PREFIX;File outputDir = new File(outputDirPath);if (!outputDir.exists()) {outputDir.mkdirs();}// 使用 try-with-resources 自動管理資源try (FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(streamUrl);Java2DFrameConverter converter = new Java2DFrameConverter()) {// 啟動抓取器,開始實時視頻讀取grabber.start();int frameCount = 0;Frame frame;// 無限循環抓取實時視頻幀while ((frame = grabber.grabImage()) != null) {// 可根據需要添加實時顯示、處理等操作BufferedImage image = converter.convert(frame);if (image != null) {// 構造圖片輸出路徑,例如 live_frame_0001.jpgString outputFileName = outputDirPath + File.separator + String.format("live_frame_%04d.jpg", frameCount);File outputFile = new File(outputFileName);ImageIO.write(image, "jpg", outputFile);System.out.println("保存幀:" + frameCount + " 到文件:" + outputFileName);}frameCount++;// 根據抓取幀率或其他需求設置適當延時,避免過快抽幀TimeUnit.MILLISECONDS.sleep(50);if (frameCount > 5) {break;}}System.out.println("抓取結束,共抓取 " + frameCount + " 幀");// 停止抓取器grabber.stop();} catch (Exception e) {log.error("抓取視頻幀出錯:", e);}}
}

2、ffmpeg 命令寫法

@Slf4j
public class FfmpegProcess {static String rtspUrl = VideoConstant.RTSP_URL_1;static String streamOutputFile = VideoConstant.FRAME_FILE_PREFIX + File.separator + DateUtil.format(DateUtil.date(), "yyyyMMddHHmmss") + ".jpg";public static void main(String[] args) throws Exception {String command = getStreamFrameExtractionCommand(rtspUrl, streamOutputFile);System.out.println("執行命令: " + command);// 創建操作系統進程ProcessBuilder builder = new ProcessBuilder();// 執行命令executeCommand(builder, command, "windows");// 合并標準輸出和標準錯誤輸出流builder.redirectErrorStream(true);Process process = builder.start();// 異步讀取輸出流,避免阻塞CompletableFuture<Void> future = readOutputAsync(process.getInputStream());int exitCode = process.waitFor();if (exitCode == 0) {System.out.println("執行成功");} else {System.err.println("執行過程中出現錯誤,退出代碼:" + exitCode);}}/*** 獲取實時視頻流抽幀的命令(只抓取一張圖片)** @param url        視頻流 url,例如 rtsp 流地址* @param outputFile 輸出文件路徑* @return 實時視頻流抽幀的命令*/private static String getStreamFrameExtractionCommand(String url, String outputFile) {return String.format("%s -y -i %s -ss 1 -frames:v 1 %s", VideoConstant.FFMPEG_PATH, url, outputFile);}/*** 異步讀取 ffmpeg 輸出流*/private static CompletableFuture<Void> readOutputAsync(InputStream inputStream) {return CompletableFuture.runAsync(() -> {try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {String line;while ((line = reader.readLine()) != null) {System.out.println(line);}} catch (IOException e) {log.error("讀取 ffmpeg 輸出流異常", e);}});}/*** 執行命令** @param builder 進程構建器* @param command 命令* @param osType  操作系統類型*/private static void executeCommand(ProcessBuilder builder, String command, String osType) {switch (osType) {case "windows":builder.command("cmd", "/c", command);break;case "Linux":case "macOS":builder.command("bash", "-c", command);break;default:throw new RuntimeException("不支持的操作系統類型");}}
}

學習參考

  • https://blog.csdn.net/asialee_bird/article/details/129014872?utm_source=chatgpt.com
  • 公共有效rtmp、rtsp、m3u8、音頻視頻測試地址(2025.1.23更新)_公開的rtsp流媒體地址-CSDN博客

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

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

相關文章

【GIT】放棄”本地更改,恢復到遠程倉庫的狀態git fetch origin git reset --hard origin/分支名

如果你想完全放棄本地更改&#xff0c;恢復到遠程倉庫的狀態&#xff0c;可以按照以下步驟操作&#xff1a; 獲取遠程最新版本 首先執行&#xff1a; git fetch origin這條命令會把遠程倉庫的最新提交拉取到你的本地&#xff0c;但不會自動合并到你的當前分支。 硬重置你的當前…

flutter doctor 信號號超時

報錯如下&#xff1a; :\Users\Administrator>flutter doctor Doctor summary (to see all details, run flutter doctor -v): [√] Flutter (Channel stable, 3.27.4, on Microsoft Windows [版本 10.0.22631.5189], locale zh-CN) [√] Windows Version (Installed versi…

【Linux】系統入門

【Linux】系統初識 起源開源 閉源版本內核內核編號 Linux的安裝雙系統(不推薦)WindowsLinuxvmware虛擬機vitualbox操作系統的鏡像centos 7/ubuntu云服務器租用 Linux的操作lsmkdir 文件名pwdadduser userdel -rrm文件名cat /proc/cpuinfolinux支持編程vim code.c./a.out 運行程…

mybatis-plus整合springboot與使用方式

注解 TableField(exist false)&#xff1a;表示該屬性不為數據庫表字段&#xff0c;但又是必須使用的。 整合springboot pom <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xs…

[第十六屆藍橋杯 JavaB 組] 真題 + 經驗分享

A&#xff1a;逃離高塔(AC) 這題就是簡單的簽到題&#xff0c;按照題意枚舉即可。需要注意的是不要忘記用long&#xff0c;用int的話會爆。 &#x1f4d6; 代碼示例&#xff1a; import java.io.*; import java.util.*; public class Main {public static PrintWriter pr ne…

GPU服務器聲音很響可以怎么處理

當GPU服務器運行時噪音過大&#xff0c;通常是由于高負載下散熱風扇高速運轉所致。以下是分步驟的解決方案&#xff0c;幫助您有效降低噪音并保持設備穩定運行&#xff1a; 一、排查噪音來源 定位聲源 ? 使用 聲級計 或手機分貝檢測APP&#xff0c;確定最大噪音位置&#xff0…

STM32平衡車開發實戰教程:從零基礎到項目精通

STM32平衡車開發實戰教程&#xff1a;從零基礎到項目精通 一、項目概述與基本原理 1.1 平衡車工作原理 平衡車是一種基于倒立擺原理的兩輪自平衡小車&#xff0c;其核心控制原理類似于人類保持平衡的過程。當人站立不穩時&#xff0c;會通過腿部肌肉的快速調整來維持平衡。平…

C#設計模式-狀態模式

狀態模式案例解析&#xff1a;三態循環燈的實現 案例概述 本案例使用 狀態模式&#xff08;State Pattern&#xff09; 實現了一個 三態循環燈 的功能。每點擊一次按鈕&#xff0c;燈的狀態會按順序切換&#xff08;狀態1 → 狀態2 → 狀態3 → 狀態1...&#xff09;&#xff…

Mac系統升級node.js版本和npm版本并安裝pnpm

1.升級node.js版本 第一步&#xff1a;查詢當前node.js版本 node -v第二步&#xff1a;清除node.js的緩存 sudo npm cache clean -f第三步&#xff1a;驗證緩存是否清空 npm cache verify第四步&#xff1a;安裝n工具&#xff0c;n工具是專門用于管理node.js版本的工具 su…

[net 5] udp_dict_server 基于udp的簡單字典翻譯(服務器與業務相分離)

目錄 1. 功能了解 1.1. 啥是 dic_server? 1.2. dic_server 的小目標 2. 基本框架 2.1. 基本文件框架 2.2. 業務與服務器解耦 -> 回調函數 3. 字典 3.1. 字典配置文件 3.2. 構建字典類 3.2.1. 字典類的基本成員 3.2.2. 字典類構造 3.2.2.1. 構造 3.2.2.2. 信息加…

七種驅動器綜合對比——《器件手冊--驅動器》

九、驅動器 名稱 功能與作用 工作原理 優勢 應用 隔離式柵極驅動器 隔離式柵極驅動器用于控制功率晶體管&#xff08;如MOSFET、IGBT、SiC或GaN等&#xff09;的開關&#xff0c;其核心功能是將控制信號從低壓側傳輸到高壓側的功率器件柵極&#xff0c;同時在輸入和輸出之…

EM儲能網關ZWS智慧儲能云應用(8) — 電站差異化支持

面對不同項目、種類繁多的儲能產品&#xff0c;如何在儲能云平臺上進行電站差異化支持尤為關鍵&#xff0c;ZWS智慧儲能云從多方面支持儲能電站差異化。 簡介 隨著行業發展&#xff0c;市場“內卷”之下&#xff0c;各大儲能企業推陳出新的速度加快。面對不同項目、種類繁多…

圖像預處理-色彩空間補充,灰度化與二值化

一.圖像色彩空間轉換 1.1 HSV顏色空間 HSV顏色空間使用色調&#xff08;Hue&#xff09;、飽和度&#xff08;Saturation&#xff09;和亮度&#xff08;Value&#xff09;三個參數來表示顏色 一般對顏色空間的圖像進行有效處理都是在HSV空間進行的&#xff0c;然后對于基本…

Midnight Flag CTF 2025

周末還是三個比賽&#xff0c;可惜不好弄。不是遠端連不上就是遠端打不開。再有就是太難了。 Crypto ABC 這個題還是不算難的。給了兩個30位數的平方和&#xff0c;并且pu1*baser0,qu2*baser1其中r 都很小&#xff0c;可以copper。 只是sage里的two_squres不管用&#xff0…

深度學習--激活函數

激活函數通過計算加權和并加上偏置來確定神經元是否應該倍激活&#xff0c;它們將輸入信號轉換為輸出的可微運算。大多數激活函數都是非線性的&#xff0c;由于激活函數是深度學習的基礎&#xff0c;下面簡要介紹一些常見的激活函數。 1 RelU函數 最受歡迎的激活函數是修正線性…

深入解析 OrdinalEncoder 與 OneHotEncoder:核心區別與實戰應用

標題&#xff1a;深入解析 OrdinalEncoder 與 OneHotEncoder&#xff1a;核心區別與實戰應用 摘要&#xff1a; 本文詳細探討了機器學習中類別特征編碼的兩種核心方法——OrdinalEncoder 和 OneHotEncoder。通過對比兩者的功能、特點、適用場景及代碼實現&#xff0c;幫助讀者…

CTF web入門之命令執行 完整版

web29 文件名過濾 由于flag被過濾,需要進行文件名繞過,有以下幾種方法: 1.通配符繞過 fla?.* 2.反斜杠繞過 fl\ag.php 3.雙引號繞過 fl’‘ag’.php 還有特殊變量$1、內聯執行等 此外 讀取文件利用cat函數,輸出利用system、passthru 、echo echo `nl flag.php`; ec…

【Linux實踐系列】:用c/c++制作一個簡易的進程池

&#x1f525; 本文專欄&#xff1a;Linux Linux實踐項目 &#x1f338;作者主頁&#xff1a;努力努力再努力wz &#x1f4aa; 今日博客勵志語錄&#xff1a; 人生沒有標準答案&#xff0c;你的錯題本也能寫成傳奇。 ★★★ 本文前置知識&#xff1a; 匿名管道 1.前置知識回顧…

2.2 函數返回值

1.回顧def def sum(x,y): return xy res sum(10,20) #調用函數 print(res) 2.函數的三個重要屬性 -函數的類型&#xff1a;function -函數的ID&#xff1a;16進制的整數數值 -函數的值&#xff1a;封裝在函數中的數據和代碼 # - 函數是一塊內存空間&#xff0c;通過…

【3GPP核心網】【5G】精講5G網絡語音業務系統架構

1. 歡迎大家訂閱和關注,精講3GPP通信協議(2G/3G/4G/5G/IMS)知識點,專欄會持續更新中.....敬請期待! 目錄 1. 音視頻業務 2. 消息類業務 SMS over IMS SMS over NAS 3. 互聯互通架構 3.1 音視頻業務互通場景 3.2 5G 用戶與 5G 用戶互通 3.3 5G 用戶與 4G 用戶的互通…