mirror of
https://github.com/johrpan/musicus.git
synced 2025-10-26 11:47:25 +01:00
Update to newest gtk-rs crates
Some things were adapted accordingly and some warnings from clippy were fixed along the way.
This commit is contained in:
parent
863c9d19c3
commit
7c9c01d3ea
9 changed files with 359 additions and 406 deletions
589
Cargo.lock
generated
589
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -5,10 +5,10 @@ edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
fragile = "1.0.0"
|
fragile = "1.0.0"
|
||||||
gio = "0.9.1"
|
gio = "0.14.0"
|
||||||
glib = "0.10.3"
|
glib = "0.14.0"
|
||||||
gstreamer = "0.16.4"
|
gstreamer = "0.17.0"
|
||||||
gstreamer-player = "0.16.3"
|
gstreamer-player = "0.17.0"
|
||||||
log = { version = "0.4.14", features = ["std"] }
|
log = { version = "0.4.14", features = ["std"] }
|
||||||
musicus_client = { version = "0.1.0", path = "../client" }
|
musicus_client = { version = "0.1.0", path = "../client" }
|
||||||
musicus_database = { version = "0.1.0", path = "../database" }
|
musicus_database = { version = "0.1.0", path = "../database" }
|
||||||
|
|
|
||||||
|
|
@ -102,11 +102,10 @@ impl Backend {
|
||||||
pub async fn init(&self) -> Result<()> {
|
pub async fn init(&self) -> Result<()> {
|
||||||
self.init_library().await?;
|
self.init_library().await?;
|
||||||
|
|
||||||
if let Some(url) = self.settings.get_string("server-url") {
|
let url = self.settings.string("server-url");
|
||||||
if !url.is_empty() {
|
if !url.is_empty() {
|
||||||
self.client.set_server_url(&url);
|
self.client.set_server_url(&url);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(all(feature = "dbus"))]
|
#[cfg(all(feature = "dbus"))]
|
||||||
match Self::load_login_data().await {
|
match Self::load_login_data().await {
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,11 @@ use std::rc::Rc;
|
||||||
impl Backend {
|
impl Backend {
|
||||||
/// Initialize the music library if it is set in the settings.
|
/// Initialize the music library if it is set in the settings.
|
||||||
pub(super) async fn init_library(&self) -> Result<()> {
|
pub(super) async fn init_library(&self) -> Result<()> {
|
||||||
if let Some(path) = self.settings.get_string("music-library-path") {
|
let path = self.settings.string("music-library-path");
|
||||||
if !path.is_empty() {
|
if !path.is_empty() {
|
||||||
self.set_music_library_path_priv(PathBuf::from(path.to_string()))
|
self.set_music_library_path_priv(PathBuf::from(path.to_string()))
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ impl Player {
|
||||||
pub fn new(music_library_path: PathBuf) -> Rc<Self> {
|
pub fn new(music_library_path: PathBuf) -> Rc<Self> {
|
||||||
let dispatcher = gstreamer_player::PlayerGMainContextSignalDispatcher::new(None);
|
let dispatcher = gstreamer_player::PlayerGMainContextSignalDispatcher::new(None);
|
||||||
let player = gstreamer_player::Player::new(None, Some(&dispatcher.upcast()));
|
let player = gstreamer_player::Player::new(None, Some(&dispatcher.upcast()));
|
||||||
let mut config = player.get_config();
|
let mut config = player.config();
|
||||||
config.set_position_update_interval(250);
|
config.set_position_update_interval(250);
|
||||||
player.set_config(config).unwrap();
|
player.set_config(config).unwrap();
|
||||||
player.set_video_track_enabled(false);
|
player.set_video_track_enabled(false);
|
||||||
|
|
@ -88,14 +88,14 @@ impl Player {
|
||||||
let clone = fragile::Fragile::new(result.clone());
|
let clone = fragile::Fragile::new(result.clone());
|
||||||
player.connect_position_updated(move |_, position| {
|
player.connect_position_updated(move |_, position| {
|
||||||
for cb in &*clone.get().position_cbs.borrow() {
|
for cb in &*clone.get().position_cbs.borrow() {
|
||||||
cb(position.mseconds().unwrap());
|
cb(position.unwrap().mseconds());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let clone = fragile::Fragile::new(result.clone());
|
let clone = fragile::Fragile::new(result.clone());
|
||||||
player.connect_duration_changed(move |_, duration| {
|
player.connect_duration_changed(move |_, duration| {
|
||||||
for cb in &*clone.get().duration_cbs.borrow() {
|
for cb in &*clone.get().duration_cbs.borrow() {
|
||||||
cb(duration.mseconds().unwrap());
|
cb(duration.unwrap().mseconds());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -172,8 +172,8 @@ impl Player {
|
||||||
self.current_track.get()
|
self.current_track.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_duration(&self) -> gstreamer::ClockTime {
|
pub fn get_duration(&self) -> Option<gstreamer::ClockTime> {
|
||||||
self.player.get_duration()
|
self.player.duration()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_playing(&self) -> bool {
|
pub fn is_playing(&self) -> bool {
|
||||||
|
|
@ -250,9 +250,11 @@ impl Player {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn previous(&self) -> Result<()> {
|
pub fn previous(&self) -> Result<()> {
|
||||||
let mut current_track = self.current_track.get().ok_or(Error::Other(String::from(
|
let mut current_track = self.current_track.get().ok_or_else(|| {
|
||||||
|
Error::Other(String::from(
|
||||||
"Player tried to access non existant current track.",
|
"Player tried to access non existant current track.",
|
||||||
)))?;
|
))
|
||||||
|
})?;
|
||||||
|
|
||||||
if current_track > 0 {
|
if current_track > 0 {
|
||||||
current_track -= 1;
|
current_track -= 1;
|
||||||
|
|
@ -273,9 +275,11 @@ impl Player {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next(&self) -> Result<()> {
|
pub fn next(&self) -> Result<()> {
|
||||||
let mut current_track = self.current_track.get().ok_or(Error::Other(String::from(
|
let mut current_track = self.current_track.get().ok_or_else(|| {
|
||||||
|
Error::Other(String::from(
|
||||||
"Player tried to access non existant current track.",
|
"Player tried to access non existant current track.",
|
||||||
)))?;
|
))
|
||||||
|
})?;
|
||||||
|
|
||||||
let playlist = self.playlist.borrow();
|
let playlist = self.playlist.borrow();
|
||||||
|
|
||||||
|
|
@ -298,10 +302,8 @@ impl Player {
|
||||||
.into_string()
|
.into_string()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let uri = glib::filename_to_uri(&path, None).or(Err(Error::Other(format!(
|
let uri = glib::filename_to_uri(&path, None)
|
||||||
"Failed to create URI from path: {}",
|
.map_err(|_| Error::Other(format!("Failed to create URI from path: {}", path)))?;
|
||||||
path
|
|
||||||
))))?;
|
|
||||||
|
|
||||||
self.player.set_uri(&uri);
|
self.player.set_uri(&uri);
|
||||||
|
|
||||||
|
|
@ -351,7 +353,7 @@ impl Player {
|
||||||
}
|
}
|
||||||
|
|
||||||
for cb in &*self.duration_cbs.borrow() {
|
for cb in &*self.duration_cbs.borrow() {
|
||||||
cb(self.player.get_duration().mseconds().unwrap());
|
cb(self.player.duration().unwrap().mseconds());
|
||||||
}
|
}
|
||||||
|
|
||||||
for cb in &*self.playing_cbs.borrow() {
|
for cb in &*self.playing_cbs.borrow() {
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,9 @@ edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
base64 = "0.13.0"
|
base64 = "0.13.0"
|
||||||
glib = { git = "https://github.com/gtk-rs/gtk-rs/", features = ["v2_64"] }
|
glib = "0.14.0"
|
||||||
gstreamer = "0.16.5"
|
gstreamer = "0.17.0"
|
||||||
gstreamer-pbutils = "0.16.5"
|
gstreamer-pbutils = "0.17.0"
|
||||||
log = "0.4.14"
|
log = "0.4.14"
|
||||||
once_cell = "1.5.2"
|
once_cell = "1.5.2"
|
||||||
rand = "0.7.3"
|
rand = "0.7.3"
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,8 @@ pub(super) fn new() -> Result<ImportSession> {
|
||||||
gstreamer::Element::link_many(&[&cdparanoiasrc, &queue, &audioconvert, &flacenc, &fakesink])?;
|
gstreamer::Element::link_many(&[&cdparanoiasrc, &queue, &audioconvert, &flacenc, &fakesink])?;
|
||||||
|
|
||||||
let bus = pipeline
|
let bus = pipeline
|
||||||
.get_bus()
|
.bus()
|
||||||
.ok_or(Error::u(String::from("Failed to get bus from pipeline.")))?;
|
.ok_or_else(|| Error::u(String::from("Failed to get bus from pipeline.")))?;
|
||||||
|
|
||||||
// Run the pipeline into the paused state and wait for the resulting TOC message on the bus.
|
// Run the pipeline into the paused state and wait for the resulting TOC message on the bus.
|
||||||
|
|
||||||
|
|
@ -38,21 +38,21 @@ pub(super) fn new() -> Result<ImportSession> {
|
||||||
|
|
||||||
let msg = bus.timed_pop_filtered(
|
let msg = bus.timed_pop_filtered(
|
||||||
ClockTime::from_seconds(5),
|
ClockTime::from_seconds(5),
|
||||||
&vec![MessageType::Toc, MessageType::Error],
|
&[MessageType::Toc, MessageType::Error],
|
||||||
);
|
);
|
||||||
|
|
||||||
let toc = match msg {
|
let toc = match msg {
|
||||||
Some(msg) => match msg.view() {
|
Some(msg) => match msg.view() {
|
||||||
MessageView::Error(err) => Err(Error::os(err.get_error())),
|
MessageView::Error(err) => Err(Error::os(err.error())),
|
||||||
MessageView::Toc(toc) => Ok(toc.get_toc().0),
|
MessageView::Toc(toc) => Ok(toc.toc().0),
|
||||||
_ => Err(Error::u(format!(
|
_ => Err(Error::u(format!(
|
||||||
"Unexpected message from GStreamer: {:?}",
|
"Unexpected message from GStreamer: {:?}",
|
||||||
msg
|
msg
|
||||||
))),
|
))),
|
||||||
},
|
},
|
||||||
None => Err(Error::Timeout(format!(
|
None => Err(Error::Timeout(
|
||||||
"Timeout while waiting for first message from GStreamer."
|
"Timeout while waiting for first message from GStreamer.".to_string(),
|
||||||
))),
|
)),
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
pipeline.set_state(gstreamer::State::Ready)?;
|
pipeline.set_state(gstreamer::State::Ready)?;
|
||||||
|
|
@ -72,33 +72,22 @@ pub(super) fn new() -> Result<ImportSession> {
|
||||||
|
|
||||||
let tmp_dir = create_tmp_dir()?;
|
let tmp_dir = create_tmp_dir()?;
|
||||||
|
|
||||||
for entry in toc.get_entries() {
|
for entry in toc.entries() {
|
||||||
if entry.get_entry_type() == TocEntryType::Track {
|
if entry.entry_type() == TocEntryType::Track {
|
||||||
let duration = entry
|
let duration = entry
|
||||||
.get_tags()
|
.tags()
|
||||||
.ok_or(Error::u(String::from("No tags in TOC entry.")))?
|
.ok_or_else(|| Error::u(String::from("No tags in TOC entry.")))?
|
||||||
.get::<Duration>()
|
.get::<Duration>()
|
||||||
.ok_or(Error::u(String::from(
|
.ok_or_else(|| Error::u(String::from("No duration tag found in TOC entry.")))?
|
||||||
"No duration tag found in TOC entry.",
|
|
||||||
)))?
|
|
||||||
.get()
|
.get()
|
||||||
.ok_or(Error::u(String::from(
|
.mseconds();
|
||||||
"Failed to unwrap duration tag from TOC entry.",
|
|
||||||
)))?
|
|
||||||
.mseconds()
|
|
||||||
.ok_or(Error::u(String::from("Failed to unwrap track duration.")))?;
|
|
||||||
|
|
||||||
let number = entry
|
let number = entry
|
||||||
.get_tags()
|
.tags()
|
||||||
.ok_or(Error::u(String::from("No tags in TOC entry.")))?
|
.ok_or_else(|| Error::u(String::from("No tags in TOC entry.")))?
|
||||||
.get::<TrackNumber>()
|
.get::<TrackNumber>()
|
||||||
.ok_or(Error::u(String::from(
|
.ok_or_else(|| Error::u(String::from("No track number tag found in TOC entry.")))?
|
||||||
"No track number tag found in TOC entry.",
|
.get();
|
||||||
)))?
|
|
||||||
.get()
|
|
||||||
.ok_or(Error::u(String::from(
|
|
||||||
"Failed to unwrap track number tag from TOC entry.",
|
|
||||||
)))?;
|
|
||||||
|
|
||||||
hasher.update(duration.to_le_bytes());
|
hasher.update(duration.to_le_bytes());
|
||||||
|
|
||||||
|
|
@ -140,7 +129,7 @@ pub(super) fn new() -> Result<ImportSession> {
|
||||||
// This will also affect the filesink as expected.
|
// This will also affect the filesink as expected.
|
||||||
pipeline.set_state(gstreamer::State::Playing)?;
|
pipeline.set_state(gstreamer::State::Playing)?;
|
||||||
|
|
||||||
for msg in bus.iter_timed(ClockTime::none()) {
|
for msg in bus.iter_timed(None) {
|
||||||
match msg.view() {
|
match msg.view() {
|
||||||
MessageView::Eos(..) => {
|
MessageView::Eos(..) => {
|
||||||
info!("Finished ripping track {}.", track.number);
|
info!("Finished ripping track {}.", track.number);
|
||||||
|
|
@ -149,7 +138,7 @@ pub(super) fn new() -> Result<ImportSession> {
|
||||||
}
|
}
|
||||||
MessageView::Error(err) => {
|
MessageView::Error(err) => {
|
||||||
pipeline.set_state(gstreamer::State::Null)?;
|
pipeline.set_state(gstreamer::State::Null)?;
|
||||||
Err(Error::os(err.get_error()))?;
|
return Err(Error::os(err.error()));
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
@ -174,9 +163,7 @@ pub(super) fn new() -> Result<ImportSession> {
|
||||||
|
|
||||||
/// Create a new temporary directory and return its path.
|
/// Create a new temporary directory and return its path.
|
||||||
fn create_tmp_dir() -> Result<PathBuf> {
|
fn create_tmp_dir() -> Result<PathBuf> {
|
||||||
let mut tmp_dir = glib::tmp_dir().ok_or(Error::u(String::from(
|
let mut tmp_dir = glib::tmp_dir();
|
||||||
"Failed to get temporary directory using glib::get_tmp_dir().",
|
|
||||||
)))?;
|
|
||||||
|
|
||||||
let dir_name = format!("musicus-{}", rand::random::<u64>());
|
let dir_name = format!("musicus-{}", rand::random::<u64>());
|
||||||
tmp_dir.push(dir_name);
|
tmp_dir.push(dir_name);
|
||||||
|
|
|
||||||
|
|
@ -19,30 +19,30 @@ pub(super) fn new(path: PathBuf) -> Result<ImportSession> {
|
||||||
|
|
||||||
let mut entries =
|
let mut entries =
|
||||||
std::fs::read_dir(path)?.collect::<std::result::Result<Vec<DirEntry>, std::io::Error>>()?;
|
std::fs::read_dir(path)?.collect::<std::result::Result<Vec<DirEntry>, std::io::Error>>()?;
|
||||||
entries.sort_by(|entry1, entry2| entry1.file_name().cmp(&entry2.file_name()));
|
entries.sort_by_key(|entry| entry.file_name());
|
||||||
|
|
||||||
for entry in entries {
|
for entry in entries {
|
||||||
if entry.file_type()?.is_file() {
|
if entry.file_type()?.is_file() {
|
||||||
let path = entry.path();
|
let path = entry.path();
|
||||||
|
|
||||||
let uri = glib::filename_to_uri(&path, None).or(Err(Error::u(format!(
|
let uri = glib::filename_to_uri(&path, None)
|
||||||
"Failed to create URI from path: {:?}",
|
.map_err(|_| Error::u(format!("Failed to create URI from path: {:?}", path)))?;
|
||||||
path
|
|
||||||
))))?;
|
|
||||||
|
|
||||||
let info = discoverer.discover_uri(&uri)?;
|
let info = discoverer.discover_uri(&uri)?;
|
||||||
|
|
||||||
if !info.get_audio_streams().is_empty() {
|
if !info.audio_streams().is_empty() {
|
||||||
let duration = info
|
let duration = info
|
||||||
.get_duration()
|
.duration()
|
||||||
.mseconds()
|
.ok_or_else(|| Error::u(format!("Failed to get duration for {}.", uri)))?
|
||||||
.ok_or(Error::u(format!("Failed to get duration for {}.", uri)))?;
|
.mseconds();
|
||||||
|
|
||||||
let file_name = entry.file_name();
|
let file_name = entry.file_name();
|
||||||
let name = file_name.into_string().or(Err(Error::u(format!(
|
let name = file_name.into_string().map_err(|_| {
|
||||||
|
Error::u(format!(
|
||||||
"Failed to convert OsString to String: {:?}",
|
"Failed to convert OsString to String: {:?}",
|
||||||
entry.file_name()
|
entry.file_name()
|
||||||
))))?;
|
))
|
||||||
|
})?;
|
||||||
|
|
||||||
hasher.update(duration.to_le_bytes());
|
hasher.update(duration.to_le_bytes());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,37 +5,18 @@ edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.33"
|
anyhow = "1.0.33"
|
||||||
|
adw = { package = "libadwaita", version = "0.1.0-alpha" }
|
||||||
async-trait = "0.1.42"
|
async-trait = "0.1.42"
|
||||||
futures-channel = "0.3.5"
|
futures-channel = "0.3.5"
|
||||||
|
gdk = { package = "gdk4", version = "0.1.0" }
|
||||||
gettext-rs = { version = "0.5.0", features = ["gettext-system"] }
|
gettext-rs = { version = "0.5.0", features = ["gettext-system"] }
|
||||||
gstreamer = "0.16.4"
|
gio = "0.14.0"
|
||||||
|
glib = "0.14.0"
|
||||||
|
gstreamer = "0.17.0"
|
||||||
|
gtk = { package = "gtk4", version = "0.1.0" }
|
||||||
gtk-macros = "0.3.0"
|
gtk-macros = "0.3.0"
|
||||||
log = "0.4.14"
|
log = "0.4.14"
|
||||||
musicus_backend = { version = "0.1.0", path = "../backend" }
|
musicus_backend = { version = "0.1.0", path = "../backend" }
|
||||||
once_cell = "1.5.2"
|
once_cell = "1.5.2"
|
||||||
rand = "0.7.3"
|
rand = "0.7.3"
|
||||||
sanitize-filename = "0.3.0"
|
sanitize-filename = "0.3.0"
|
||||||
|
|
||||||
[dependencies.gdk]
|
|
||||||
git = "https://github.com/gtk-rs/gtk4-rs/"
|
|
||||||
package = "gdk4"
|
|
||||||
|
|
||||||
[dependencies.gio]
|
|
||||||
git = "https://github.com/gtk-rs/gtk-rs/"
|
|
||||||
features = ["v2_64"]
|
|
||||||
|
|
||||||
[dependencies.glib]
|
|
||||||
git = "https://github.com/gtk-rs/gtk-rs/"
|
|
||||||
features = ["v2_64"]
|
|
||||||
|
|
||||||
[dependencies.gtk]
|
|
||||||
git = "https://github.com/gtk-rs/gtk4-rs"
|
|
||||||
package = "gtk4"
|
|
||||||
|
|
||||||
[dependencies.adw]
|
|
||||||
git = "https://gitlab.gnome.org/World/Rust/libadwaita-rs.git"
|
|
||||||
package = "libadwaita"
|
|
||||||
|
|
||||||
[dependencies.pango]
|
|
||||||
git = "https://github.com/gtk-rs/gtk-rs/"
|
|
||||||
features = ["v1_44"]
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue