FFmpeg錄制屏幕和音頻

一、FFmpeg命令行實現錄制屏幕和音頻

1、Windows 示例

#include <cstdlib>
#include <string>
#include <iostream>int main() {// FFmpeg 命令行(錄制屏幕 + 麥克風音頻)std::string command = "ffmpeg -f gdigrab -framerate 30 -i desktop "          // 屏幕捕獲(GDI)"-f dshow -i audio=\"麥克風 (Realtek Audio)\" "       // 音頻設備(需替換為你的設備名)"-c:v libx264 -preset ultrafast -crf 18 "             // 視頻編碼(H.264)"-c:a aac -b:a 192k "                                 // 音頻編碼(AAC)"-pix_fmt yuv420p "                                   // 兼容性格式"output.mp4";                                         // 輸出文件std::cout << "開始錄制(按 Ctrl+C 停止)..." << std::endl;int ret = system(command.c_str());if (ret == 0) {std::cout << "錄制完成!保存為 output.mp4" << std::endl;} else {std::cerr << "錄制失敗!錯誤碼: " << ret << std::endl;}return 0;
}

僅僅錄制視頻:

ffmpeg -f gdigrab -framerate 30 -i desktop -vcodec libx264 -pix_fmt yuv420p output.mp4

2、Linux 示例

std::string command ="ffmpeg -f x11grab -framerate 30 -video_size 1920x1080 -i :0.0 "  // X11 屏幕捕獲"-f alsa -i default "                                              // ALSA 音頻輸入"-c:v libx264 -preset ultrafast -crf 18 ""-c:a aac -b:a 192k ""output.mp4";

?3、macOS 示例

std::string command ="ffmpeg -f avfoundation -framerate 30 -i \"1:0\" "        // 屏幕+音頻捕獲"-c:v libx264 -preset ultrafast -crf 18 ""-c:a aac -b:a 192k ""output.mp4";

關鍵參數說明

參數說明
-f gdigrabWindows 屏幕捕獲驅動
-f x11grabLinux 屏幕捕獲驅動
-f avfoundationmacOS 屏幕/音頻捕獲驅動
-i desktop捕獲整個屏幕(Windows)
-i :0.0Linux 主顯示器(X11)
-f dshow -i audio="..."Windows 音頻設備名(通過?ffmpeg -list_devices true -f dshow -i dummy?查詢)
-f alsa -i defaultLinux 默認音頻輸入
-c:v libx264H.264 視頻編碼
-preset ultrafast編碼速度優化(犧牲壓縮率)
-crf 18視頻質量(18~28,值越小質量越高)
-c:a aacAAC 音頻編碼
-b:a 192k音頻比特率(192kbps)

4、高級功能

1)錄制特定窗口(Windows)

// 替換 -i desktop 為窗口標題(模糊匹配)
std::string command = "ffmpeg -f gdigrab -framerate 30 -i title=\"Chrome\" output.mp4";

2)硬件加速(NVIDIA/Intel)

// NVIDIA NVENC
std::string command = "ffmpeg -f gdigrab -framerate 30 -i desktop -c:v h264_nvenc -preset p7 -tune hq output.mp4";// Intel QuickSync
std::string command = "ffmpeg -f gdigrab -framerate 30 -i desktop -c:v h264_qsv -preset faster output.mp4";

?3)僅錄制音頻

// Windows
std::string command = "ffmpeg -f dshow -i audio=\"麥克風 (Realtek Audio)\" -c:a aac audio.m4a";// Linux
std::string command = "ffmpeg -f alsa -i default -c:a aac audio.m4a";

4)設備名稱:Windows 需通過?ffmpeg -list_devices true -f dshow -i dummy?查詢正確的音頻設備名。
5)權限問題:Linux/macOS 可能需要?sudo?或音頻組權限。
6)性能優化:高分辨率錄制建議使用硬件加速(如?h264_nvenc)。

二、FFmpeg庫實現錄制屏幕和音頻

1、?初始化 FFmpeg

#include <iostream>
#include <string>
extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavdevice/avdevice.h>
#include <libswscale/swscale.h>
}int main() {// 初始化 FFmpegavdevice_register_all(); // 注冊設備輸入(屏幕、麥克風等)avformat_network_init();// ... 后續代碼return 0;
}

2、捕獲屏幕(Windows 使用?gdigrab

AVFormatContext* screenFormatCtx = nullptr;
AVDictionary* screenOptions = nullptr;// 設置屏幕捕獲參數(Windows GDI)
av_dict_set(&screenOptions, "framerate", "30", 0);      // 幀率
av_dict_set(&screenOptions, "offset_x", "0", 0);        // 起始 X 坐標
av_dict_set(&screenOptions, "offset_y", "0", 0);        // 起始 Y 坐標
av_dict_set(&screenOptions, "video_size", "1920x1080", 0); // 分辨率// 打開屏幕輸入流
if (avformat_open_input(&screenFormatCtx, "desktop", av_find_input_format("gdigrab"), &screenOptions) < 0) {std::cerr << "無法打開屏幕輸入!" << std::endl;return -1;
}// 查找視頻流
if (avformat_find_stream_info(screenFormatCtx, nullptr) < 0) {std::cerr << "無法獲取屏幕流信息!" << std::endl;return -1;
}

3、捕獲音頻(Windows 使用?dshow

AVFormatContext* audioFormatCtx = nullptr;
AVDictionary* audioOptions = nullptr;// 設置音頻設備(需替換為你的設備名)
av_dict_set(&audioOptions, "sample_rate", "44100", 0);  // 采樣率
av_dict_set(&audioOptions, "channels", "2", 0);         // 聲道數// 打開音頻輸入流
if (avformat_open_input(&audioFormatCtx, "audio=麥克風 (Realtek Audio)", av_find_input_format("dshow"), &audioOptions) < 0) {std::cerr << "無法打開音頻輸入!" << std::endl;return -1;
}// 查找音頻流
if (avformat_find_stream_info(audioFormatCtx, nullptr) < 0) {std::cerr << "無法獲取音頻流信息!" << std::endl;return -1;
}

?4、創建輸出文件(MP4 封裝)

AVFormatContext* outputFormatCtx = nullptr;
avformat_alloc_output_context2(&outputFormatCtx, nullptr, nullptr, "output.mp4");// 添加視頻流(H.264)
AVStream* videoStream = avformat_new_stream(outputFormatCtx, nullptr);
AVCodecParameters* videoCodecParams = videoStream->codecpar;
videoCodecParams->codec_id = AV_CODEC_ID_H264;
videoCodecParams->codec_type = AVMEDIA_TYPE_VIDEO;
videoCodecParams->width = 1920;
videoCodecParams->height = 1080;
videoCodecParams->format = AV_PIX_FMT_YUV420P;// 添加音頻流(AAC)
AVStream* audioStream = avformat_new_stream(outputFormatCtx, nullptr);
AVCodecParameters* audioCodecParams = audioStream->codecpar;
audioCodecParams->codec_id = AV_CODEC_ID_AAC;
audioCodecParams->codec_type = AVMEDIA_TYPE_AUDIO;
audioCodecParams->sample_rate = 44100;
audioCodecParams->channels = 2;
audioCodecParams->channel_layout = AV_CH_LAYOUT_STEREO;// 打開輸出文件
if (avio_open(&outputFormatCtx->pb, "output.mp4", AVIO_FLAG_WRITE) < 0) {std::cerr << "無法打開輸出文件!" << std::endl;return -1;
}// 寫入文件頭
if (avformat_write_header(outputFormatCtx, nullptr) < 0) {std::cerr << "無法寫入文件頭!" << std::endl;return -1;
}

5、循環讀取音視頻幀并寫入文件

AVPacket packet;
while (true) {// 讀取視頻幀if (av_read_frame(screenFormatCtx, &packet) >= 0) {av_packet_rescale_ts(&packet, screenFormatCtx->streams[packet.stream_index]->time_base, videoStream->time_base);packet.stream_index = videoStream->index;av_interleaved_write_frame(outputFormatCtx, &packet);av_packet_unref(&packet);}// 讀取音頻幀if (av_read_frame(audioFormatCtx, &packet) >= 0) {av_packet_rescale_ts(&packet, audioFormatCtx->streams[packet.stream_index]->time_base, audioStream->time_base);packet.stream_index = audioStream->index;av_interleaved_write_frame(outputFormatCtx, &packet);av_packet_unref(&packet);}// 按 Ctrl+C 停止錄制if (GetAsyncKeyState(VK_ESCAPE) {break;}
}// 寫入文件尾
av_write_trailer(outputFormatCtx);

6、釋放資源

avformat_close_input(&screenFormatCtx);
avformat_close_input(&audioFormatCtx);
avio_closep(&outputFormatCtx->pb);
avformat_free_context(outputFormatCtx);

7、示例代碼(window)

#include <iostream>
#include <Windows.h>
extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavdevice/avdevice.h>
}int main() {// 初始化 FFmpegavdevice_register_all();avformat_network_init();// 1. 打開屏幕輸入AVFormatContext* screenFormatCtx = nullptr;AVDictionary* screenOptions = nullptr;av_dict_set(&screenOptions, "framerate", "30", 0);av_dict_set(&screenOptions, "video_size", "1920x1080", 0);if (avformat_open_input(&screenFormatCtx, "desktop", av_find_input_format("gdigrab"), &screenOptions) < 0) {std::cerr << "無法打開屏幕輸入!" << std::endl;return -1;}// 2. 打開音頻輸入AVFormatContext* audioFormatCtx = nullptr;AVDictionary* audioOptions = nullptr;av_dict_set(&audioOptions, "sample_rate", "44100", 0);av_dict_set(&audioOptions, "channels", "2", 0);if (avformat_open_input(&audioFormatCtx, "audio=麥克風 (Realtek Audio)", av_find_input_format("dshow"), &audioOptions) < 0) {std::cerr << "無法打開音頻輸入!" << std::endl;return -1;}// 3. 創建輸出文件AVFormatContext* outputFormatCtx = nullptr;avformat_alloc_output_context2(&outputFormatCtx, nullptr, nullptr, "output.mp4");// 4. 寫入音視頻流AVStream* videoStream = avformat_new_stream(outputFormatCtx, nullptr);AVStream* audioStream = avformat_new_stream(outputFormatCtx, nullptr);// 5. 循環讀取幀并寫入文件AVPacket packet;while (!GetAsyncKeyState(VK_ESCAPE)) {// 讀取視頻幀if (av_read_frame(screenFormatCtx, &packet) >= 0) {av_packet_rescale_ts(&packet, screenFormatCtx->streams[packet.stream_index]->time_base, videoStream->time_base);packet.stream_index = videoStream->index;av_interleaved_write_frame(outputFormatCtx, &packet);av_packet_unref(&packet);}// 讀取音頻幀if (av_read_frame(audioFormatCtx, &packet) >= 0) {av_packet_rescale_ts(&packet, audioFormatCtx->streams[packet.stream_index]->time_base, audioStream->time_base);packet.stream_index = audioStream->index;av_interleaved_write_frame(outputFormatCtx, &packet);av_packet_unref(&packet);}}// 6. 釋放資源avformat_close_input(&screenFormatCtx);avformat_close_input(&audioFormatCtx);avio_closep(&outputFormatCtx->pb);avformat_free_context(outputFormatCtx);std::cout << "錄制完成!保存為 output.mp4" << std::endl;return 0;
}

三、總結

方法適用場景優點缺點
FFmpeg 命令行快速開發簡單依賴外部進程
libavformat/libavcodec高性能、精細控制直接操作音視頻流代碼復雜

推薦

  • 快速開發?→ 直接調用?ffmpeg?命令行。

  • 高性能/嵌入式?→ 使用 FFmpeg 庫(如?libavformat)。

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

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

相關文章

【數據集】多視圖文本數據集

多視圖文本數據集指的是包含多個不同類型或來源的信息的文本數據集。不同視圖可以來源于不同的數據模式&#xff08;如原始文本、元數據、網絡結構等&#xff09;&#xff0c;或者不同的文本表示方法&#xff08;如 TF-IDF、詞嵌入、主題分布等&#xff09;。這些數據集常用于多…

C++ 繼承方式使用場景(極簡版)

1. 公有繼承&#xff08;public&#xff09; 什么時候用&#xff1f; “是一個”&#xff08;is-a&#xff09;關系&#xff1a;派生類 是 基類的一種。 例&#xff1a;class Dog : public Animal&#xff08;狗是動物&#xff09; 最常見&#xff0c;90%的繼承都用它。 2. 保…

Ubuntu 系統 Docker 中搭建 CUDA cuDNN 開發環境

CUDA 是 NVIDIA 推出的并行計算平臺和編程模型&#xff0c;利用 GPU 多核心架構加速計算任務&#xff0c;廣泛應用于深度學習、科學計算等領域。cuDNN 是基于 CUDA 的深度神經網絡加速庫&#xff0c;為深度學習框架提供高效卷積、池化等操作的優化實現&#xff0c;提升模型訓練…

高密度任務下的挑戰與破局:數字樣機助力火箭發射提效提質

2025年4月1日12時&#xff0c;在酒泉衛星發射中心&#xff0c;長征二號丁運載火箭順利升空&#xff0c;成功將一顆衛星互聯網技術試驗衛星送入預定軌道&#xff0c;發射任務圓滿完成。這是長征二號丁火箭的第97次發射&#xff0c;也是長征系列火箭的第567次發射。 執行本次任務…

關于SQL子查詢的使用策略

在 SQL 優化中&#xff0c;一般遵循**“非必要不使用子查詢”**的原則&#xff0c;因為子查詢可能會帶來額外的計算開銷&#xff0c;影響查詢效率。但是&#xff0c;并不是所有子查詢都需要避免&#xff0c;有時子查詢是最優解&#xff0c;具體要根據實際場景選擇合適的優化方式…

JavaEE初階復習(JVM篇)

JVM Java虛擬機 jdk java開發工具包 jre java運行時環境 jvm java虛擬機(解釋執行 java 字節碼) java作為一個半解釋,半編譯的語言,可以做到跨平臺. java 通過javac把.java文件>.class文件(字節碼文件) 字節碼文件, 包含的就是java字節碼, jvm把字節碼進行翻譯轉化為…

2.pycharm保姆級安裝教程

一、pycharm安裝 1.官網上下載好好軟&#xff0c;雙擊打開 2.下一步 3.修改路徑地址 (默認也可以) 4.打勾 5.安裝 不用重啟電腦 二、添加解釋器 1.雙擊軟件&#xff0c;打開 2.projects – new project 3.指定項目名字&#xff0c;項目保存地址&#xff0c;解釋器 4.右擊 – …

zk基礎—4.zk實現分布式功能二

大綱 1.zk實現數據發布訂閱 2.zk實現負載均衡 3.zk實現分布式命名服務 4.zk實現分布式協調(Master-Worker協同) 5.zk實現分布式通信 6.zk實現Master選舉 7.zk實現分布式鎖 8.zk實現分布式隊列和分布式屏障 4.zk實現分布式協調(Master-Worker協同) (1)Master-Worker架構…

Java 實現 字母異位詞分組

在這篇博客中&#xff0c;我們將詳細解析如何使用 Java 代碼來解決 字母異位詞分組這個經典的算法問題。我們會逐步分析代碼邏輯&#xff0c;并探討其時間復雜度及優化思路。 題目描述 給定一個字符串數組 strs&#xff0c;請將字母異位詞組合在一起。字母異位詞是指由相同字…

【Ragflow】10. 助理配置參數詳細解析/模型響應加速方法

概述 Ragflow的助理配置中&#xff0c;有很多參數&#xff0c;盡管官方文檔給出了一定程度的解釋&#xff0c;但不夠詳細。 本文將對各項參數進行更詳細的解釋說明&#xff0c;并進一步挖掘某些參數中隱含的潛在陷阱。 助理設置 空回復 含義&#xff1a;輸入的問題若未能在…

Mac Apple silicon如何指定運行amd64架構的ubuntu Docker?

如何指定運行amd64架構的ubuntu Docker 下面這個docker命令如何指定運行amd64架構的ubuntu Docker&#xff1f; docker run -it -v $(pwd):/workspace ubuntu:20.04 bash這個命令已經非常接近正確運行一個基于 amd64 架構的 Ubuntu 容器了&#xff0c;但如果你想明確指定運行…

ColPali:基于視覺語言模型的高效文檔檢索

摘要 文檔是視覺豐富的結構&#xff0c;不僅通過文本傳遞信息&#xff0c;還包括圖表、頁面布局、表格&#xff0c;甚至字體。然而&#xff0c;由于現代檢索系統主要依賴從文檔頁面中提取的文本信息來索引文檔&#xff08;通常是冗長且脆弱的流程&#xff09;&#xff0c;它們…

使用C++實現HTTP服務

天天開心&#xff01;&#xff01;&#xff01; 閱讀本篇文章之前&#xff0c;請先閱讀HTTP基礎知識 傳送門----> HTTP基礎知識 文章目錄 一、CWeb服務器&#xff08;核心代碼WebServer.cpp&#xff09;二、靜態文件結構三、編譯和運行四、訪問測試 一、CWeb服務器&#xff…

Reactive編程入門:Project Reactor 深度指南

文章目錄 4.2.1 創建 Flux 和 MonoFlux 基礎創建方式高級創建模式Mono 創建方式 4.2.2 訂閱與數據處理基礎訂閱模式數據處理操作符 4.2.3 核心操作符深度解析flatMap 操作符zip 操作符buffer 操作符 高級組合模式復雜流處理示例背壓處理策略 測試響應式流性能優化技巧 React 編…

【萬字總結】前端全方位性能優化指南(完結篇)——自適應優化系統、遺傳算法調參、Service Worker智能降級方案

前言 自適應進化宣言 當監控網絡精準定位病灶&#xff0c;真正的挑戰浮出水面&#xff1a;系統能否像生物般自主進化&#xff1f; 五維感知——通過設備傳感器實時捕獲環境指紋&#xff08;如地鐵隧道弱光環境自動切換省電渲染&#xff09; 基因調參——150個性能參數在遺傳算…

PQ以及有關索引的筆記Faiss: The Missing Manual

參考Faiss 索引結構總結&#xff1a; 為了加深記憶&#xff0c;介紹一下Inverted File Index&#xff08;IVF&#xff09;的名字由來&#xff1a; IVF索引的名字源自“倒排文件”&#xff08;Inverted File&#xff09;的概念。在傳統的信息檢索中&#xff0c;倒排文件是一種索…

win10徹底讓圖標不顯示在工具欄

關閉需要不顯示的軟件 打開 例此時我關閉了IDEA的顯示 如果說只是隱藏&#xff0c;鼠標拖動一個道理 例QQ 如果說全部顯示不隱藏

關稅核爆72小時!跨境矩陣防御戰緊急打響

一、T86崩塌&#xff1a;全球貿易鏈的至暗時刻 &#xff08;配圖&#xff1a;美國海關系統深夜彈出紅色警報&#xff09; 5月2日凌晨2:17&#xff0c;杭州某光伏企業的供應鏈系統突然發出刺耳警報——其價值1800萬美元的逆變器模塊被劃入34%關稅清單。這場代號"黑天鵝突…

藍橋杯Java B組省賽真題題型近6年統計分類

困難題 題號題型分值代碼量難度通過率內容2024-F解答1581困難0.12最短路問題 Dijkstra 期望2024-G解答20116困難0.19模擬 暴力 搜索 DFS 剪紙 枚舉2023-H解答2070困難0動態規劃2022-H解答20109困難0.032022-J解答25141困難0搜索2021-H解答2041困難0.18二分 思維 規律2021-I解答…

【網絡流 圖論建模 最大權閉合子圖】 [六省聯考 2017] 壽司餐廳

題目描述&#xff1a; P3749 [六省聯考 2017] 壽司餐廳 題目描述 Kiana 最近喜歡到一家非常美味的壽司餐廳用餐。 每天晚上&#xff0c;這家餐廳都會按順序提供 n n n 種壽司&#xff0c;第 i i i 種壽司有一個代號 a i a_i ai? 和美味度 d i , i d_{i, i} di,i?&…