blockish_player/
lib.rs

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}