Skip to content

fix: streaming video by adding a limit to streaming chunks#1949

Merged
joachimvh merged 1 commit intoCommunitySolidServer:mainfrom
jaxoncreed:fix/issue-1948
Oct 14, 2024
Merged

fix: streaming video by adding a limit to streaming chunks#1949
joachimvh merged 1 commit intoCommunitySolidServer:mainfrom
jaxoncreed:fix/issue-1948

Conversation

@jaxoncreed
Copy link
Contributor

📁 Related issues

Fixes #1948

✍️ Description

Firefox and Chrome both use range headers with ambiguous endings to stream video (for example range: 0- rather than range: 0-5000000). As built, CSS was trying to deliver an entire video in a single request because of this. This lead to long load times for large videos.

I followed the solution posed by Zeng Xu (https://www.zeng.dev/post/2023-http-range-and-play-mp4-in-browser/) and arbitrarily added a default number of bytes to deliver if the byte range end wasn't provided. This works on Firefox, Chrome, and Safari.

Unfortunately, this does break RFC 7233 (https://www.rfc-editor.org/rfc/rfc7233#section-2.1), but as of this moment, it is the only way I found to get streaming video to work on Firefox and Chrome.

✅ PR check list

Before this pull request can be merged, a core maintainer will check whether

  • [?] this PR is labeled with the correct semver label
    • semver.patch: Backwards compatible bug fixes.
    • semver.minor: Backwards compatible feature additions.
    • semver.major: Breaking changes. This includes changing interfaces or configuration behaviour.
  • the correct branch is targeted. Patch updates can target main, other changes should target the latest versions/* branch.
  • [] the RELEASE_NOTES.md document in case of relevant feature or config changes.
  • any relevant documentation was updated to reflect the changes in this PR.

Copy link
Member

@joachimvh joachimvh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor changes requested.

RELEASE_NOTES.md Outdated
- The `StaticAssetHandler` can now be used to link static pages to containers.
This can be used to set a static page for the root container of a server.
See the `/config/app/init/static-root.json` config for an example.
- Streaming video now works on Firefox and Chrome.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I implemented this I tested on Firefox and video streaming worked for me. But I'm guessing the difference is specifically for large videos?
But this line shouldn't be added here, these were the release notes for v7.0.0. Fixes like this one will just be mentioned in the github release.

import type { ResponseDescription } from '../output/response/ResponseDescription';
import type { OperationHandlerInput } from './OperationHandler';
import { OperationHandler } from './OperationHandler';

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unneeded change

protected readonly logger = getLoggerFor(this);
private readonly defaultSliceSize: number;

public constructor(source: T, defaultSliceSize: number) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public constructor(source: T, defaultSliceSize: number) {
public constructor(source: T, defaultSliceSize = 0) {

This needs to be an optional parameter to not be a breaking change. And just in general it's not bad to have this be optional.

const size = termToInt(result.metadata.get(POSIX.terms.size));

// Set the default end size if not set already
if (typeof end !== 'number' && typeof size === 'number' && start >= 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (typeof end !== 'number' && typeof size === 'number' && start >= 0) {
if (this.defaultSliceSize > 0 && typeof end !== 'number' && typeof size === 'number' && start >= 0) {

Comment on lines 61 to 62
const adustedEnd = start + this.defaultSliceSize - 1;
end = adustedEnd < size ? adustedEnd : size - 1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const adustedEnd = start + this.defaultSliceSize - 1;
end = adustedEnd < size ? adustedEnd : size - 1;
end = Math.min(size, start + this.defaultSlizeSize) - 1;

@@ -24,6 +24,12 @@ import type { ResourceStore } from './ResourceStore';
*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
*/
*
* The `defaultSliceSize` parameter can be used to set how large a slice should be if the end of a range is not defined.
* Setting this to 0, which is the default, will cause the end of the stream to be used as the end of the slice.
*/

@jaxoncreed
Copy link
Contributor Author

Fantastic. I've made the adjustments.

Copy link
Member

@joachimvh joachimvh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. I'll do a new release with this soon.

@joachimvh joachimvh merged commit b8bcec9 into CommunitySolidServer:main Oct 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Streaming video does not work (fix in progress)

2 participants