1extern crate crossterm;
2extern crate glob;
3extern crate regex;
4use glob::glob;
5use regex::Regex;
6use std::env;
7use std::error::Error;
8use std::process::Command;
9
10fn find_lib(lib: String) -> Result<String, Box<dyn Error>> {
11 let output = Command::new("ldconfig").arg("-p").output()?;
12 let pattern = Regex::new(&format!(r"^[\s]*lib{}.*.so .* ([^ ]+)$", lib))?;
13 let list = String::from_utf8(output.stdout)?
14 .lines()
15 .filter_map(|line| pattern.captures(line))
16 .map(|cap| cap[1].to_string())
17 .collect::<Vec<String>>();
18 if list.is_empty() {
19 Err(std::boxed::Box::new(std::io::Error::new(
20 std::io::ErrorKind::Other,
21 format!("failed to load lib {}", lib),
22 )))
23 } else {
24 Ok(list[0].to_string())
25 }
26}
27
28pub fn ld_preload_path(player: &String) -> Result<String, Box<dyn Error>> {
29 let exe = env::current_exe()?;
30 let bin_dir = exe.parent().ok_or("bin_dir")?.to_str().ok_or("to str")?;
31 let mut ld_preload: String = "".to_string();
32 let mut found = false;
33 let pattern = bin_dir.to_string() + "/**/libblockish_caca*.so";
34 for entry in glob(&(pattern))? {
35 if let Ok(path) = entry {
36 if let Some(str_path) = path.as_path().to_str() {
37 ld_preload += &(":".to_string() + str_path);
38 found = true;
39 }
40 }
41 }
42 if !found {
43 ld_preload += &find_lib("blockish_caca".to_string())?;
44 }
45 if player == "cvlc" {
46 ld_preload += &":".to_string();
47 ld_preload += &find_lib("caca".to_string())?;
48 }
49 Ok(ld_preload)
50}
51
52pub fn video_command(player: &String, path: &String) -> Result<Command, Box<dyn Error>> {
53 let mut quiet = "-quiet";
54 let mut vo = "-vo";
55 let mut com = Command::new(player);
56 let ld_preload = ld_preload_path(&player)?;
57 let mut bwidth = 80;
58 let mut bheight = 20;
59 if let Ok(res) = crossterm::terminal::size() {
60 bwidth = res.0;
61 bheight = res.1
62 }
63 if player == "cvlc" {
64 quiet = "--quiet";
65 vo = "-V";
66 com.env("DISPLAY", "");
67 }
68 com.env("COLUNMS", bwidth.to_string())
69 .env("LINES", bheight.to_string())
70 .env("CACA_DRIVER", "raw")
71 .env("LD_PRELOAD", ld_preload)
72 .arg(quiet)
73 .arg(vo)
74 .arg("caca")
75 .arg(path);
76 Ok(com)
77}
78
79#[cfg(target_family = "unix")]
80pub fn play_video(player: &String, path: &String) -> Result<(), Box<dyn Error>> {
81 use std::os::unix::process::CommandExt;
82 video_command(player, path)?.exec();
83 Ok(())
84}