Add local HTTP server for audio streaming on Linux#923
Add local HTTP server for audio streaming on Linux#923martpie merged 3 commits intomartpie:fix-linux-playbackfrom
Conversation
This commit introduces a local HTTP server for streaming audio on Linux as a workaround for WebKitGTK's asset protocol limitations with media streaming and Range requests. Includes a `stream_server` module and necessary changes to TS and Tauri integration.
|
omg that's amazing, I was looking into this right now. IIRC, I think this issue was also happening on mac with some files but I cannot reproduce it, I need to double check. If that's the case, we may want to open this via a custom setting and for all operating systems. Let me try this branch once I get home. |
|
Just tested it, it works amazingly, thanks so much for doing that. I was really afraid I´d need to move the playback to the Rust side (tbh, maybe I'll still have to do it one day). I'll review the code once I have a bit more time. You can ignore the macOS failure, it's expected as it uses my own certificate to bundle the app. |
If you want me to prompt this and share what Opus would came up with, we can do that. 😄 |
|
hahahaha I have to say Claude has been working on a few PRs like #916 |
|
I see, nice! 👍 |
| } | ||
|
|
||
| fn content_type_for_extension(ext: &str) -> Option<&'static str> { | ||
| match ext { |
There was a problem hiding this comment.
Can we keep that in sync with
museeks/src-tauri/src/libs/database.rs
Line 12 in 6656f95
Basically, if an extension is added there, this function should break saying a case is not covered. This may require changing the type of the constant though.
There was a problem hiding this comment.
I put this into the database.rs and derived SUPPORTED_AUDIO_FORMATS.
| headers.insert(header::CONTENT_TYPE, content_type.parse().unwrap()); | ||
| headers.insert(header::CONTENT_LENGTH, body.len().to_string().parse().unwrap()); | ||
| headers.insert(header::ACCEPT_RANGES, "bytes".parse().unwrap()); | ||
| headers.insert(header::ACCESS_CONTROL_ALLOW_ORIGIN, "*".parse().unwrap()); |
There was a problem hiding this comment.
Not sure this header is required is it?
There was a problem hiding this comment.
Yes, can be removed.
src-tauri/src/main.rs
Outdated
| // On Linux, start a local HTTP server for audio streaming. | ||
| // WebKitGTK's asset protocol doesn't support media streaming properly. | ||
| #[cfg(target_os = "linux")] | ||
| let stream_server_port = plugins::stream_server::start(); |
There was a problem hiding this comment.
any way this logic can be moved within the init of the plugin? I understand it's a sync init.
See how I did it for the DB:
museeks/src-tauri/src/plugins/db.rs
Line 467 in 6656f95
It may create weird rust errors though, if it's too hard to change or fix the errors correctly, feel free to leave them like that, it's okeeey-ish.
| walkdir = "2.5.0" | ||
|
|
||
| [target.'cfg(target_os = "linux")'.dependencies] | ||
| axum = "0.7" |
There was a problem hiding this comment.
genuine question, how heavy is this? are there other minimalist-yet-ergonomic http servers here? not a big deal.
There was a problem hiding this comment.
Based on what Opus analyzed it is very light in this case. It only added 5 new crates to the lock file (axum, axum-core, matchit, serde_path_to_error, httpdate). Everything else axum depends on (hyper, http, tokio, tower, serde, bytes, futures-util, etc.) was already in the tree via Tauri. So the actual added weight is minimal.
The main alternatives would be:
warp- similar weight (also built on hyper/tokio), but its filter-based API is less ergonomic for this use casetiny_http- truly minimal, but synchronous (doesn't use tokio), so it'd need its own thread pool for concurrent requests- Raw
hyper- zero extra crates, but significantly more boilerplate for routing, query parsing, and response building - Raw
tokio::net::TcpListener- zero deps, but manual HTTP parsing is error-prone
Given that axum reuses almost the entire existing dependency tree and only adds 5 small crates, it's a good trade-off for correct, maintainable code.
|
Let me merge that, I think I may transform this into a Setting for people to opt-in, regardless of what OS they use, and there are a couple of nit I may do. Thank you, hopefully I can release that this week, if not, when you can build from sources in the meantime haha ( |
* Add local HTTP server for audio streaming on Linux This commit introduces a local HTTP server for streaming audio on Linux as a workaround for WebKitGTK's asset protocol limitations with media streaming and Range requests. Includes a `stream_server` module and necessary changes to TS and Tauri integration. * Refactor stream server plugin: centralize MIME type logic and simplify initialization
* Add local HTTP server for audio streaming on Linux This commit introduces a local HTTP server for streaming audio on Linux as a workaround for WebKitGTK's asset protocol limitations with media streaming and Range requests. Includes a `stream_server` module and necessary changes to TS and Tauri integration. * Refactor stream server plugin: centralize MIME type logic and simplify initialization
* Add local HTTP server for audio streaming on Linux This commit introduces a local HTTP server for streaming audio on Linux as a workaround for WebKitGTK's asset protocol limitations with media streaming and Range requests. Includes a `stream_server` module and necessary changes to TS and Tauri integration. * Refactor stream server plugin: centralize MIME type logic and simplify initialization
This commit introduces a local HTTP server for streaming audio on Linux as a workaround for WebKitGTK's asset protocol limitations with media streaming and Range requests. Includes a
stream_servermodule and necessary changes to TS and Tauri integration.I asked the Claude Opus AI agent to analyze this issue, and it came up with a working solution. This is its own review:
I didn't test these changes on Mac or Windows, but on Linux this is night and day type of improvement.
Fixes: #909, #912 any maybe some other related playback issues?