AgregoreWeb / agregore-browser

A minimal browser for the distributed web (Desktop version)
https://www.youtube.com/watch?v=TnYKvOQB0ts&list=PL7sG5SCUNyeYx8wnfMOUpsh7rM_g0w_cu&index=14
GNU Affero General Public License v3.0
741 stars 66 forks source link

p2p live streaming #117

Open resession opened 3 years ago

resession commented 3 years ago

talked about it on discord. putting it down here as well to refer back to it in case its something that gets worked on. would be great to have a way to live stream media especially video through p2p. from my reading and research, hypercore would be the best for live streaming media/data.

from the discord discussion


zaaz: out of all the p2p protocols i read about, hyper seems most suited for streaming media. a while ago i read this page https://louis.center/p2p-hypervision very interesting stuff. would p2p live streaming media be possible in agregore? or would something like that be out of the scope for agregore and too laborious?

Mauve: @ zaaz It should be possible, hyperdrive actually has a built-in feature for opening a file as a separate hypercore and adding to it on its own, however I don't have a nice interface for that exposed yet. Thoughts on how it would fit with the fetch interface would be welcome.

zaaz: wouldn't know where to start with the fetch interface since it's a stream and not a one and done request. hope the community and other folks have some ideas for that

Mauve: @ zaaz Yeah, that's fair. It should be possible to do it by emulating the same methods that regular websites used to stream video through http. For example using HTTP get to stream chunks of the fallout as it's coming out, I'm not sure what the go-to method is for uploading though. I think there's actually a way to upload a stream with fetch, but I'm not sure how well that'd play with electron


if folks have any thoughts or ideas about this, would love to hear it. p2p live streaming would be great

RangerMauve commented 3 years ago

This would be good to have.

Some stuff that would help a lot in getting this through is examples of how other platforms do live streaming via HTTP.

Namely, what does the HTTP request look like when you GET a source a video, and what does it look like to POST data to it (if that's even what they do).

Cc @benhylau who has done some live streaming with p2p before. I think in their case they had a manifest file that they'd periodically poll to get updates and load the latest data from there. Might be possible to make an even more efficient version of that with the new change listener stuff in the hyper protocol. 😁

resession commented 3 years ago

read a little about it with http

multiple ways to stream, the two is have seen is the do-it-yourself way and the hls way(http live streaming)

with live streams, a get request is sent. now how the get request is handled and responded is what makes the difference. the do-it-yourself way is just chunking the files your self and sending those chunks. the hls way is having segments of the file in a .m3u8 file and then getting those segments from the .m3u8 file(each segment is about 6 seconds each and has a url). so no PUT/POST, only GET.

seems like, GET: http://somedomain.com/somevideofile.extension > response(diy is chucks of the file, hls is .m3u8 with the segments and their urls)

so now just gotta figure out the p2p/hyper/fetch version of that

RangerMauve commented 3 years ago

Sweet. We might be able to make use of existing HLS streaming mechanisms, then.

I'd imagine that you could test it by having some HLS files published in a hyperdrive to start, and then see if existing video players can just support the hyper:// URL to the m3u8 file or if there's more that needs to be done.

From there it might be good to see if there's existing things out there for generating m3u8 files and HLS streams using JS in the browser. Once you generate the file in the browser it should be pretty straighforward to upload it to a hyperdrive using POST and fetch.

resession commented 3 years ago

couple of issue i can see that can come up is the .m3u8 file uses http urls inside the file(iirc). we would have to find out if we can not only use hyper::// to get the .m3u8 file but also if we can use hyper urls inside the .m3u8 file.

also, for it to be p2p. we probably don't want the single video/file source to be sending data to everyone else, then it would defeat the point of p2p. all peers should be sending data to new peers that connect. so not, user 1 -> sends chunks to everyone else one way, but this, user 1 streams -> other users consume data -> current users with data already -> helps and sends data to newer users that connect which need data.

this link https://louis.center/p2p-hypervision describes the second path. peers that already has data from the stream, helps newer peers. hyper should be suited for this. just gotta find a way to put it together(.m3u8 and all that).

so to do:

  1. how can we make m3u8 files work with hyper:// and also have hyper:// urls inside the m3u8 file(because if the urls inside the file is still http then its single source, which leads to the next thing)
  2. how can we make sure current peers helps send and spread stream data to new peers(if number 1 is answered then this should not be an issue)

i'll play around and see what happens

RangerMauve commented 3 years ago

My gut feeling is that m3u8 files that only use relative URLs should work if the players can handle hyper:// URLs. If anything this is something that shouldn't be too hard to modify. They might just have a hardcoded url.startsWith('http') in there or something.

Regarding spreading data, the protocol should handle that automatically. As soon as a peer has a chunk of data it'll be re-sharing it with all other peers. So even if a single peer is adding to the hyperdrive, the load should be getting balanced based on who's connected to who. This might result in a bit more lag for some, but I think everything is in 30 second increments anyways so the watchers will be a little behind anyway.

benhylau commented 3 years ago

Here are the key files we used for ipfs live streaming:

Cc @benhylau who has done some live streaming with p2p before. I think in their case they had a manifest file that they'd periodically poll to get updates and load the latest data from there. Might be possible to make an even more efficient version of that with the new change listener stuff in the hyper protocol. 😁

I think polling the player is the job of the video player. We basically write IPFS CIDs into the m3u8 from what I recall.

RangerMauve commented 3 years ago

This sort of application might be useful for a IPFS microgrant.

E.g. if you specify that you want to use multiple protocols (including IPFS) for live streaming in Agregore. I'm down to apply jointly with somebody and provide support while they take the wheel. 😁

SionoiS commented 2 years ago

Hello! @RangerMauve sent me a link to this here discussion.

I've been working on live streaming on IPFS for the past year. Here's what I've done.

Instead of using HLS and .m3u8 files and trying to shoehorn IPFS in there I built the required metadata using IPLD. It replicate the same features as HLS and more. The same DAG structure can do both live and pre-recorded video adaptative bitrate streaming plus live chat.

Addressing is easy ipfs://LATESTVIDEOSEGMENTCID/tracks/1080p60 when receiving the latest CID from PubSub.

For pre-recorded video do ipfs://VIDEOCID/time/hour/0/minute/2/second/57/video/tracks/720p30 for each video segments. You can also do ipfs://VIDEOCID/time/hour/0/minute/2/second/57/chat/3 to get the 3# chat message.

You can check the IPLD schemas here https://github.com/Defluencer/rust-linked-data#streams

resession commented 2 years ago

instead of going the .m3u8 file route, what about just using the range header? should be easier.

watched this, https://www.youtube.com/watch?v=ZjBLbXUuyWg

while this would be bad for regular server-client setup(for example if a user seeks forward or backward, then that is another request), for p2p/make-fetch, this should work great. using this way, we can skip .m3u8 file and just directly request for the file itself. except only get chunks, if the user has not asked for a specific range, we can give them 1 percent of the start of the file(random idea). just ideas, but this can be played around with and we can come up with variations. this way instead of having hypercore/ipfs split the file into chunks with their own links which might make things slower, we can have a way for live streaming in the fetch level.

Pantyhose-X commented 1 year ago

libp2p and

watched this https://github.com/Glimesh/broadcast-box#peer-to-peer-if-you-need-it Run Broadcast Box on the same machine that you are running OBS, and share your video with the world! WebRTC comes with P2P technology, so users can broadcast and playback video without paying for dedicated servers.

SionoiS commented 1 year ago

watched this https://github.com/Glimesh/broadcast-box#peer-to-peer-if-you-need-it

Run Broadcast Box on the same machine that you are running OBS, and share your video with the world! WebRTC comes with P2P technology, so users can broadcast and playback video without paying for dedicated servers.

Correct me if i'm wrong but with WebRTC you can't have more viewers than the size of your connection no?

Does it actually create a p2p network? Can it do 1000s of viewers with a broadcaster connection speed 2-3x the speed of a video stream?

RangerMauve commented 1 year ago

Correct me if i'm wrong but with WebRTC you can't have more viewers than the size of your connection no?

By default yes, but there's setups where instead of having a star topology you create a mesh where peers rebroadcast data to other peers. Generally this means you get really bad latency as peers get further out, though. :x

SionoiS commented 1 year ago

Correct me if i'm wrong but with WebRTC you can't have more viewers than the size of your connection no?

By default yes, but there's setups where instead of having a star topology you create a mesh where peers rebroadcast data to other peers. Generally this means you get really bad latency as peers get further out, though. :x

Is the latency increase due to the path in the mesh being not optimal or is the implementation not spreading the stream fast?

The theoretical min latency possible would be the shortest path in the mesh plus each intra-node latency.

RangerMauve commented 1 year ago

I think the intra-node latency is what will eventually add up. Generally it's not realistic to handle more than 2/3 video streams per p2p node (in a full mesh) and that also varies per device. So those extra hops would add up.

I think it depends on how big a swarm you have and how strong the devices are. It's a pretty tricky challenge.

SionoiS commented 1 year ago

I've been thinking about this for some time now.

Since live streaming has a single point of origin, one could build a kind of directionality in the mesh using latency information.

Nodes would have to organize themselves to get their stream from the lowest latency source possible (that is not overloaded) and push the stream to the highest latency nodes connected to them.

Of course you would have the same free-rider problem than with Bittorrent and IPFS (I'm super overloaded guys I swear!). I'm not sure how to deal with that yet.