Skip to content

Design proposal: #47685 Add blob() method to JS side of Blazor DotNetStreamReference #61826

Open
@MaxxBahr

Description

@MaxxBahr

Summary

Add a blob([mimeType: string]) method to DotNetStreamReference in Blazor, allowing developers to obtain a Blob from a .NET stream in JavaScript, without fully loading the stream into memory. We chose this specific issue, because it is a "good-first-issue" and we are participating in a germany wide competition, where the subject is to work on issues in open source projects.
Link to issue: #47685

Motivation and goals

Blazor developers can currently pass .NET streams to JavaScript using DotNetStreamReference, which exposes two main methods:

  • stream() (returns a ReadableStream)
  • arrayBuffer() (loads the full stream into memory)

The problem:

  • There is no direct way to obtain a Blob, which is required for many web APIs (like <video> elements, file downloads or drag-and-drop functionality).
  • arrayBuffer() is not suitable for large files (like videos) because it fully buffers the stream in memory before use.
  • Using stream() gives a ReadableStream, but many APIs (like <video src=...>, URL.createObjectURL()) require a Blob, not a stream, and converting a ReadableStream into a Blob in JS is non-trivial and inefficient.

Adding a blob() method would:

  • Allow efficient handling of large files (like video or audio) without consuming excessive memory.
  • Simplify developer workflows by aligning with common web APIs that expect a Blob.
  • Close a usability gap in the current Blazor-JS interop system.

In scope

  • A new method blob([mimeType: string]) on DotNetStreamReference that returns a Blob representing the .NET stream.
  • Ensuring the Blob can be used with standard web APIs (e.g., <video>, <audio>, URL.createObjectURL()).
  • Keeping performance and memory usage efficient for large streams.

Out of scope

  • Changes to the existing stream() or arrayBuffer() methods.
  • Polyfills for browsers that lack Blob support (modern browsers are assumed).
  • Enhancements to streaming APIs beyond providing the Blob.

Risks / unknowns

  • Browser behavior: While Blobs are widely supported, the implementation detail of
    streaming data into a Blob without full buffering might depend on browser internals.
    Some browsers may still buffer the entire Blob in memory before making it available.

  • Memory use: Even if we avoid buffering in .NET or JS, the underlying browser may still
    end up consuming memory when the Blob is accessed, especially for very large files.

  • Implementation complexity: Creating a Blob from a .NET stream across JS interop
    might require platform-level work to ensure true streaming behavior rather than just
    buffering and converting.

Examples

Blazor usage example

<video @ref="videoPlayer" controls autoplay></video>

<button @onclick="PlayVideo">Play Streamed Video</button>

@code {
    private ElementReference videoPlayer;

    private async Task PlayVideo()
    {
        using var fileStream = File.OpenRead("bigvideo.mp4");
        var streamRef = new DotNetStreamReference(fileStream);

        // JS call to create a blob URL from the .NET stream
        var videoUrl = await JS.InvokeAsync<string>("createVideoBlobUrl", streamRef);

        // Set the video source
        await JS.InvokeVoidAsync("setVideoSrc", videoPlayer, videoUrl);
    }
}

JavaScript interop

window.createVideoBlobUrl = async function (streamRef) {
    const blob = await streamRef.blob("video/mp4");
    return URL.createObjectURL(blob);
};

window.setVideoSrc = function (videoElement, src) {
    videoElement.src = src;
};

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-blazorIncludes: Blazor, Razor Componentsdesign-proposalThis issue represents a design proposal for a different issue, linked in the descriptiongood first issueGood for newcomers.help wantedUp for grabs. We would accept a PR to help resolve this issue

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions