源码地址:https://gitee.com/jackxiao3386/rust-m3u8。
先看最终效果图
image.png
打开vscode,使用cargo new projectName 命令新建一个项目,将
eframe = "0.14.0"
confy = "0.4.0"
serde = {version = "1.0.130", features = ["derive"]}
加入到cargo.toml
的依赖项
转到main.rs
,在这里需要新建一个结构体,存放关键的一些字段
pub struct M3u8App {
pub m3u8link: String,
pub save_path: String,
pub progress: Arc<Mutex<f32>>,
pub message: Arc<Mutex<String>>,
pub animated: bool,
pub proxies: String,
}
在这里我使用了 pub
关键词,后续方便移入到其他的模块中。详细解释下各个字段的含义
- m3u8link m3u8链接
- save_path 下载的视频的保存目录
- progress 进度条数据,用于实时更新下载进度,使用多线程需要线程同步所以使用了Arc类型
- message 任务附加信息,使用多线程需要线程同步所以使用了Arc类型
- animated 标记进度动画的开始截止
- proxies 是否使用代理
结构体准备了,就需要初始化了,在main.rs
中添加代码
impl M3u8App {
pub fn new() -> Self {
Self {
m3u8link: String::new(),
save_path: String::new(),
progress: Arc::new(Mutex::new(0.)),
message: Arc::new(Mutex::new(String::from("等待任务开始"))),
animated: false,
proxies: String::new(),
}
}
}
为eframe有个主要的trait 名为app
,要建立ui界面需要实现这个trait,当然实现很简单。
impl App for M3u8App {
fn setup(
&mut self,
_ctx: &eframe::egui::CtxRef,
_frame: &mut eframe::epi::Frame<'_>,
_storage: Option<&dyn eframe::epi::Storage>,
) {
}
fn update(&mut self, ctx: &eframe::egui::CtxRef, _frame: &mut eframe::epi::Frame<'_>) {}
fn name(&self) -> &str {
"M3u8 Downloader"
}
}
setup函数用于初始化其他必须的工作,update函数,用于绘制主要的UI界面,name函数则返回一个字符串,是ui的窗口标题
现在,在入口函数main中注册这个app并运行吧
fn main() {
let app = M3u8App::new();
let mut win_options = NativeOptions::default();
win_options.initial_window_size = Some(Vec2::new(600., 400.));
run_native(Box::new(app), win_options);
}
运行后,出现一个框,里面什么都没有,因为还没update一些组件,后续会讲解如何绘制组件进去
image.png