基于FFmpeg使用C#和C++開發
以下是一些基于FFmpeg使用C#和C++開發的簡單屏幕錄制軟件示例,涵蓋不同平臺和功能需求。這些示例可作為學習或項目開發的起點。
使用C++開發FFmpeg屏幕錄制
基礎屏幕錄制(Windows)
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <Windows.h>int main() {AVFormatContext* formatContext = nullptr;avformat_alloc_output_context2(&formatContext, nullptr, "flv", "output.flv");// 配置視頻流(使用GDI抓屏)AVStream* stream = avformat_new_stream(formatContext, nullptr);stream->codecpar->codec_id = AV_CODEC_ID_H264;stream->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;stream->codecpar->width = GetSystemMetrics(SM_CXSCREEN);stream->codecpar->height = GetSystemMetrics(SM_CYSCREEN);stream->codecpar->format = AV_PIX_FMT_BGR0;avio_open(&formatContext->pb, formatContext->filename, AVIO_FLAG_WRITE);avformat_write_header(formatContext, nullptr);// 模擬抓幀(實際需用GDI/DXGI)AVPacket pkt;av_new_packet(&pkt, 0);av_write_frame(formatContext, &pkt);av_write_trailer(formatContext);avio_closep(&formatContext->pb);
}
使用DXGI抓屏(高性能)
#include <dxgi.h>
#include <d3d11.h>
// 需結合FFmpeg的硬件加速編碼(如h264_nvenc)
Linux X11屏幕錄制
#include <X11/Xlib.h>
// 使用XGetImage抓屏后通過FFmpeg編碼
使用C#開發FFmpeg屏幕錄制
通過Process調用FFmpeg
using System.Diagnostics;Process.Start("ffmpeg", "-f gdigrab -i desktop -c:v libx264 output.mp4");
使用FFmpeg.AutoGen(原生封裝)
using FFmpeg.AutoGen;public unsafe class Recorder {public void Start() {AVFormatContext* fmtCtx = null;ffmpeg.avformat_alloc_output_context2(&fmtCtx, null, "mp4", "output.mp4");// 配置視頻流參數AVStream* stream = ffmpeg.avformat_new_stream(fmtCtx, null);AVCodecParameters* codecpar = stream->codecpar;codecpar->codec_id = AVCodecID.AV_CODEC_ID_H264;codecpar->width = 1920;codecpar->height = 1080;}
}
結合AForge.NET抓屏
using AForge.Video.DirectShow;
// 通過ScreenCaptureStream獲取幀后傳給FFmpeg編碼
功能擴展示例
錄制系統音頻
ffmpeg -f dshow -i audio="麥克風" -f gdigrab -i desktop output.mkv
區域錄制
Process.Start("ffmpeg", "-f gdigrab -offset_x 100 -offset_y 200 -video_size 1280x720 -i desktop -c:v libx264 region.mp4");
硬件加速錄制(NVIDIA)
av_dict_set(&opts, "preset", "fast", 0);
av_dict_set(&opts, "c:v", "h264_nvenc", 0);
其他語言/平臺示例
Python調用FFmpeg
import subprocess
subprocess.run(["ffmpeg", "-f", "avfoundation", "-i", "1", "output.mov"]) # macOS
Electron桌面應用
const { exec } = require('child_process');
exec('ffmpeg -f x11grab -i :0.0 output.mp4');
關鍵注意事項
- 分辨率設置:需與顯示器實際分辨率匹配
- 幀率控制:通過
-r
參數指定(如-r 30
) - 編碼選擇:
- 軟件編碼:
libx264
(CPU) - 硬件編碼:
h264_nvenc
(NVIDIA)、h264_amf
(AMD)
- 軟件編碼:
- 內存管理:C++示例需手動釋放FFmpeg資源
完整項目建議參考:
- ScreenRecorderLib(C#庫)
- QtFFmpegScreenRecorder(C++/Qt實現)
- OBS Studio開源代碼(高級參考)
基于C++和FFmpeg的移動端開發實例
以下是一些基于C++和FFmpeg的移動端開發實例,涵蓋音視頻處理、編解碼、流媒體等常見場景。所有示例均適配Android/iOS平臺,代碼結構簡潔,適合快速實現功能集成。
音視頻基礎處理
解碼本地視頻文件
使用avformat_open_input
和avcodec_send_packet
實現視頻解碼,輸出YUV幀數據:
AVFormatContext* fmt_ctx = nullptr;
avformat_open_input(&fmt_ctx, input_path, nullptr, nullptr);
AVCodecContext* codec_ctx = avcodec_alloc_context3(decoder);
avcodec_parameters_to_context(codec_ctx, fmt_ctx->streams[video_index]->codecpar);
avcodec_open2(codec_ctx, decoder, nullptr);
提取音頻PCM數據
通過swr_convert
將音頻重采樣為PCM格式:
SwrContext* swr = swr_alloc_set_opts(nullptr, out_ch_layout, out_sample_fmt, out_sample_rate,in_ch_layout, in_sample_fmt, in_sample_rate, 0, nullptr);
swr_convert(swr, &out_buffer, out_samples, (const uint8_t**)in_buffer, in_samples);
高級功能實現
視頻實時濾鏡
應用FFmpeg濾鏡鏈實現色彩調整(需鏈接libavfilter
):
AVFilterContext* buffersrc = avfilter_graph_alloc_filter(graph, buffersrc_c, "src");
avfilter_graph_create_filter(&buffersink, buffersink_c, "sink", nullptr, nullptr, graph);
AVFilterInOut* outputs = avfilter_inout_alloc();
outputs->name = av_strdup("in");
outputs->filter_ctx = buffersrc;
硬件加速解碼
Android上使用MediaCodec硬解(NDK集成):
AVBufferRef* hw_device_ctx = nullptr;
av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_MEDIACODEC, nullptr, nullptr, 0);
codec_ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);
流媒體與網絡
RTMP直播推流
配置輸出流并發送數據包:
AVOutputFormat* ofmt = av_guess_format("flv", nullptr, nullptr);
avformat_alloc_output_context2(&out_fmt_ctx, ofmt, nullptr, rtmp_url);
avio_open(&out_fmt_ctx->pb, out_fmt_ctx->filename, AVIO_FLAG_WRITE);
avformat_write_header(out_fmt_ctx, nullptr);
av_interleaved_write_frame(out_fmt_ctx, &pkt);
HLS切片生成
設置分段參數并生成m3u8文件:
AVDictionary* opts = nullptr;
av_dict_set(&opts, "hls_time", "10", 0);
av_dict_set(&opts, "hls_list_size", "6", 0