mirror of
https://github.com/arabianq/pipewire-soundpad.git
synced 2026-06-19 12:13:32 +00:00
Compare commits
4 Commits
695c83c9e6
...
dac9d53cef
| Author | SHA1 | Date | |
|---|---|---|---|
| dac9d53cef | |||
| 9da3799cd3 | |||
| d66369884c | |||
| 5e47e7d6fb |
Generated
+677
-156
File diff suppressed because it is too large
Load Diff
+4
-1
@@ -43,7 +43,7 @@ rustix = { version = "1.1.4", features = ["process"] }
|
|||||||
rust-i18n = "4.0.0"
|
rust-i18n = "4.0.0"
|
||||||
sys-locale = "0.3.2"
|
sys-locale = "0.3.2"
|
||||||
|
|
||||||
rodio = { git = "https://github.com/arabianq/rodio.git", rev = "1a08f281c352622bd82b87b8731585245802d9cf", default-features = false, features = [
|
rodio = { git = "https://github.com/arabianq/rodio.git", rev = "33afba2a2d97bb730eb6537f09d2b3815bff0f33", default-features = false, features = [
|
||||||
"symphonia-all",
|
"symphonia-all",
|
||||||
"symphonia-libopus",
|
"symphonia-libopus",
|
||||||
"playback",
|
"playback",
|
||||||
@@ -64,6 +64,9 @@ egui_extras = "0.34.1"
|
|||||||
egui_material_icons = "0.6.0"
|
egui_material_icons = "0.6.0"
|
||||||
egui_dnd = "0.15.0"
|
egui_dnd = "0.15.0"
|
||||||
|
|
||||||
|
reqwest = "0.13.4"
|
||||||
|
percent-encoding = "2.3.2"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "pwsp-daemon"
|
name = "pwsp-daemon"
|
||||||
path = "src/bin/daemon.rs"
|
path = "src/bin/daemon.rs"
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
Name=PWSP (Soundpad)
|
Name=PWSP (Soundpad)
|
||||||
Comment=Let's you play audio files through you microphone
|
Comment=Let's you play audio files through you microphone
|
||||||
Exec=pwsp-gui %u
|
Exec=/usr/bin/pwsp-gui %u
|
||||||
Icon=pwsp
|
Icon=pwsp
|
||||||
Terminal=false
|
Terminal=false
|
||||||
Type=Application
|
Type=Application
|
||||||
Categories=Audio
|
Categories=Audio
|
||||||
|
MimeType=x-scheme-handler/soundpad;
|
||||||
+843
-297
File diff suppressed because one or more lines are too long
@@ -2,21 +2,26 @@
|
|||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
if len(sys.argv) == 2 and sys.argv[1].startswith("soundpad://"):
|
||||||
|
subprocess.Popen(["pwsp-gui", sys.argv[1]])
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
prog="PWSP Flatpak",
|
prog="PWSP Flatpak", add_help=True, exit_on_error=True
|
||||||
add_help=True,
|
|
||||||
exit_on_error=True
|
|
||||||
)
|
)
|
||||||
subparsers = parser.add_subparsers(dest="command")
|
subparsers = parser.add_subparsers(dest="command")
|
||||||
|
|
||||||
cli_parser = subparsers.add_parser("cli", add_help=False, prefix_chars=" ")
|
cli_parser = subparsers.add_parser("cli", add_help=False, prefix_chars=" ")
|
||||||
cli_parser.add_argument("args", nargs=argparse.REMAINDER, help="Arguments for pwsp-cli")
|
cli_parser.add_argument(
|
||||||
|
"args", nargs=argparse.REMAINDER, help="Arguments for pwsp-cli"
|
||||||
|
)
|
||||||
|
|
||||||
daemon_parser = subparsers.add_parser("daemon", add_help=True)
|
daemon_parser = subparsers.add_parser("daemon", add_help=True)
|
||||||
daemon_group = daemon_parser.add_mutually_exclusive_group(required=True)
|
daemon_group = daemon_parser.add_mutually_exclusive_group(required=True)
|
||||||
daemon_group.add_argument("--start", action="store_true", help="Start pwps-daemon")
|
daemon_group.add_argument("--start", action="store_true", help="Start pwsp-daemon")
|
||||||
daemon_group.add_argument("--kill", action="store_true", help="Kill pwsp-daemon")
|
daemon_group.add_argument("--kill", action="store_true", help="Kill pwsp-daemon")
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
@@ -32,4 +37,4 @@ if __name__ == "__main__":
|
|||||||
if args.start:
|
if args.start:
|
||||||
subprocess.Popen("pwsp-daemon")
|
subprocess.Popen("pwsp-daemon")
|
||||||
elif args.kill:
|
elif args.kill:
|
||||||
subprocess.Popen(["pwsp-cli", "action", "kill"])
|
subprocess.Popen(["pwsp-cli", "action", "kill"])
|
||||||
|
|||||||
@@ -7,3 +7,4 @@ Terminal=false
|
|||||||
Type=Application
|
Type=Application
|
||||||
Categories=AudioVideo;Audio;
|
Categories=AudioVideo;Audio;
|
||||||
Keywords=soundpad;pipewire;audio;
|
Keywords=soundpad;pipewire;audio;
|
||||||
|
MimeType=x-scheme-handler/soundpad;
|
||||||
+48
-2
@@ -1,7 +1,9 @@
|
|||||||
mod gui;
|
mod gui;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::{Context, Result};
|
||||||
|
use pwsp::utils::gui::ensure_pwsp_audio_dir;
|
||||||
use rust_i18n::i18n;
|
use rust_i18n::i18n;
|
||||||
|
use std::{env, path::PathBuf};
|
||||||
|
|
||||||
i18n!("locales", fallback = "en");
|
i18n!("locales", fallback = "en");
|
||||||
|
|
||||||
@@ -10,5 +12,49 @@ async fn main() -> Result<()> {
|
|||||||
let locale = sys_locale::get_locale().unwrap_or(String::from("en-US"));
|
let locale = sys_locale::get_locale().unwrap_or(String::from("en-US"));
|
||||||
rust_i18n::set_locale(&locale);
|
rust_i18n::set_locale(&locale);
|
||||||
|
|
||||||
gui::run().await
|
let args = env::args().skip(1).collect::<Vec<String>>();
|
||||||
|
|
||||||
|
if let Some(uri) = args.first() {
|
||||||
|
match download_audio_from_url(uri).await {
|
||||||
|
Ok(path) => println!("Successfully downloaded to: {:?}", path),
|
||||||
|
Err(e) => eprintln!("Error downloading file: {}", e),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
gui::run().await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn download_audio_from_url(uri: &str) -> Result<PathBuf> {
|
||||||
|
let prefix = "soundpad://sound/url/";
|
||||||
|
|
||||||
|
let target_url = uri
|
||||||
|
.strip_prefix(prefix)
|
||||||
|
.ok_or_else(|| anyhow::anyhow!("URI does not containt an expected prefix: {}", prefix))?;
|
||||||
|
|
||||||
|
let file_name_encoded = target_url
|
||||||
|
.split('/')
|
||||||
|
.next_back()
|
||||||
|
.unwrap_or("downloaded_audio.mp3");
|
||||||
|
|
||||||
|
let file_name = percent_encoding::percent_decode_str(file_name_encoded)
|
||||||
|
.decode_utf8()
|
||||||
|
.unwrap_or_else(|_| file_name_encoded.into())
|
||||||
|
.into_owned();
|
||||||
|
|
||||||
|
let save_path = ensure_pwsp_audio_dir().join(file_name);
|
||||||
|
|
||||||
|
let response = reqwest::get(target_url)
|
||||||
|
.await?
|
||||||
|
.error_for_status()
|
||||||
|
.context("Failed to fetch file")?;
|
||||||
|
|
||||||
|
let bytes = response.bytes().await?;
|
||||||
|
|
||||||
|
tokio::fs::write(&save_path, bytes)
|
||||||
|
.await
|
||||||
|
.context("Failed to save file to disk")?;
|
||||||
|
|
||||||
|
Ok(save_path)
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-2
@@ -1,4 +1,7 @@
|
|||||||
use crate::{types::socket::Request, utils::config::get_config_path};
|
use crate::{
|
||||||
|
types::socket::Request,
|
||||||
|
utils::{config::get_config_path, gui::ensure_pwsp_audio_dir},
|
||||||
|
};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{collections::HashMap, fs, path::PathBuf};
|
use std::{collections::HashMap, fs, path::PathBuf};
|
||||||
@@ -69,7 +72,7 @@ impl Default for GuiConfig {
|
|||||||
save_scale_factor: false,
|
save_scale_factor: false,
|
||||||
pause_on_exit: false,
|
pause_on_exit: false,
|
||||||
|
|
||||||
dirs: vec![],
|
dirs: vec![ensure_pwsp_audio_dir()],
|
||||||
|
|
||||||
preferred_theme: PreferredTheme::System,
|
preferred_theme: PreferredTheme::System,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use anyhow::{Result, anyhow};
|
use anyhow::{Result, anyhow};
|
||||||
use std::{
|
use std::{
|
||||||
|
path::PathBuf,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
time::Instant,
|
time::Instant,
|
||||||
};
|
};
|
||||||
@@ -36,6 +37,17 @@ pub fn make_request_async(request: Request) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn ensure_pwsp_audio_dir() -> PathBuf {
|
||||||
|
let audio_dir = dirs::audio_dir().unwrap_or("~/Music".into());
|
||||||
|
let pwsp_audio_dir = audio_dir.join("PWSP");
|
||||||
|
|
||||||
|
if !pwsp_audio_dir.exists() {
|
||||||
|
std::fs::create_dir_all(&pwsp_audio_dir).ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
pwsp_audio_dir
|
||||||
|
}
|
||||||
|
|
||||||
pub fn format_time_pair(position: f32, duration: f32) -> String {
|
pub fn format_time_pair(position: f32, duration: f32) -> String {
|
||||||
fn format_time(seconds: f32) -> String {
|
fn format_time(seconds: f32) -> String {
|
||||||
let total_seconds = seconds.round() as u32;
|
let total_seconds = seconds.round() as u32;
|
||||||
|
|||||||
Reference in New Issue
Block a user