-
Notifications
You must be signed in to change notification settings - Fork 133
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
[QUESTION] Change starting offset time in custom manifest loader #1600
Comments
Hi, So if I get it right your start position calculation is too complex for what startAt allows? Can you tell us an example of such calculation? |
I need this for the live stream, for normal vod I can calculate proper position because I know range for the stream. |
Summarizing the main problem, live streaming is tricky due to a DVR window. Best results occur when the start position is within this range. If the start time is outside this range, it can cause the player to struggle. |
Yes when you start further than the DVR window, the player will have to wait because media segments aren't available yet for that position, you'll normally also have Where do you need to start? For example the |
Yes, I want to reduce that time, when position is outside DVR window, it works a lot of better when position is inside DVR window range, then player doesn't need to download not ready segents. When position is after the end of DVR window I'm using Also, about catching it in So my questions:
|
Right now, no. Though I'll have multiple things to check, which I'll try to do soon (tomorrow?):
So to summarize for me the right solution would be something like: rxPlayer.addEventListener("warning", (err) => {
if (err.code === "MEDIA_TIME_BEFORE_MANIFEST") {
const minimumPosition = rxPlayer.getMinimumPosition();
if (minimumPostion != null) {
rxPlayer.seekTo(rxPlayer.getMinimumPosition() + 5);
}
} else if (err.code === "MEDIA_TIME_AFTER_MANIFEST") {
const maximumPosition = rxPlayer.getMaximumPosition();
if (maximumPostion != null) {
rxPlayer.seekTo(rxPlayer.getMaximumPosition() - 5);
}
}
}); But I have to check that it's both performant (as in: called as soon as we can) and that it works as expected.
We avoid doing that ourselves because we don't know what the application would want in that case (e.g. applications could prefer displaying a warning if a particular program is not available anymore and play live content instead). There's also questions about what should we do if the end user pauses a content enough time that the position now fell behind the DVR window: Should we seek at the minimum position and play? Or seek and pause with the risk of very soon have to re-do it? Do nothing as the current frame is still visible anyway and wait for a Because of all those questions, we ended up preferring the exposition of an unopinionated lower-level API where we try to give an application the means to do what it wants to do. |
Though we understand that this is a situation that's easy to miss and that it can be assumed that the RxPlayer should be the one handling it. We do often hear developers who would have preferred that some specific logic ot be handled by the RxPlayer, so we're not totally closed to the idea of doing things our way in some cases. |
I looked more into it and there seem to actually be some bouding to the Manifest's minimum and maximum positions going down specifically for the rx-player/src/main_thread/init/utils/get_initial_time.ts Lines 88 to 131 in 2ca74e6
But this is actually worse here than doing nothing here, not only we don't have the warnings initially, but:
In most cases, at least multiple seconds should be added/removed from the max/min position for more efficient content start-up. So we're right now discussing on two elements on our side:
|
As #1600 signalled, there's currently no practical way to update the initial position (configured through the `startAt` `loadVideo` option) until `startAt` has actually been applied. More generally, it's not possible to perform a `seekTo` call until the initial seek has been performed on the content (the `seekTo` call will just be ignored). This commit proposes the following code updates to improve on that situation: 1. Tangentially related, we now schedule a JavaScript micro-task right at `ContentTimeBoundariesObserver`'s instantiation so the caller can catch `events` that were previously synchronously sent (I'm thinking here of the warnings for the `MEDIA_TIME_BEFORE_MANIFEST` and the `MEDIA_TIME_AFTER_MANIFEST` codes). Without this, we would wait for the next playback observation, which could happen a whole second later. 2. I noticed that the position indicated through the `startAt` `loadVideo` option was bounded so it's inside the `[minimumPosition, maximumPosition]` range (as obtained from the Manifest). As [stated here](#1600 (comment)) I personally think this is suboptimal. In my opinion, we should let the initial position go outside the range of the Manifest and let the application do its thing based on `MEDIA_TIME_BEFORE_MANIFEST` / `MEDIA_TIME_AFTER_MANIFEST` events. As to not totally change the behavior, I've only done so for dynamic contents (contents for which segments are added or removed, like live and contents that are being downloaded locally). VoD contents continue to have the previous behavior for now. 3. I added a "seek-blocking" mechanism to the `MediaElementPlaybackObserver` and made all seek operations, including the one from `seekTo` go through it. The idea is that when it is blocked (as it is initially), we'll delay any seek operation (by marking it as a "pending seek") and only seek to the last one of those once the `unblockSeeking` method is called (when the RxPlayer considers that the initial seek should be done). I also had to add `getPendingSeekInformation` method, sadly. I feel that we could do without it if we're smarter about things, but I wanted to avoid changing too much code here. I also thought about reworking the initial seek so it is completely handled by the `MediaElementPlaybackObserver` - as it could make everything simpler - but I chose for now to implement that less disruptive "seek-blocking" mechanism for now. Note that technically, we could still have an application directly updating the `HTMLMediaElement.property.currentTime` property, or even a web feature such as picture-in-picture doing that. I ensured that this eventuality did not break anything. Still, there will be a preference for pending seeks performed through the `MediaElementPlaybackObserver` over such "HTML5 seeks" performed during that time (if there is a "pending seek", we will apply it regardless of if an "HTML5 seek" happened since then). I'm now unsure if the `getPosition` or `getCurrentBufferGap` API should now return that planned position. I did nothing for those yet.
As #1600 signalled, there's currently no practical way to update the initial position (configured through the `startAt` `loadVideo` option) until `startAt` has actually been applied. More generally, it's not possible to perform a `seekTo` call until the initial seek has been performed on the content (the `seekTo` call will just be ignored). This commit proposes the following code updates to improve on that situation: 1. Tangentially related, we now schedule a JavaScript micro-task right at `ContentTimeBoundariesObserver`'s instantiation so the caller can catch `events` that were previously synchronously sent (I'm thinking here of the warnings for the `MEDIA_TIME_BEFORE_MANIFEST` and the `MEDIA_TIME_AFTER_MANIFEST` codes). Without this, we would wait for the next playback observation, which could happen a whole second later. 2. I noticed that the position indicated through the `startAt` `loadVideo` option was bounded so it's inside the `[minimumPosition, maximumPosition]` range (as obtained from the Manifest). As [stated here](#1600 (comment)) I personally think this is suboptimal. In my opinion, we should let the initial position go outside the range of the Manifest and let the application do its thing based on `MEDIA_TIME_BEFORE_MANIFEST` / `MEDIA_TIME_AFTER_MANIFEST` events. As to not totally change the behavior, I've only done so for dynamic contents (contents for which segments are added or removed, like live and contents that are being downloaded locally). VoD contents continue to have the previous behavior for now. 3. I added a "seek-blocking" mechanism to the `MediaElementPlaybackObserver` and made all seek operations, including the one from `seekTo` go through it. The idea is that when it is blocked (as it is initially), we'll delay any seek operation (by marking it as a "pending seek") and only seek to the last one of those once the `unblockSeeking` method is called (when the RxPlayer considers that the initial seek should be done). I also had to add `getPendingSeekInformation` method, sadly. I feel that we could do without it if we're smarter about things, but I wanted to avoid changing too much code here. I also thought about reworking the initial seek so it is completely handled by the `MediaElementPlaybackObserver` - as it could make everything simpler - but I chose for now to implement that less disruptive "seek-blocking" mechanism for now. Note that technically, we could still have an application directly updating the `HTMLMediaElement.property.currentTime` property, or even a web feature such as picture-in-picture doing that. I ensured that this eventuality did not break anything. Still, there will be a preference for pending seeks performed through the `MediaElementPlaybackObserver` over such "HTML5 seeks" performed during that time (if there is a "pending seek", we will apply it regardless of if an "HTML5 seek" happened since then). I'm now unsure if the `getPosition` or `getCurrentBufferGap` API should now return that planned position. I did nothing for those yet.
As #1600 signalled, there's currently no practical way to update the initial position (configured through the `startAt` `loadVideo` option) until `startAt` has actually been applied. More generally, it's not possible to perform a `seekTo` call until the initial seek has been performed on the content (the `seekTo` call will just be ignored). This commit proposes the following code updates to improve on that situation: 1. Tangentially related, we now schedule a JavaScript micro-task right at `ContentTimeBoundariesObserver`'s instantiation so the caller can catch `events` that were previously synchronously sent (I'm thinking here of the warnings for the `MEDIA_TIME_BEFORE_MANIFEST` and the `MEDIA_TIME_AFTER_MANIFEST` codes). Without this, we would wait for the next playback observation, which could happen a whole second later. 2. I noticed that the position indicated through the `startAt` `loadVideo` option was bounded so it's inside the `[minimumPosition, maximumPosition]` range (as obtained from the Manifest). As [stated here](#1600 (comment)) I personally think this is suboptimal. In my opinion, we should let the initial position go outside the range of the Manifest and let the application do its thing based on `MEDIA_TIME_BEFORE_MANIFEST` / `MEDIA_TIME_AFTER_MANIFEST` events. As to not totally change the behavior, I've only done so for dynamic contents (contents for which segments are added or removed, like live and contents that are being downloaded locally). VoD contents continue to have the previous behavior for now. 3. I added a "seek-blocking" mechanism to the `MediaElementPlaybackObserver` and made all seek operations, including the one from `seekTo` go through it. The idea is that when it is blocked (as it is initially), we'll delay any seek operation (by marking it as a "pending seek") and only seek to the last one of those once the `unblockSeeking` method is called (when the RxPlayer considers that the initial seek should be done). I also had to add `getPendingSeekInformation` method, sadly. I feel that we could do without it if we're smarter about things, but I wanted to avoid changing too much code here. I also thought about reworking the initial seek so it is completely handled by the `MediaElementPlaybackObserver` - as it could make everything simpler - but I chose for now to implement that less disruptive "seek-blocking" mechanism for now. Note that technically, we could still have an application directly updating the `HTMLMediaElement.property.currentTime` property, or even a web feature such as picture-in-picture doing that. I ensured that this eventuality did not break anything. Still, there will be a preference for pending seeks performed through the `MediaElementPlaybackObserver` over such "HTML5 seeks" performed during that time (if there is a "pending seek", we will apply it regardless of if an "HTML5 seek" happened since then). I'm now unsure if the `getPosition` or `getCurrentBufferGap` API should now return that planned position. I did nothing for those yet.
As #1600 signalled, there's currently no practical way to update the initial position (configured through the `startAt` `loadVideo` option) until `startAt` has actually been applied. More generally, it's not possible to perform a `seekTo` call until the initial seek has been performed on the content (the `seekTo` call will just be ignored). This commit proposes the following code updates to improve on that situation: 1. Tangentially related, we now schedule a JavaScript micro-task right at `ContentTimeBoundariesObserver`'s instantiation so the caller can catch `events` that were previously synchronously sent (I'm thinking here of the warnings for the `MEDIA_TIME_BEFORE_MANIFEST` and the `MEDIA_TIME_AFTER_MANIFEST` codes). Without this, we would wait for the next playback observation, which could happen a whole second later. 2. I noticed that the position indicated through the `startAt` `loadVideo` option was bounded so it's inside the `[minimumPosition, maximumPosition]` range (as obtained from the Manifest). As [stated here](#1600 (comment)) I personally think this is suboptimal. In my opinion, we should let the initial position go outside the range of the Manifest and let the application do its thing based on `MEDIA_TIME_BEFORE_MANIFEST` / `MEDIA_TIME_AFTER_MANIFEST` events. As to not totally change the behavior, I've only done so for dynamic contents (contents for which segments are added or removed, like live and contents that are being downloaded locally). VoD contents continue to have the previous behavior for now. 3. I added a "seek-blocking" mechanism to the `MediaElementPlaybackObserver` and made all seek operations, including the one from `seekTo` go through it. The idea is that when it is blocked (as it is initially), we'll delay any seek operation (by marking it as a "pending seek") and only seek to the last one of those once the `unblockSeeking` method is called (when the RxPlayer considers that the initial seek should be done). I also had to add `getPendingSeekInformation` method, sadly. I feel that we could do without it if we're smarter about things, but I wanted to avoid changing too much code here. I also thought about reworking the initial seek so it is completely handled by the `MediaElementPlaybackObserver` - as it could make everything simpler - but I chose for now to implement that less disruptive "seek-blocking" mechanism for now. Note that technically, we could still have an application directly updating the `HTMLMediaElement.property.currentTime` property, or even a web feature such as picture-in-picture doing that. I ensured that this eventuality did not break anything. Still, there will be a preference for pending seeks performed through the `MediaElementPlaybackObserver` over such "HTML5 seeks" performed during that time (if there is a "pending seek", we will apply it regardless of if an "HTML5 seek" happened since then). I'm now unsure if the `getPosition` or `getCurrentBufferGap` API should now return that planned position. I did nothing for those yet.
As #1600 signalled, there's currently no practical way to update the initial position (configured through the `startAt` `loadVideo` option) until `startAt` has actually been applied. More generally, it's not possible to perform a `seekTo` call until the initial seek has been performed on the content (the `seekTo` call will just be ignored). This commit proposes the following code updates to improve on that situation: 1. Tangentially related, we now schedule a JavaScript micro-task right at `ContentTimeBoundariesObserver`'s instantiation so the caller can catch `events` that were previously synchronously sent (I'm thinking here of the warnings for the `MEDIA_TIME_BEFORE_MANIFEST` and the `MEDIA_TIME_AFTER_MANIFEST` codes). Without this, we would wait for the next playback observation, which could happen a whole second later. 2. I noticed that the position indicated through the `startAt` `loadVideo` option was bounded so it's inside the `[minimumPosition, maximumPosition]` range (as obtained from the Manifest). As [stated here](#1600 (comment)) I personally think this is suboptimal. In my opinion, we should let the initial position go outside the range of the Manifest and let the application do its thing based on `MEDIA_TIME_BEFORE_MANIFEST` / `MEDIA_TIME_AFTER_MANIFEST` events. As to not totally change the behavior, I've only done so for dynamic contents (contents for which segments are added or removed, like live and contents that are being downloaded locally). VoD contents continue to have the previous behavior for now. 3. I added a "seek-blocking" mechanism to the `MediaElementPlaybackObserver` and made all seek operations, including the one from `seekTo` go through it. The idea is that when it is blocked (as it is initially), we'll delay any seek operation (by marking it as a "pending seek") and only seek to the last one of those once the `unblockSeeking` method is called (when the RxPlayer considers that the initial seek should be done). I also had to add `getPendingSeekInformation` method, sadly. I feel that we could do without it if we're smarter about things, but I wanted to avoid changing too much code here. I also thought about reworking the initial seek so it is completely handled by the `MediaElementPlaybackObserver` - as it could make everything simpler - but I chose for now to implement that less disruptive "seek-blocking" mechanism for now. Note that technically, we could still have an application directly updating the `HTMLMediaElement.property.currentTime` property, or even a web feature such as picture-in-picture doing that. I ensured that this eventuality did not break anything. Still, there will be a preference for pending seeks performed through the `MediaElementPlaybackObserver` over such "HTML5 seeks" performed during that time (if there is a "pending seek", we will apply it regardless of if an "HTML5 seek" happened since then). I'm now unsure if the `getPosition` or `getCurrentBufferGap` API should now return that planned position. I did nothing for those yet.
As #1600 signalled, there's currently no practical way to update the initial position (configured through the `startAt` `loadVideo` option) until `startAt` has actually been applied. More generally, it's not possible to perform a `seekTo` call until the initial seek has been performed on the content (the `seekTo` call will just be ignored). This commit proposes the following code updates to improve on that situation: 1. Tangentially related, we now schedule a JavaScript micro-task right at `ContentTimeBoundariesObserver`'s instantiation so the caller can catch `events` that were previously synchronously sent (I'm thinking here of the warnings for the `MEDIA_TIME_BEFORE_MANIFEST` and the `MEDIA_TIME_AFTER_MANIFEST` codes). Without this, we would wait for the next playback observation, which could happen a whole second later. 2. I noticed that the position indicated through the `startAt` `loadVideo` option was bounded so it's inside the `[minimumPosition, maximumPosition]` range (as obtained from the Manifest). As [stated here](#1600 (comment)) I personally think this is suboptimal. In my opinion, we should let the initial position go outside the range of the Manifest and let the application do its thing based on `MEDIA_TIME_BEFORE_MANIFEST` / `MEDIA_TIME_AFTER_MANIFEST` events. As to not totally change the behavior, I've only done so for dynamic contents (contents for which segments are added or removed, like live and contents that are being downloaded locally). VoD contents continue to have the previous behavior for now. 3. I added a "seek-blocking" mechanism to the `MediaElementPlaybackObserver` and made all seek operations, including the one from `seekTo` go through it. The idea is that when it is blocked (as it is initially), we'll delay any seek operation (by marking it as a "pending seek") and only seek to the last one of those once the `unblockSeeking` method is called (when the RxPlayer considers that the initial seek should be done). I also had to add `getPendingSeekInformation` method, sadly. I feel that we could do without it if we're smarter about things, but I wanted to avoid changing too much code here. I also thought about reworking the initial seek so it is completely handled by the `MediaElementPlaybackObserver` - as it could make everything simpler - but I chose for now to implement that less disruptive "seek-blocking" mechanism for now. Note that technically, we could still have an application directly updating the `HTMLMediaElement.property.currentTime` property, or even a web feature such as picture-in-picture doing that. I ensured that this eventuality did not break anything. Still, there will be a preference for pending seeks performed through the `MediaElementPlaybackObserver` over such "HTML5 seeks" performed during that time (if there is a "pending seek", we will apply it regardless of if an "HTML5 seek" happened since then). I'm now unsure if the `getPosition` or `getCurrentBufferGap` API should now return that planned position. I did nothing for those yet.
As #1600 signalled, there's currently no practical way to update the initial position (configured through the `startAt` `loadVideo` option) until `startAt` has actually been applied. More generally, it's not possible to perform a `seekTo` call until the initial seek has been performed on the content (the `seekTo` call will just be ignored). This commit proposes the following code updates to improve on that situation: 1. Tangentially related, we now schedule a JavaScript micro-task right at `ContentTimeBoundariesObserver`'s instantiation so the caller can catch `events` that were previously synchronously sent (I'm thinking here of the warnings for the `MEDIA_TIME_BEFORE_MANIFEST` and the `MEDIA_TIME_AFTER_MANIFEST` codes). Without this, we would wait for the next playback observation, which could happen a whole second later. 2. I noticed that the position indicated through the `startAt` `loadVideo` option was bounded so it's inside the `[minimumPosition, maximumPosition]` range (as obtained from the Manifest). As [stated here](#1600 (comment)) I personally think this is suboptimal. In my opinion, we should let the initial position go outside the range of the Manifest and let the application do its thing based on `MEDIA_TIME_BEFORE_MANIFEST` / `MEDIA_TIME_AFTER_MANIFEST` events. As to not totally change the behavior, I've only done so for dynamic contents (contents for which segments are added or removed, like live and contents that are being downloaded locally). VoD contents continue to have the previous behavior for now. 3. I added a "seek-blocking" mechanism to the `MediaElementPlaybackObserver` and made all seek operations, including the one from `seekTo` go through it. The idea is that when it is blocked (as it is initially), we'll delay any seek operation (by marking it as a "pending seek") and only seek to the last one of those once the `unblockSeeking` method is called (when the RxPlayer considers that the initial seek should be done). I also had to add `getPendingSeekInformation` method, sadly. I feel that we could do without it if we're smarter about things, but I wanted to avoid changing too much code here. I also thought about reworking the initial seek so it is completely handled by the `MediaElementPlaybackObserver` - as it could make everything simpler - but I chose for now to implement that less disruptive "seek-blocking" mechanism for now. Note that technically, we could still have an application directly updating the `HTMLMediaElement.property.currentTime` property, or even a web feature such as picture-in-picture doing that. I ensured that this eventuality did not break anything. Still, there will be a preference for pending seeks performed through the `MediaElementPlaybackObserver` over such "HTML5 seeks" performed during that time (if there is a "pending seek", we will apply it regardless of if an "HTML5 seek" happened since then). I'm now unsure if the `getPosition` or `getCurrentBufferGap` API should now return that planned position. I did nothing for those yet.
Hi 👋
Is it possible to change start position during custom manifest loading?
So we want to start stream from certain position using loadVideo method, e.g.
Set base loadVideo config:
Parse manifest data and modify offset:
So far I have logic where
loadVideo
is called and then after stream is readyseekTo
, so yep it's not the most efficient.I will be grateful for your help ;)
The text was updated successfully, but these errors were encountered: