-
Notifications
You must be signed in to change notification settings - Fork 89
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature request: streaming torrents from disk and from memory #110
Comments
Hi, both aren't possible at the moment.
I'm not sure it makes sense without the second feature you're asking for. Torrents are multi-file (potentially), so one writer won't work, so what does it mean to write to smth else, when I'm requesting to download a torrent with 50 files? Conceptually, the operations that are working on the FS today are:
So it shouldn't be hard to write an abstraction where you provide all these somehow. But again, I'm not sure what's the use without streaming. And streaming probably makes sense only for one file at a time.
Some building blocks are there, but you'll need to rewrite a big chunk of TorrentStateLive (which is big). So it seems like it should be a completely different API. But if you combine the "make_peer_rx" with a custom implementation of PeerConnectionHandler + something that spawns peers, and queues needed pieces to them (TorrentStateLive does this today), then it could cover it. So in short, no, it's not available today, and is a pretty substantial amount of work, but possible. |
Btw @anacrolix, as you were contributing recently, maybe you have some thoughts on it, especially as you implemented another streaming client already |
I can only add that yes, it would certainly be possible, and it would end up looking much like how I did it in https://github.com/anacrolix/torrent. It's not trivial as it infects how request prioritisation, torrent state, and storage are handled. What you should definitely not do is download to files and then try to guess the state of the file and stream from disk without synchronization. As a workaround you could do the streaming part using a HTTP wrapper around https://github.com/anacrolix/torrent, like https://github.com/anacrolix/confluence. That would let you use Rust but do the streaming parts in Go (if that's palatable to you 😆, it's not particularly tasteful to myself anymore). I have considered moving to Rust with my streaming client/knowledge but I don't have adequate funding for the effort. I think rqbit could support it, the performance and fundamentals are very good. |
@cocool97 I've done both in #128, still testing, but seems to work fine Look at examples/storage.rs to for an example on how to pass in a custom storage, and in test_e2e_stream on how to stream a file. Streams are also available over HTTP Curious if this helps. I'll polish and test a bit then merge them into main. Don't know about storage backends, but streams are cool as you can paste the URL into e.g. VLC and jump around a video file way before it's fully downloaded. |
I'll continue the discussion here as you merged #128 and #129 ! Your API is fine, the notion of |
It already will request new data from peers when the stream is seeked (as long as the torrent is unpaused). |
I've kept testing your code with my torrent streaming project. Here is the URL is you want to take a look at it (URL) Integration was pretty easy and straightforward. I took your code to handle streaming server-side and your Technically, I think that is comes from the fact that torrent reading from peers is not driven by client-side (VLC e.g), meaning that both sides are decorrelate and this causes this issue.. Cannot storage be used only for readahead and let the streaming be done from clients directly ? |
The inmemory one is an example. You can write a storage that will work in a different way, or just use the disk one. However if what you're asking is if you can get away without any storage altogether and just stream from network, then the simple answer is it's not possible yet. |
Also from the bittorent protocol perspective it's not great to just download and not reshare. That's why other clients don't have that feature either. So what I suggest to you is just use the default disk storage, unselect the files you don't need (by passing "only_files" explicitly), and then stream. It will download the file in background, and if streams are alive, their pieces will be prioritized. |
Closing as this is done in 6.* versions |
Wow that's awesome |
@izissise here's an example of how to stream a file in librqbit https://github.com/ikatson/rqbit/blob/main/crates/librqbit/src/tests/e2e_stream.rs HTTP API: Web UI: once you click on the "cog" icon, the video files will point to the above HTTP API link. You can paste them into e.g. VLC or ffmpeg, and then you can seek in the video file while its being downloaded. |
I've got two questions about
rqbit
and its public API. I'm not interested in using the executable but would like to use the library directly (to use in another personal / open source project).How can I download a torrent to something other than a directory using it ? Could it be possible to implement downloading into a
Writer
, that could be a directory by default ?I do not think this is possible yet but would it be possible to implement a
Read
/Seek
interface onManagedTorrent
? This would allow for streaming / downloading only parts of torrent files (like done in https://github.com/anacrolix/torrent, but for Go @anacrolix) ?Thanks for you time and the amazing work !
The text was updated successfully, but these errors were encountered: