lumina/src/rust/ytdl.rs

104 lines
3.2 KiB
Rust

#[cxx_qt::bridge]
mod qobject {
unsafe extern "C++" {
include!("cxx-qt-lib/qurl.h");
type QUrl = cxx_qt_lib::QUrl;
include!("cxx-qt-lib/qstring.h");
type QString = cxx_qt_lib::QString;
}
unsafe extern "RustQt" {
#[qobject]
#[qml_element]
#[qproperty(QString, title)]
#[qproperty(QUrl, thumbnail)]
#[qproperty(bool, loaded)]
#[qproperty(bool, loading)]
#[qproperty(QUrl, file)]
type Ytdl = super::YtdlRust;
#[qinvokable]
fn get_video(self: Pin<&mut Ytdl>, url: QUrl) -> bool;
}
impl cxx_qt::Threading for Ytdl {}
}
use cxx_qt::{CxxQtType, Threading};
use cxx_qt_lib::{QString, QUrl};
use dirs;
use std::{fs, pin::Pin};
use tracing::debug;
use youtube_dl::YoutubeDl;
#[derive(Clone, Default)]
pub struct YtdlRust {
title: QString,
thumbnail: QUrl,
loaded: bool,
loading: bool,
file: QUrl,
}
impl qobject::Ytdl {
pub fn get_video(mut self: Pin<&mut Self>, url: QUrl) -> bool {
if !url.is_valid() {
false
} else if let Some(mut data_dir) = dirs::data_local_dir() {
data_dir.push("lumina");
data_dir.push("ytdl");
if !data_dir.exists() {
fs::create_dir(&data_dir)
.expect("Could not create ytdl dir");
}
debug!(?data_dir);
self.as_mut().set_loading(true);
let thread = self.qt_thread();
let runtime = tokio::runtime::Runtime::new().unwrap();
runtime.spawn(async move {
let url = url.to_string();
let output_dirs = data_dir.to_str().unwrap();
debug!(output_dirs);
let ytdl = YoutubeDl::new(url)
.socket_timeout("15")
.output_directory(output_dirs)
.output_template("%(title)s.%(ext)s")
.download(true)
.run()
.unwrap();
let output = ytdl.into_single_video().unwrap();
debug!(
output.title,
output.thumbnail, output.url
);
let title = QString::from(&output.title);
let thumbnail = QUrl::from(
&output.thumbnail.unwrap_or_default(),
);
let mut file = String::from(output_dirs);
file.push('/');
file.push_str(&output.title);
file.push('.');
file.push_str(&output.ext.unwrap_or_default());
debug!(file);
thread.queue(move |mut qobject_ytdl| {
qobject_ytdl.as_mut().set_loaded(true);
qobject_ytdl.as_mut().set_loading(false);
qobject_ytdl.as_mut().set_title(title);
qobject_ytdl
.as_mut()
.set_thumbnail(thumbnail);
qobject_ytdl
.as_mut()
.set_file(QUrl::from(&file));
})
});
true
} else {
false
}
}
async fn dl_video() {}
}