Rust屏幕捕获库ScreenCaptureKit的使用,实现高效屏幕录制与截图功能
Rust屏幕捕获库ScreenCaptureKit的使用,实现高效屏幕录制与截图功能
以下是基于ScreenCaptureKit的Rust完整示例代码,展示如何实现屏幕录制和截图功能:
use screencapturekit::{
SCContentFilter, SCShareableContent, SCStream, SCStreamOutputType, SCStreamConfig,
SCPixelFormat, SCColorSpace
};
use std::{fs::File, sync::mpsc, time::Duration};
use image::{ImageBuffer, Rgba};
// 屏幕截图示例
fn capture_screenshot() -> Result<(), Box<dyn std::error::Error>> {
// 获取当前可用的屏幕内容
let available_content = SCShareableContent::current()?;
// 选择主显示器
let main_display = available_content.displays
.into_iter()
.find(|d| d.is_main)
.ok_or("主显示器未找到")?;
// 创建内容过滤器
let filter = SCContentFilter::new_display(main_display, false);
// 配置流参数
let config = SCStreamConfig {
width: main_display.width as u32,
height: main_display.height as u32,
pixel_format: SCPixelFormat::BGRA8888,
color_space: SCColorSpace::sRGB,
shows_cursor: true,
..Default::default()
};
// 创建通信通道
let (tx, rx) = mpsc::channel();
// 创建并配置流
let mut stream = SCStream::new(config)?;
stream.add_output(SCStreamOutputType::Screen, move |sample, error| {
if let Some(sample) = sample {
if let Some(buffer) = sample.get_sample_buffer() {
if let Some(image_buffer) = buffer.get_image_buffer() {
tx.send(image_buffer.clone()).unwrap();
}
}
}
if let Some(error) = error {
eprintln!("捕获错误: {:?}", error);
}
})?;
// 开始捕获
stream.start_capture()?;
// 等待并获取图像数据
let image_buffer = rx.recv_timeout(Duration::from_secs(5))?;
// 停止捕获
stream.stop_capture()?;
// 处理图像数据
let width = image_buffer.width as u32;
let height = image_buffer.height as u32;
let bytes_per_row = image_buffer.bytes_per_row as usize;
// 创建图像缓冲区
let image = ImageBuffer::<Rgba<u8>, _>::from_raw(width, height, {
let mut vec = Vec::with_capacity((width * height * 4) as usize);
for y in 0..height {
let start = (y * bytes_per_row as u32) as usize;
let end = start + (width * 4) as usize;
vec.extend_from_slice(&image_buffer.data[start..end]);
}
vec
}).ok_or("创建图像缓冲区失败")?;
// 保存为PNG文件
let mut file = File::create("screen_capture.png")?;
image.save(&mut file, image::ImageFormat::Png)?;
println!("屏幕截图已保存为screen_capture.png");
Ok(())
}
// 屏幕录制示例
fn screen_recording(duration_secs: u64) -> Result<(), Box<dyn std::error::Error>> {
// 获取可共享内容
let content = SCShareableContent::current()?;
let display = content.displays[0].clone();
// 配置录制参数
let config = SCStreamConfig {
width: display.width as u32,
height: display.height as u32,
pixel_format: SCPixelFormat::BGRA8888,
color_space: SCColorSpace::sRGB,
shows_cursor: true,
..Default::default()
};
// 创建流
let mut stream = SCStream::new(config)?;
// 添加输出处理器
stream.add_output(SCStreamOutputType::Screen, |sample, error| {
match sample {
Some(s) => println!("收到帧: {:?}", s),
None => {}
}
if let Some(e) = error {
eprintln!("录制错误: {:?}", e);
}
})?;
// 开始录制
stream.start_capture()?;
println!("开始屏幕录制...");
// 录制指定时长
std::thread::sleep(Duration::from_secs(duration_secs));
// 停止录制
stream.stop_capture()?;
println!("屏幕录制完成");
Ok(())
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 执行屏幕截图
capture_screenshot()?;
// 执行5秒屏幕录制
screen_recording(5)?;
Ok(())
}
代码说明
-
capture_screenshot函数:
- 获取当前屏幕内容
- 配置捕获参数(分辨率、像素格式等)
- 使用通道接收捕获的图像数据
- 将图像保存为PNG文件
-
screen_recording函数:
- 设置基本录制参数
- 启动屏幕录制
- 持续指定时长后停止
-
主要功能:
- 支持截图和录制两种模式
- 可配置分辨率、光标显示等参数
- 使用Rust的通道进行线程间通信
使用建议
- 在Cargo.toml中添加依赖:
[dependencies]
screencapturekit = "0.1"
image = "0.24"
-
需要先在系统设置中授予"屏幕录制"权限
-
该库仅支持macOS系统
1 回复
Rust屏幕捕获库ScreenCaptureKit的使用指南
ScreenCaptureKit是一个高效的Rust库,用于实现屏幕录制和截图功能。它提供了简单易用的API,可以捕获整个屏幕、特定窗口或屏幕的某个区域。
基本功能
- 捕获整个屏幕
- 捕获特定窗口
- 捕获屏幕的指定区域
- 录制屏幕视频
安装
在Cargo.toml中添加依赖:
[dependencies]
screen_capture_kit = "0.1.0"
基本使用方法
1. 捕获整个屏幕截图
use screen_capture_kit::{ScreenCapture, CaptureConfig};
fn main() {
// 创建ScreenCapture实例
let capture = ScreenCapture::new().unwrap();
// 配置捕获所有显示器
let config = CaptureConfig::default()
.capture_all_displays(true);
// 捕获图像并保存
let image = capture.capture_image(&config).unwrap();
image.save("screenshot.png").unwrap();
println!("截图已保存为 screenshot.png");
}
2. 捕获特定窗口
use screen_capture_kit::{ScreenCapture, CaptureConfig, WindowInfo};
fn main() {
let capture = ScreenCapture::new().unwrap();
// 获取所有窗口列表
let windows = capture.list_windows().unwrap();
for window in &windows {
println!("窗口: {} (ID: {})", window.title, window.window_id);
}
// 捕获第一个窗口
if let Some(window) = windows.first() {
let config = CaptureConfig::default()
.window_id(window.window_id);
let image = capture.capture_image(&config).unwrap();
image.save("window_capture.png").unwrap();
}
}
3. 捕获屏幕指定区域
use screen_capture_kit::{ScreenCapture, CaptureConfig, Rect};
fn main() {
let capture = ScreenCapture::new().unwrap();
// 定义捕获区域
let region = Rect {
x: 100,
y: 100,
width: 800,
height: 600,
};
let config = CaptureConfig::default()
.region(region);
let image = capture.capture_image(&config).unwrap();
image.save("region_capture.png").unwrap();
}
4. 屏幕录制
use screen_capture_kit::{ScreenCapture, CaptureConfig, RecorderConfig};
use std::time::Duration;
fn main() {
let capture = ScreenCapture::new().unwrap();
let config = CaptureConfig::default()
.capture_all_displays(true);
// 配置录制参数
let recorder_config = RecorderConfig::new("recording.mp4")
.fps(30)
.quality(85);
// 开始录制
let mut recorder = capture.start_recording(&config, &recorder_config).unwrap();
// 录制5秒
std::thread::sleep(Duration::from_secs(5));
// 停止录制
recorder.stop().unwrap();
println!("录制已保存为 recording.mp4");
}
高级功能
带回调的实时捕获
use screen_capture_kit::{ScreenCapture, CaptureConfig, FrameHandler};
// 自定义帧处理器
struct MyHandler;
impl FrameHandler for MyHandler {
fn handle_frame(&mut self, frame: &[u8], width: u32, height: u32) {
println!("收到帧: {}x{}, 大小: {}字节", width, height, frame.len());
// 在这里处理帧数据
}
}
fn main() {
let capture = ScreenCapture::new().unwrap();
let config = CaptureConfig::default()
.capture_all_displays(true);
let handler = MyHandler;
let mut stream = capture.start_stream(&config, handler).unwrap();
// 运行10秒
std::thread::sleep(Duration::from_secs(10));
stream.stop().unwrap();
}
多显示器支持
use screen_capture_kit::{ScreenCapture, CaptureConfig, DisplayInfo};
fn main() {
let capture = ScreenCapture::new().unwrap();
// 获取所有显示器信息
let displays = capture.list_displays().unwrap();
for (i, display) in displays.iter().enumerate() {
println!("显示器 {}: {}x{}", i, display.width, display.height);
}
// 捕获第二个显示器
if displays.len() > 1 {
let config = CaptureConfig::default()
.display_id(displays[1].display_id);
let image = capture.capture_image(&config).unwrap();
image.save("display2.png").unwrap();
}
}
完整示例代码
下面是一个结合了多种功能的完整示例,展示如何创建一个简单的屏幕捕获工具:
use screen_capture_kit::{
ScreenCapture,
CaptureConfig,
WindowInfo,
DisplayInfo,
Rect,
RecorderConfig,
FrameHandler
};
use std::time::Duration;
// 自定义帧处理器实现
struct CustomFrameHandler;
impl FrameHandler for CustomFrameHandler {
fn handle_frame(&mut self, frame: &[u8], width: u32, height: u32) {
println!("处理帧数据: {}x{} ({}字节)", width, height, frame.len());
}
}
fn main() {
// 初始化ScreenCapture
let capture = match ScreenCapture::new() {
Ok(c) => c,
Err(e) => {
eprintln!("初始化失败: {}", e);
return;
}
};
// 1. 列出所有窗口
println!("可用窗口:");
if let Ok(windows) = capture.list_windows() {
for window in windows {
println!("- {} (ID: {})", window.title, window.window_id);
}
}
// 2. 列出所有显示器
println!("\n可用显示器:");
if let Ok(displays) = capture.list_displays() {
for (i, display) in displays.iter().enumerate() {
println!("{}: {}x{}", i, display.width, display.height);
}
}
// 3. 捕获全屏截图
println!("\n捕获全屏截图...");
let fullscreen_config = CaptureConfig::default()
.capture_all_displays(true);
if let Ok(image) = capture.capture_image(&fullscreen_config) {
if let Err(e) = image.save("fullscreen.png") {
eprintln!("保存截图失败: {}", e);
} else {
println!("全屏截图已保存为 fullscreen.png");
}
}
// 4. 捕获特定区域
println!("\n捕获区域截图...");
let region = Rect {
x: 100,
y: 100,
width: 800,
height: 600,
};
let region_config = CaptureConfig::default()
.region(region);
if let Ok(image) = capture.capture_image(®ion_config) {
if let Err(e) = image.save("region.png") {
eprintln!("保存区域截图失败: {}", e);
} else {
println!("区域截图已保存为 region.png");
}
}
// 5. 屏幕录制
println!("\n开始屏幕录制...");
let recorder_config = RecorderConfig::new("output.mp4")
.fps(30)
.quality(80);
if let Ok(mut recorder) = capture.start_recording(&fullscreen_config, &recorder_config) {
println!("录制中...等待5秒");
std::thread::sleep(Duration::from_secs(5));
recorder.stop().unwrap();
println!("录制已保存为 output.mp4");
}
// 6. 实时流处理
println!("\n开始实时流处理...");
let handler = CustomFrameHandler;
if let Ok(mut stream) = capture.start_stream(&fullscreen_config, handler) {
println!("流处理中...等待3秒");
std::thread::sleep(Duration::from_secs(3));
stream.stop().unwrap();
println!("流处理结束");
}
}
性能优化建议
- 对于视频录制,适当调整帧率和质量平衡性能与输出大小
- 捕获特定区域而非整个屏幕可显著提高性能
- 考虑使用回调处理帧数据而不是保存每一帧到内存
- 对于长时间录制,使用文件流式写入而非内存缓冲
注意事项
- 在macOS上需要屏幕录制权限
- 在Windows上需要管理员权限才能捕获某些窗口
- 捕获的帧数据格式通常是RGBA,处理时需注意
ScreenCaptureKit提供了强大而灵活的屏幕捕获功能,适用于各种屏幕录制和截图场景。通过合理配置,可以实现高性能的屏幕捕获应用。