/
main.rs
146 lines (133 loc) · 3.7 KB
/
main.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
mod common;
mod config;
mod util;
use crate::common::GLOBAL_CLIENT;
use anyhow::{anyhow, Result};
use clap::Parser;
use seam_core::error::SeamError;
/// 获取直播源
#[derive(Parser)]
#[command(name = "seam")]
#[command(about ="
________ _______ _______ _______
| __| ___| _ | | |
|__ | ___| | |
|_______|_______|___|___|__|_|__|", long_about = None)]
#[command(subcommand_negates_reqs = true)]
#[command(arg_required_else_help = true)]
struct Cli {
/// 平台名称
#[arg(short = 'l', required = true)]
live: Option<String>,
/// 直播间号
#[arg(short = 'i', required = true)]
rid: Option<String>,
/// 显示详细信息
#[arg(short = 'a')]
all: bool,
/// 直接录播功能
#[arg(short = 'r')]
record: bool,
/// 自动监控录播功能
#[arg(short = 'R')]
auto_record: bool,
/// 输出到终端的弹幕功能
#[arg(short = 'd')]
danmu: bool,
/// 根据参数指定的文件地址输出弹幕
#[arg(short = 'D')]
config_danmu: bool,
#[command(subcommand)]
command: Option<Commands>,
}
#[derive(Parser, Debug)]
enum Commands {
/// 显示所有支持的平台
List,
}
// 获取直播源的实现
pub async fn cli() -> Result<()> {
let Cli {
live,
rid,
all,
record,
auto_record,
danmu,
config_danmu,
command,
} = Cli::parse();
// 获取参数
let live = live.ok_or(anyhow!("请指定平台名称"))?;
let rid = rid.ok_or(anyhow!("请指定直播间号"))?;
// 处理子命令
if let Some(command) = command {
return match command {
Commands::List => {
println!(
"可用平台:{}",
GLOBAL_CLIENT.keys().cloned().collect::<Vec<_>>().join(", ")
);
Ok(())
}
};
}
let node = match GLOBAL_CLIENT.get(&live) {
Some(client) => client.get(&rid, Some(config::headers(&live))).await,
None => {
return Err(anyhow!(
"请检查 {} 是否为可用平台, 或前往 https://github.com/Borber/seam/issues 申请支持",
live
))
}
};
// 无参数情况下,直接输出直播源信息
if !(danmu || config_danmu || record || auto_record) {
match node {
Ok(node) => {
if all {
println!("{}", node.json())
} else {
println!(
"{}",
node.urls
.into_iter()
.map(|item| item.url)
.collect::<Vec<_>>()
.join("\n\n")
)
}
}
Err(SeamError::None) => println!("未开播"),
Err(e) => println!("{}", e),
}
return Ok(());
}
// 收集不同参数功能的异步线程 handler
let mut thread_handlers = vec![];
// 处理参数-d,直接输出弹幕。
// 由于该函数为cli层,所以出错可以直接panic。
if danmu {
let h = tokio::spawn(async move {
// args.command
// .danmu(vec![&Terminal::try_new(None).unwrap()])
// .await
// .unwrap();
println!("弹幕功能正在重构中,敬请期待") // TODO
});
thread_handlers.push(h);
}
tokio::select! {
_ = async {
for h in thread_handlers {
h.await.unwrap();
}
} => {}
}
Ok(())
}
#[tokio::main]
async fn main() -> Result<()> {
cli().await?;
Ok(())
}