Hello!
Can someone give a plan for the simplest implementation of shaka-p2p loader for a shaka-beginner? )
Just basic and required steps.
Thanks in advance )
Hi @sapolio
Could you elaborate on your use case? I'm familiar with the p2p concept for networks and stuff, but not super sure what a p2p loader entails in this context. Would be happy to advise once we understand your use case better!
In short, you can register a network scheme plugin that will be called by Shaka Player to handle network requests. You can then handle them using some p2p scheme, likely over WebRTC. We designed our plugin system to accommodate this use case, but we have never implemented any p2p features in Shaka Player directly.
There is a brief doc outlining the plugin interfaces, with links to APIs and implementations of them. From there, you can find links to the registerScheme method, the SchemePlugin definition, and the implementation of our default HTTP plugin HttpFetchPlugin.
If you aren't interested in implementing this yourself, but just want to use an existing implementation, a quick google search turned up an existing p2p scheme implemented on top of Shaka Player. This was not created by the Shaka Player team, so we can't make any promises about it or offer any support:
https://www.npmjs.com/package/p2p-media-loader-shaka
The latest version seems to have been published by @mrlika, who may be able to offer you further assistance if you're interested in that. You can also find their issue tracker here: https://github.com/Novage/p2p-media-loader/issues
Hi!
@ismena
Thank you for your concern.
I have a task to make a plugin (or whatever) to make shaka load chunks using already implemented p2p. Its frontend API has, briefly, two functions: to load chunk (via p2p or CDN. The core chooses the download method) and to abort loading. For example, in hlsjs, you can override the loader class to use your p2p library.
@joeyparrish
Thank you a lot for the advices!
I've already started to explore p2p-media-loader, it's cool, but it's still too complicated for me. I have to start with something more basic. )
I'm sure it will help me in the future.
Well, if you're implementing your own scheme plugin, you'll just need to be able to take an array of URIs (override http/https or make up and register your own scheme), and return a ByteArray of the response data. Let us know if you need more pointers than the ones I listed above, or if you need any specific advice along the way.
@sapolio Does this answer all your questions? Can we close the issue?
Hello.
I managed to use fragments loaded via my P2P core.
But I still have a couple of questions. )
I had to copy-paste _shaka.net.HttpPluginUtils.makeResponse_ method into my code, because I couldn't find it in _shaka.net_ object. Is there a better way?
My response looks like so:
data: Uint8Array(160098) [0, 0, 0, 24, 115, 鈥
fromCache: false
headers: {}
originalUri: "stream uri"
timeMs: 97
uri: "the same stream uri"
And I don't yet understand if the _headers_ object is important to something. I left it blank because my p2p doesn't give away any headers. _FromCache_ is always _false_ because of this. I don't know if it matters.
_originalUri_ and _uri_ are always the same string. I as well don't know if it matters.
Anyway, I have some positive stats on loading chunks via p2p, so thanks for your advice! )
See the docs for more info on what this structure contains.
That makeResponse method just takes an HTTP status code and creates the response object or throws an error; you don't have to do that depending on how your p2p channel signals errors or success. All you need to do is create that response object and return it, or throw an error.
The headers object contains the response headers, which can be empty if you don't have any. I think the only use so far is getting the Date header in the DASH parser when using the UTCTiming element.
originalUri should be the URI given to the plugin, uri should be the URI after any redirects (if any). It is fine if they are the same so long as there was no redirects.
You should probably not set the timeMs field. That is used by ABR to calculate how long it took to download the segment. You should only set this field if you downloaded the segment before. Otherwise you should leave it unset and we'll calculate it based on how long the function call took. This will ensure accurate ABR calculations.
Response is a plain javascript object without any magic. You can create it like:
const response = { data: new ArrayBuffer(100) };
All other fields are not required.
In P2P Media Loader we create response object with different set of fields depending on situation:
Downloading an asset (manifest, key, init segment etc.) using shaka.net.HttpXHRPlugin that returns response promise:
https://github.com/Novage/p2p-media-loader/blob/136084877460373a31bb7ab9eb231f1807cb1744/p2p-media-loader-shaka/lib/integration.ts#L127
Getting an asset from assets storage (like indexedDB cache):
https://github.com/Novage/p2p-media-loader/blob/136084877460373a31bb7ab9eb231f1807cb1744/p2p-media-loader-shaka/lib/integration.ts#L121
Getting segments using P2P algorithm (the function returns response promise with data and timeMs fields set):
https://github.com/Novage/p2p-media-loader/blob/136084877460373a31bb7ab9eb231f1807cb1744/p2p-media-loader-shaka/lib/segment-manager.ts#L74
@sapolio Does this answer all your questions? Can we close the issue?
Sorry, I've been away for a while.
Thank you very much, @mrlika !
@TheModMaker thank you too.
I have no more questions at the moment.