mirror of
https://github.com/johrpan/musicus.git
synced 2025-10-26 19:57:25 +01:00
Update gtk-rs crates
This commit is contained in:
parent
df6e2e86c7
commit
7d7343ea8c
63 changed files with 3499 additions and 908 deletions
|
|
@ -1,10 +1,10 @@
|
|||
use crate::error::{Error, Result};
|
||||
use crate::session::{ImportSession, ImportTrack, State};
|
||||
use gstreamer::prelude::*;
|
||||
use gstreamer::{ClockTime, ElementFactory, MessageType, MessageView, TocEntryType};
|
||||
use gstreamer::tags::{Duration, TrackNumber};
|
||||
use gstreamer::{ClockTime, ElementFactory, MessageType, MessageView, TocEntryType};
|
||||
use log::info;
|
||||
use sha2::{Sha256, Digest};
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::path::PathBuf;
|
||||
use tokio::sync::watch;
|
||||
|
||||
|
|
@ -28,23 +28,31 @@ pub(super) fn new() -> Result<ImportSession> {
|
|||
pipeline.add_many(&[&cdparanoiasrc, &queue, &audioconvert, &flacenc, &fakesink])?;
|
||||
gstreamer::Element::link_many(&[&cdparanoiasrc, &queue, &audioconvert, &flacenc, &fakesink])?;
|
||||
|
||||
let bus = pipeline.get_bus().ok_or(Error::u(String::from("Failed to get bus from pipeline.")))?;
|
||||
let bus = pipeline
|
||||
.get_bus()
|
||||
.ok_or(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.
|
||||
|
||||
pipeline.set_state(gstreamer::State::Paused)?;
|
||||
|
||||
let msg = bus.timed_pop_filtered(ClockTime::from_seconds(5),
|
||||
&vec![MessageType::Toc, MessageType::Error]);
|
||||
let msg = bus.timed_pop_filtered(
|
||||
ClockTime::from_seconds(5),
|
||||
&vec![MessageType::Toc, MessageType::Error],
|
||||
);
|
||||
|
||||
let toc = match msg {
|
||||
Some(msg) => match msg.view() {
|
||||
MessageView::Error(err) => Err(Error::os(err.get_error())),
|
||||
MessageView::Toc(toc) => Ok(toc.get_toc().0),
|
||||
_ => Err(Error::u(format!("Unexpected message from GStreamer: {:?}", msg))),
|
||||
_ => Err(Error::u(format!(
|
||||
"Unexpected message from GStreamer: {:?}",
|
||||
msg
|
||||
))),
|
||||
},
|
||||
None => Err(Error::Timeout(
|
||||
format!("Timeout while waiting for first message from GStreamer."))),
|
||||
None => Err(Error::Timeout(format!(
|
||||
"Timeout while waiting for first message from GStreamer."
|
||||
))),
|
||||
}?;
|
||||
|
||||
pipeline.set_state(gstreamer::State::Ready)?;
|
||||
|
|
@ -66,22 +74,31 @@ pub(super) fn new() -> Result<ImportSession> {
|
|||
|
||||
for entry in toc.get_entries() {
|
||||
if entry.get_entry_type() == TocEntryType::Track {
|
||||
let duration = entry.get_tags()
|
||||
let duration = entry
|
||||
.get_tags()
|
||||
.ok_or(Error::u(String::from("No tags in TOC entry.")))?
|
||||
.get::<Duration>()
|
||||
.ok_or(Error::u(String::from("No duration tag found in TOC entry.")))?
|
||||
.ok_or(Error::u(String::from(
|
||||
"No duration tag found in TOC entry.",
|
||||
)))?
|
||||
.get()
|
||||
.ok_or(Error::u(String::from("Failed to unwrap duration tag from TOC entry.")))?
|
||||
.ok_or(Error::u(String::from(
|
||||
"Failed to unwrap duration tag from TOC entry.",
|
||||
)))?
|
||||
.mseconds()
|
||||
.ok_or(Error::u(String::from("Failed to unwrap track duration.")))?;
|
||||
|
||||
let number = entry.get_tags()
|
||||
let number = entry
|
||||
.get_tags()
|
||||
.ok_or(Error::u(String::from("No tags in TOC entry.")))?
|
||||
.get::<TrackNumber>()
|
||||
.ok_or(Error::u(String::from("No track number tag found in TOC entry.")))?
|
||||
.ok_or(Error::u(String::from(
|
||||
"No track number tag found in TOC entry.",
|
||||
)))?
|
||||
.get()
|
||||
.ok_or(Error::u(
|
||||
String::from("Failed to unwrap track number tag from TOC entry.")))?;
|
||||
.ok_or(Error::u(String::from(
|
||||
"Failed to unwrap track number tag from TOC entry.",
|
||||
)))?;
|
||||
|
||||
hasher.update(duration.to_le_bytes());
|
||||
|
||||
|
|
@ -129,11 +146,11 @@ pub(super) fn new() -> Result<ImportSession> {
|
|||
info!("Finished ripping track {}.", track.number);
|
||||
pipeline.set_state(gstreamer::State::Ready)?;
|
||||
break;
|
||||
},
|
||||
}
|
||||
MessageView::Error(err) => {
|
||||
pipeline.set_state(gstreamer::State::Null)?;
|
||||
Err(Error::os(err.get_error()))?;
|
||||
},
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
|
@ -157,8 +174,9 @@ pub(super) fn new() -> Result<ImportSession> {
|
|||
|
||||
/// Create a new temporary directory and return its path.
|
||||
fn create_tmp_dir() -> Result<PathBuf> {
|
||||
let mut tmp_dir = glib::get_tmp_dir().ok_or(Error::u(
|
||||
String::from("Failed to get temporary directory using glib::get_tmp_dir().")))?;
|
||||
let mut tmp_dir = glib::tmp_dir().ok_or(Error::u(String::from(
|
||||
"Failed to get temporary directory using glib::get_tmp_dir().",
|
||||
)))?;
|
||||
|
||||
let dir_name = format!("musicus-{}", rand::random::<u64>());
|
||||
tmp_dir.push(dir_name);
|
||||
|
|
@ -167,4 +185,3 @@ fn create_tmp_dir() -> Result<PathBuf> {
|
|||
|
||||
Ok(tmp_dir)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,10 +39,7 @@ impl Error {
|
|||
|
||||
/// Create a new unexpected error without an explicit source.
|
||||
pub(super) fn u(msg: String) -> Self {
|
||||
Self::Unexpected {
|
||||
msg,
|
||||
source: None,
|
||||
}
|
||||
Self::Unexpected { msg, source: None }
|
||||
}
|
||||
|
||||
/// Create a new unexpected error with an explicit source.
|
||||
|
|
@ -85,4 +82,3 @@ impl From<std::io::Error> for Error {
|
|||
}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ use crate::error::{Error, Result};
|
|||
use crate::session::{ImportSession, ImportTrack, State};
|
||||
use gstreamer::ClockTime;
|
||||
use gstreamer_pbutils::Discoverer;
|
||||
use log::{warn, info};
|
||||
use sha2::{Sha256, Digest};
|
||||
use log::{info, warn};
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::fs::DirEntry;
|
||||
use std::path::PathBuf;
|
||||
use tokio::sync::watch;
|
||||
|
|
@ -17,26 +17,32 @@ pub(super) fn new(path: PathBuf) -> Result<ImportSession> {
|
|||
let mut hasher = Sha256::new();
|
||||
let discoverer = Discoverer::new(ClockTime::from_seconds(1))?;
|
||||
|
||||
let mut entries = std::fs::read_dir(path)?.collect::<std::result::Result<Vec<DirEntry>, std::io::Error>>()?;
|
||||
let mut entries =
|
||||
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()));
|
||||
|
||||
for entry in entries {
|
||||
if entry.file_type()?.is_file() {
|
||||
let path = entry.path();
|
||||
|
||||
let uri = glib::filename_to_uri(&path, None)
|
||||
.or(Err(Error::u(format!("Failed to create URI from path: {:?}", path))))?;
|
||||
let uri = glib::filename_to_uri(&path, None).or(Err(Error::u(format!(
|
||||
"Failed to create URI from path: {:?}",
|
||||
path
|
||||
))))?;
|
||||
|
||||
let info = discoverer.discover_uri(&uri)?;
|
||||
|
||||
if !info.get_audio_streams().is_empty() {
|
||||
let duration = info.get_duration().mseconds()
|
||||
let duration = info
|
||||
.get_duration()
|
||||
.mseconds()
|
||||
.ok_or(Error::u(format!("Failed to get duration for {}.", uri)))?;
|
||||
|
||||
let file_name = entry.file_name();
|
||||
let name = file_name.into_string()
|
||||
.or(Err(Error::u(format!(
|
||||
"Failed to convert OsString to String: {:?}", entry.file_name()))))?;
|
||||
let name = file_name.into_string().or(Err(Error::u(format!(
|
||||
"Failed to convert OsString to String: {:?}",
|
||||
entry.file_name()
|
||||
))))?;
|
||||
|
||||
hasher.update(duration.to_le_bytes());
|
||||
|
||||
|
|
@ -50,7 +56,10 @@ pub(super) fn new(path: PathBuf) -> Result<ImportSession> {
|
|||
tracks.push(track);
|
||||
number += 1;
|
||||
} else {
|
||||
warn!("File {} skipped, because it doesn't contain any audio streams.", uri);
|
||||
warn!(
|
||||
"File {} skipped, because it doesn't contain any audio streams.",
|
||||
uri
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
pub use session::{ImportSession, ImportTrack, State};
|
||||
pub use error::{Error, Result};
|
||||
pub use session::{ImportSession, ImportTrack, State};
|
||||
|
||||
pub mod error;
|
||||
pub mod session;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use crate::{disc, folder};
|
||||
use crate::error::Result;
|
||||
use crate::{disc, folder};
|
||||
use std::path::PathBuf;
|
||||
use std::thread;
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
use tokio::sync::{oneshot, watch};
|
||||
|
||||
/// The current state of the import process.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue