Skip to content

Add stream media source#3181

Merged
TheCodeTraveler merged 56 commits into
CommunityToolkit:mainfrom
matt-goldman:add-stream-media-source
May 11, 2026
Merged

Add stream media source#3181
TheCodeTraveler merged 56 commits into
CommunityToolkit:mainfrom
matt-goldman:add-stream-media-source

Conversation

@matt-goldman
Copy link
Copy Markdown
Contributor

Description of Change

Adds StreamMediaSource support to MediaElement so media can be played directly from a .NET Stream.

This is intended for scenarios where media should remain in memory or within the app sandbox, rather than being written out to a file or fetched from an external URL. It enables workflows such as capturing or generating media in-memory and previewing it before persisting it.

The change adds a new MediaSource subtype and wires it through the existing MediaElement pipeline on supported platforms:

  • Windows: uses WinMediaSource.CreateFromStream with IRandomAccessStream conversion
  • Android: uses a custom ExoPlayer IDataSource implementation backed by Stream
  • iOS/macOS: uses AVAssetResourceLoader to serve stream data to AVPlayer
  • Tizen: explicitly reports stream playback as unsupported

The API follows the existing MediaSource patterns, including a MediaSource.FromStream(Stream) factory method and direct use of StreamMediaSource.

Linked Issues

PR Checklist

Additional information

  • This work is currently linked to discussion 2968 rather than a formal issue.
  • The feature proposal originated from secure-app scenarios where media must remain in-memory and within the app sandbox.
  • Sample app updates are included to demonstrate stream-backed playback.
  • Tizen is not supported at this stage and reports that limitation explicitly.
  • Tested platforms: Windows, Android, iOS/macOS as applicable to the implementation.

What Was Added

Core Class

  • StreamMediaSource.shared.cs: New MediaSource subclass that wraps a .NET Stream
    • Includes Stream bindable property
    • Implicit operators for convenient Stream conversion
    • Factory method MediaSource.FromStream(Stream)
    • Follows the same pattern as FileMediaSource, UriMediaSource, and ResourceMediaSource

Platform-Specific Implementations

Windows (MediaManager.windows.cs)

  • Implementation: Uses WinMediaSource.CreateFromStream() with IRandomAccessStream
  • Status: ✅ Fully Supported
  • Method: Leverages WindowsRuntimeStreamExtensions.AsRandomAccessStream() to convert .NET streams to Windows Runtime streams
  • Helper: StreamExtensions.windows.cs - Provides GetMimeType() extension method

Android (MediaManager.android.cs)

  • Implementation: Custom StreamDataSource implementing ExoPlayer's IDataSource interface
  • Status: ✅ Fully Supported
  • Method: Created custom data source that reads from .NET Stream and integrates with ExoPlayer's ProgressiveMediaSource
  • Helper: StreamDataSource.android.cs - Contains StreamDataSource and StreamDataSourceFactory classes
  • Features:
    • Supports seeking if stream is seekable
    • Handles range requests
    • Proper resource cleanup and disposal

iOS/macOS (MediaManager.macios.cs)

  • Implementation: Uses AVAssetResourceLoaderDelegate to provide custom data source
  • Status: ✅ Fully Supported
  • Method: Creates custom URL scheme (stream://media) and uses AVAssetResourceLoader to intercept loading requests
  • Helper: StreamAssetResourceLoader.macios.cs - Custom delegate that feeds stream data to AVPlayer
  • Features:
    • Works with both audio and video
    • Supports seeking if stream is seekable
    • Integrates seamlessly with existing AVPlayer architecture

Tizen (MediaManager.tizen.cs)

  • Status: ❌ Not Supported
  • Reason: Platform limitation - throws NotSupportedException with helpful message

Usage Examples

// Using factory method
MediaSource source = MediaSource.FromStream(myStream);

// Using implicit conversion
MediaSource source = myStream;

// Direct instantiation
var streamSource = new StreamMediaSource { Stream = myStream };

// Assigning to MediaElement
mediaElement.Source = MediaSource.FromStream(myStream);

Files Modified

New Files

  1. MediaSource/StreamMediaSource.shared.cs - Core class
  2. Platforms/Android/StreamDataSource.android.cs - Android implementation
  3. Views/StreamAssetResourceLoader.macios.cs - iOS/macOS implementation
  4. Views/StreamExtensions.windows.cs - Windows helper extensions

Modified Files

  1. MediaSource/MediaSource.shared.cs - Added FromStream() factory method
  2. Views/MediaManager.android.cs - Added stream support via custom DataSource
  3. Views/MediaManager.windows.cs - Added stream support via CreateFromStream()
  4. Views/MediaManager.macios.cs - Added stream support via AVAssetResourceLoader
  5. Views/MediaManager.tizen.cs - Added NotSupportedException for streams
  6. Converters/MediaSourceConverter.shared.cs - Added StreamMediaSource case

Technical Details

Android Implementation

The Android implementation uses ExoPlayer's extensibility model:

  • StreamDataSource implements IDataSource interface
  • Reads data from .NET Stream on demand
  • StreamDataSourceFactory creates instances for ExoPlayer
  • Integrates with ProgressiveMediaSource.Factory

iOS/macOS Implementation

The iOS/macOS implementation uses Apple's official extension mechanism:

  • Creates AVUrlAsset with custom URL scheme
  • AVAssetResourceLoaderDelegate intercepts resource loading requests
  • Provides stream data through AVAssetResourceLoadingDataRequest
  • Supports both content information and data requests

Windows Implementation

The Windows implementation uses built-in .NET stream conversion:

  • Converts .NET Stream to IRandomAccessStream using AsRandomAccessStream()
  • Uses WinMediaSource.CreateFromStream() API
  • Provides default MIME type (can be enhanced for better type detection)

Considerations

Stream Lifecycle

  • Streams are not automatically disposed by the MediaElement
  • Callers are responsible for managing stream lifetime
  • Consider keeping streams open for the duration of playback
  • Seeking requires seekable streams

MIME Type Detection

  • Windows: Returns generic "application/octet-stream" by default
  • iOS/macOS: Defaults to "video/mp4" assumption
  • Future enhancement: Could detect MIME type from stream content (magic bytes)

Performance

  • Streams should support efficient random access for best performance
  • Non-seekable streams may have limited functionality
  • Consider buffering strategies for network streams

Future Enhancements

  1. MIME Type Detection: Implement magic byte detection to automatically determine content type
  2. Tizen Support: Investigate if Tizen platform can support stream-based playback
  3. Stream Properties: Add optional properties to StreamMediaSource for MIME type hint
  4. Buffering Options: Add configurable buffering strategies for different stream types
  5. Progress Reporting: Add stream read progress callbacks for monitoring

Copilot AI review requested due to automatic review settings April 3, 2026 02:12
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR primarily adds Stream-backed playback to CommunityToolkit.Maui.MediaElement via a new StreamMediaSource, with platform implementations for Windows/Android/iOS(+macOS) and an explicit “not supported” path on Tizen. It also includes several related refactors and fixes across Popup/StateContainer, source-generator infrastructure, analyzers, tests, CI, and the sample app.

Changes:

  • Add StreamMediaSource + platform-specific playback wiring (Windows CreateFromStream, Android ExoPlayer IDataSource, iOS/macOS AVAssetResourceLoader).
  • Introduce Android MediaElement foreground-service configuration plumbing (options, generator/test projects) and update initialization call sites.
  • Assorted toolkit fixes/refactors (Popup close edge-cases, StateContainer defaults/validation, AppThemeResource lookup) with corresponding unit tests.

Reviewed changes

Copilot reviewed 117 out of 126 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/CommunityToolkit.Maui/Views/Popup/PopupPage.shared.cs Refines popup close edge-case detection and default-value converters.
src/CommunityToolkit.Maui/Views/Popup/Popup.shared.cs Adjusts popup defaults initialization and makes popup exceptions public/documented.
src/CommunityToolkit.Maui/Services/PopupService.shared.cs Refactors popup content resolution to avoid extra DI constructions.
src/CommunityToolkit.Maui/Primitives/StateContainerDefaults.shared.cs Removes shared static default StateViews instance.
src/CommunityToolkit.Maui/Primitives/BindablePropertySourceGeneratorPrimitives/BindablePropertyDiagnostics.shared.cs Adds public diagnostic ID constants for generator attributes.
src/CommunityToolkit.Maui/Primitives/BindablePropertySourceGeneratorPrimitives/BindablePropertyAttribute.shared.shared.cs Adds runtime BindablePropertyAttribute (experimental) for generator use.
src/CommunityToolkit.Maui/Primitives/BindablePropertySourceGeneratorPrimitives/AttachedBindablePropertyAttribute.shared.cs Adds runtime AttachedBindablePropertyAttribute<T> (experimental) for generator use.
src/CommunityToolkit.Maui/Primitives/BindablePropertySourceGeneratorPrimitives/AccessModifier.shared.cs Adds AccessModifier enum used by generators.
src/CommunityToolkit.Maui/PlatformConfiguration/AndroidSpecific/NavigationBar.shared.cs Tweaks navigation bar default color creation.
src/CommunityToolkit.Maui/PlatformConfiguration/AndroidSpecific/NavigationBar.android.cs Adds Android 35+ navigation bar overlay behavior and imports.
src/CommunityToolkit.Maui/Layouts/StateContainer/StateContainerController.shared.cs Moves to primary ctor, improves state lookup and error reporting.
src/CommunityToolkit.Maui/Layouts/StateContainer/StateContainer.shared.cs Makes default StateViews a fresh list; enhances exception to support inner exception.
src/CommunityToolkit.Maui/Extensions/WeakReferenceExtensions.cs Formatting-only adjustment.
src/CommunityToolkit.Maui/Extensions/PropertyChangedEventArgsExtensions.shared.cs Reworks property-name helper APIs (consolidates to IsOneOf).
src/CommunityToolkit.Maui/Extensions/AppThemeResourceExtension.shared.cs Improves AppTheme resource lookup fallback (root resources / resource dictionaries).
src/CommunityToolkit.Maui/Converters/DateTimeOffsetConverter.shared.cs Fixes offset handling and microseconds in DateTimeOffset conversions.
src/CommunityToolkit.Maui/Behaviors/Validators/MultiValidationBehavior.shared.cs Whitespace/formatting adjustment.
src/CommunityToolkit.Maui.UnitTests/Views/Popup/PopupPageTests.cs Adds tests for modal navigation stack edge-cases and blocked popup close behavior.
src/CommunityToolkit.Maui.UnitTests/Views/Popup/DefaultPopupSettingsTests.cs Expands coverage for popup defaults and service-based popup creation.
src/CommunityToolkit.Maui.UnitTests/Views/MediaElement/MediaSourceTests.cs Adds test for stream media source factory method.
src/CommunityToolkit.Maui.UnitTests/Views/MediaElement/MediaElementOptionsTests.cs Adds tests for MediaElement options defaults and foreground service behavior.
src/CommunityToolkit.Maui.UnitTests/Services/PopupServiceTests.cs Adds tests ensuring DI viewmodel is constructed once for popup service scenarios.
src/CommunityToolkit.Maui.UnitTests/Resources/Styles/AppThemeResourceDictionary.xaml.cs Adds a ResourceDictionary code-behind for AppThemeResource tests.
src/CommunityToolkit.Maui.UnitTests/Resources/Styles/AppThemeResourceDictionary.xaml Adds test XAML ResourceDictionary for AppThemeResource lookups.
src/CommunityToolkit.Maui.UnitTests/Layouts/StateContainerTests.cs Adds tests for duplicate state keys and per-layout default state views uniqueness.
src/CommunityToolkit.Maui.UnitTests/Layouts/DockLayoutTests.cs Whitespace/formatting adjustment.
src/CommunityToolkit.Maui.UnitTests/Extensions/AppThemeResourceExtensionTests.cs Adds regression test for AppThemeResource dictionary loading.
src/CommunityToolkit.Maui.UnitTests/Extensions/AppBuilderExtensionsTests.cs Updates tests for new MediaElement init signature and foreground service rules.
src/CommunityToolkit.Maui.UnitTests/Converters/DateTimeOffsetConverterTests.cs Updates tests for new offset/microsecond logic and adds DST-oriented cases.
src/CommunityToolkit.Maui.UnitTests/Behaviors/BaseBehaviorTest.cs Whitespace/formatting adjustment.
src/CommunityToolkit.Maui.UnitTests/BaseViewTest.cs Registers additional popups used in expanded tests.
src/CommunityToolkit.Maui.UnitTests/BaseTest.cs Restores default MediaElement options (incl. foreground service flag) on dispose.
src/CommunityToolkit.Maui.SourceGenerators/Models/BindablePropertyRecords.cs Formatting adjustments to generated XML doc string templates.
src/CommunityToolkit.Maui.SourceGenerators/Generators/TextColorToGenerator.cs Filters to public MAUI control types; minor formatting fix.
src/CommunityToolkit.Maui.SourceGenerators/Generators/BindablePropertyAttributeSourceGenerator.cs Stops emitting attribute via post-init; tweaks default binding mode literal handling.
src/CommunityToolkit.Maui.SourceGenerators/Generators/AttachedBindablePropertyAttributeSourceGenerator.cs Stops emitting attribute/enum via post-init (now provided by runtime primitives).
src/CommunityToolkit.Maui.SourceGenerators/CommunityToolkit.Maui.SourceGenerators.csproj Uses centralized $(CodeAnalysisVersion) for Roslyn packages.
src/CommunityToolkit.Maui.SourceGenerators/BindablePropertyDiagnostic.cs Removes generator-side diagnostic constant (moved to runtime primitives).
src/CommunityToolkit.Maui.SourceGenerators.UnitTests/TextColorToGeneratorTests/TextColorToGeneratorTests.cs Adds generator test ensuring internal MAUI types don’t receive emitted code.
src/CommunityToolkit.Maui.SourceGenerators.UnitTests/CommunityToolkit.Maui.SourceGenerators.UnitTests.csproj Updates package versions and project references for new generator setup.
src/CommunityToolkit.Maui.SourceGenerators.UnitTests/BindablePropertyAttributeSourceGeneratorTests/BindablePropertyAttributeSourceGenerator_IntegrationTests.cs Updates expected output for binding mode literal changes.
src/CommunityToolkit.Maui.SourceGenerators.UnitTests/BindablePropertyAttributeSourceGeneratorTests/BaseBindablePropertyAttributeSourceGeneratorTest.cs Removes expectation for post-init emitted attribute file.
src/CommunityToolkit.Maui.SourceGenerators.UnitTests/BaseTest.cs Updates references to runtime primitives (attribute/enum) instead of Roslyn Accessibility.
src/CommunityToolkit.Maui.SourceGenerators.UnitTests/AttachedBindablePropertyAttributeSourceGeneratorTests/BaseAttachedBindablePropertyAttributeGeneratorTest.cs Removes expectation for post-init emitted attribute/enum files.
src/CommunityToolkit.Maui.SourceGenerators.UnitTests/AttachedBindablePropertyAttributeSourceGeneratorTests/AttachedBindablePropertyAttributeSourceGenerator_ConstructorAttribute_CommonUsageTests.cs Whitespace/formatting adjustment.
src/CommunityToolkit.Maui.SourceGenerators.UnitTests/AttachedBindablePropertyAttributeSourceGeneratorTests/AttachedBindablePropertyAttributeSourceGenerator_ClassAttribute_CommonUsageTests.cs Whitespace/formatting adjustment.
src/CommunityToolkit.Maui.SourceGenerators.Benchmarks/Program.cs Adds benchmark execution for Android MediaElement foreground-service configuration generator tests.
src/CommunityToolkit.Maui.SourceGenerators.Benchmarks/CommunityToolkit.Maui.SourceGenerators.Benchmarks.csproj Adjusts project references for benchmark coverage.
src/CommunityToolkit.Maui.SourceGenerators.Benchmarks/AndroidMediaElementForegroundServiceConfigurationBenchmarks.cs Adds benchmark wrapper over MediaElement foreground-service generator test suites.
src/CommunityToolkit.Maui.slnx Adds MediaElement source generator projects and updates solution metadata.
src/CommunityToolkit.Maui.MediaElement/Views/StreamExtensions.windows.cs Adds Windows stream MIME-type helper (currently generic default).
src/CommunityToolkit.Maui.MediaElement/Views/StreamAssetResourceLoader.macios.cs Adds iOS/macOS AVAsset resource loader backed by a .NET Stream.
src/CommunityToolkit.Maui.MediaElement/Views/MediaManager.windows.cs Wires stream source via WinMediaSource.CreateFromStream.
src/CommunityToolkit.Maui.MediaElement/Views/MediaManager.tizen.cs Throws NotSupportedException for stream sources on Tizen.
src/CommunityToolkit.Maui.MediaElement/Views/MediaManager.macios.cs Wires stream sources via AVUrlAsset + resource loader delegate; adds content-type sniffing.
src/CommunityToolkit.Maui.MediaElement/Views/MediaManager.android.cs Adds stream handling via custom data source; foreground service gating; lifecycle cleanup.
src/CommunityToolkit.Maui.MediaElement/Views/MauiMediaElement.android.cs Fixes constructor availability/trim scenarios and updates Android namespace qualifiers.
src/CommunityToolkit.Maui.MediaElement/readme.txt Updates usage to pass the new MediaElement initialization parameter.
src/CommunityToolkit.Maui.MediaElement/Platforms/Android/StreamDataSource.android.cs Adds ExoPlayer IDataSource wrapper over .NET Stream.
src/CommunityToolkit.Maui.MediaElement/MediaSource/UriMediaSource.shared.cs Replaces generator-backed property with explicit BindableProperty implementation.
src/CommunityToolkit.Maui.MediaElement/MediaSource/StreamMediaSource.shared.cs Introduces new MediaSource type backed by a Stream (bindable property + operators).
src/CommunityToolkit.Maui.MediaElement/MediaSource/ResourceMediaSource.shared.cs Replaces generator-backed property with explicit BindableProperty implementation.
src/CommunityToolkit.Maui.MediaElement/MediaSource/MediaSource.shared.cs Adds MediaSource.FromStream(Stream) factory method.
src/CommunityToolkit.Maui.MediaElement/MediaSource/FileMediaSource.shared.cs Replaces generator-backed property with explicit BindableProperty implementation.
src/CommunityToolkit.Maui.MediaElement/MediaElementOptions.shared.cs Adds Android foreground service enable flag and update helper.
src/CommunityToolkit.Maui.MediaElement/Handlers/MediaElementHandler.android.cs Passes foreground service enabled flag into platform view creation.
src/CommunityToolkit.Maui.MediaElement/Converters/MediaSourceConverter.shared.cs Adds StreamMediaSource handling in converter output.
src/CommunityToolkit.Maui.MediaElement/CommunityToolkit.Maui.MediaElement.csproj Packs MediaElement source generator analyzer; removes old generator reference.
src/CommunityToolkit.Maui.MediaElement/AppBuilderExtensions.shared.cs Changes MediaElement initialization signature and applies foreground-service setting.
src/CommunityToolkit.Maui.MediaElement.SourceGenerators/CommunityToolkit.Maui.MediaElement.SourceGenerators.csproj Adds new MediaElement-specific source generator project.
src/CommunityToolkit.Maui.MediaElement.SourceGenerators.UnitTests/xunit.runner.json Adds xUnit runner config for new generator unit test project.
src/CommunityToolkit.Maui.MediaElement.SourceGenerators.UnitTests/GlobalUsings.cs Adds global usings for generator unit tests.
src/CommunityToolkit.Maui.MediaElement.SourceGenerators.UnitTests/CommunityToolkit.Maui.MediaElement.SourceGenerators.UnitTests.csproj Adds MediaElement generator unit test project.
src/CommunityToolkit.Maui.MediaElement.SourceGenerators.UnitTests/BaseTest.cs Adds generator testing base harness for MediaElement generator tests.
src/CommunityToolkit.Maui.MediaElement.SourceGenerators.UnitTests/AndroidMediaElementServiceConfigurationGeneratorTests/BaseAndroidMediaElementForegroundServiceConfigurationGeneratorTest.cs Adds base test helper for foreground-service generator tests.
src/CommunityToolkit.Maui.MediaElement.SourceGenerators.UnitTests/AndroidMediaElementServiceConfigurationGeneratorTests/AndroidMediaElementForegroundServiceConfigurationGenerator_OutputTests.cs Adds output/behavior tests for service configuration generator.
src/CommunityToolkit.Maui.MediaElement.SourceGenerators.UnitTests/AndroidMediaElementServiceConfigurationGeneratorTests/AndroidMediaElementForegroundServiceConfigurationGenerator_IntegrationTests.cs Adds integration-style tests for service configuration generator.
src/CommunityToolkit.Maui.MediaElement.SourceGenerators.UnitTests/AndroidMediaElementServiceConfigurationGeneratorTests/AndroidMediaElementForegroundServiceConfigurationGenerator_EdgeCaseTests.cs Adds edge-case tests for service configuration generator.
src/CommunityToolkit.Maui.MediaElement.Analyzers/Resources.resx Updates resource file schema/contents.
src/CommunityToolkit.Maui.MediaElement.Analyzers/Resources.Designer.cs Regenerates strongly-typed resources designer.
src/CommunityToolkit.Maui.MediaElement.Analyzers/CommunityToolkit.Maui.MediaElement.Analyzers.csproj Uses centralized $(CodeAnalysisVersion) for Roslyn packages.
src/CommunityToolkit.Maui.MediaElement.Analyzers.CodeFixes/CommunityToolkit.Maui.MediaElement.Analyzers.CodeFixes.csproj Uses centralized $(CodeAnalysisVersion) for Roslyn packages.
src/CommunityToolkit.Maui.Core/Platform/StatusBar/StatusBar.android.cs Adds Android 35+ overlay behavior and improves window selection logic.
src/CommunityToolkit.Maui.Core/Platform/KeyboardExtensions/KeyboardExtensions.shared.cs Makes SoftKeyboardException public and documents it.
src/CommunityToolkit.Maui.Core/Extensions/WindowExtensions.android.cs Updates window selection logic to prefer visible dialog windows.
src/CommunityToolkit.Maui.Core/Essentials/FolderPicker/FolderPickerImplementation.windows.cs Temporarily comments SuggestedFolder usage pending Windows SDK support.
src/CommunityToolkit.Maui.Core/CommunityToolkit.Maui.Core.csproj Updates WindowsAppSDK package version.
src/CommunityToolkit.Maui.Camera/CommunityToolkit.Maui.Camera.csproj Removes old source generator reference block.
src/CommunityToolkit.Maui.Camera/CameraManager.windows.cs Refactors initialization tracking and resets stream position after recording stop.
src/CommunityToolkit.Maui.Camera/CameraManager.shared.cs Refactors initialization tracking fields and onLoaded callback storage.
src/CommunityToolkit.Maui.Camera.Analyzers/CommunityToolkit.Maui.Camera.Analyzers.csproj Uses centralized $(CodeAnalysisVersion) for Roslyn packages.
src/CommunityToolkit.Maui.Camera.Analyzers.CodeFixes/CommunityToolkit.Maui.Camera.Analyzers.CodeFixes.csproj Uses centralized $(CodeAnalysisVersion) for Roslyn packages.
src/CommunityToolkit.Maui.Analyzers/CommunityToolkit.Maui.Analyzers.csproj Uses centralized $(CodeAnalysisVersion) for Roslyn packages.
src/CommunityToolkit.Maui.Analyzers/AnalyzerReleases.Shipped.md Formatting adjustments.
src/CommunityToolkit.Maui.Analyzers.UnitTests/UseCommunityToolkitMediaElementInitializationAnalyzerTests.cs Updates analyzer unit test sources for new MediaElement init signature.
src/CommunityToolkit.Maui.Analyzers.UnitTests/CommunityToolkit.Maui.Analyzers.UnitTests.csproj Uses centralized $(CodeAnalysisVersion) for Roslyn packages.
src/CommunityToolkit.Maui.Analyzers.CodeFixes/CommunityToolkit.Maui.Analyzers.CodeFixes.csproj Uses centralized $(CodeAnalysisVersion) for Roslyn packages.
samples/CommunityToolkit.Maui.Sample/ViewModels/Views/ViewsGalleryViewModel.cs Adds a new “MediaElement from Stream” entry to the gallery.
samples/CommunityToolkit.Maui.Sample/ViewModels/Views/MediaElement/MediaElementFromStreamViewModel.cs Adds new ViewModel placeholder for the stream sample page.
samples/CommunityToolkit.Maui.Sample/ViewModels/Behaviors/StatusBarBehaviorViewModel.cs Updates default slider values and reorganizes style/color properties.
samples/CommunityToolkit.Maui.Sample/Properties/launchSettings.json Switches Windows launch profile from MsixPackage to Project.
samples/CommunityToolkit.Maui.Sample/Platforms/Android/SamsungBadgeProvider.cs Adds fully-qualified Android URI usage.
samples/CommunityToolkit.Maui.Sample/Platforms/Android/AndroidManifest.xml Re-indents manifest and adds VIDEO_CAPTURE query intent.
samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementFromStreamPage.xaml.cs Adds sample page demonstrating StreamMediaSource playback.
samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementFromStreamPage.xaml Adds UI for stream playback sample page.
samples/CommunityToolkit.Maui.Sample/Pages/Views/CameraView/CameraViewPage.xaml.cs Adds Windows unpackaged microphone-permission handling and improves capture flow.
samples/CommunityToolkit.Maui.Sample/Pages/PlatformSpecific/NavigationBarPage.xaml Adjusts layout and label formatting for navigation bar style selector.
samples/CommunityToolkit.Maui.Sample/Pages/Behaviors/StatusBarBehaviorPage.xaml Layout/formatting improvements for style selection UI.
samples/CommunityToolkit.Maui.Sample/MauiProgram.cs Registers stream sample page/VM and updates MediaElement init call with new parameter.
samples/CommunityToolkit.Maui.Sample/CommunityToolkit.Maui.Sample.csproj Updates packages, analyzer refs, Windows packaging settings, and XAML compilation for new page.
samples/CommunityToolkit.Maui.Sample/AppShell.xaml.cs Adds route mapping for stream sample page.
samples/CommunityToolkit.Maui.Sample.slnx Adds MediaElement generator projects and adjusts deploy metadata.
Directory.Build.props Adds CodeAnalysisVersion and updates MAUI package version / internals visibility.
.github/workflows/dotnet-build.yml Builds new MediaElement generator project and runs its unit tests; bumps artifact action versions.
.github/workflows/benchmarks.yml Bumps artifact action version.
.github/instructions/mobile-memory-leaks.instructions.md Adds repo guidance on iOS/catalyst memory leak patterns.
.github/instructions/async.instructions.md Adds repo guidance on async best practices.
Files not reviewed (1)
  • src/CommunityToolkit.Maui.MediaElement.Analyzers/Resources.Designer.cs: Language not supported

@TheCodeTraveler
Copy link
Copy Markdown
Collaborator

Thanks Matt! Could you rebase your branch against our main branch? This PR is showing a bunch of "new" commits that already exist in our main branch.

@matt-goldman
Copy link
Copy Markdown
Contributor Author

Thanks Matt! Could you rebase your branch against our main branch? This PR is showing a bunch of "new" commits that already exist in our main branch.

Yeah sorry thought I'd done that...stand by

@matt-goldman matt-goldman force-pushed the add-stream-media-source branch from 5732b76 to a1f72a4 Compare April 3, 2026 02:33
@matt-goldman
Copy link
Copy Markdown
Contributor Author

@TheCodeTraveler I've done that now, I'll look at the copilot feedback next, but I think some of it is related to those earlier commits you mentioned.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated 9 comments.

Comment thread src/CommunityToolkit.Maui.UnitTests/Views/MediaElement/MediaSourceTests.cs Outdated
Comment thread src/CommunityToolkit.Maui.MediaElement/Views/MediaManager.macios.cs Outdated
Comment thread src/CommunityToolkit.Maui.MediaElement/Views/MediaManager.android.cs Outdated
Comment thread samples/CommunityToolkit.Maui.Sample/CommunityToolkit.Maui.Sample.csproj Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated 8 comments.

Comment thread src/CommunityToolkit.Maui.MediaElement/Views/MediaManager.android.cs Outdated
Comment thread samples/CommunityToolkit.Maui.Sample/ViewModels/Views/ViewsGalleryViewModel.cs Outdated
Comment thread samples/CommunityToolkit.Maui.Sample/MauiProgram.cs Outdated
@TheCodeTraveler
Copy link
Copy Markdown
Collaborator

Hey @matt-goldman! Could you take a look at CoPilot's comments on this PR and either implement them or comment on why we shouldn't then click Resolve conversation for each??

@TheCodeTraveler TheCodeTraveler self-assigned this May 7, 2026
@matt-goldman
Copy link
Copy Markdown
Contributor Author

@matt-goldman Just FYI - we're seeing the same Unit Test failure that we thought was fixed :

Unhandled exception. System.ArgumentException: An item with the same key has already been added. Key: Microsoft.Maui.Controls.BindableProperty

https://github.com/CommunityToolkit/Maui/actions/runs/25446477233/job/74651856833?pr=3181#step:30:157

Since it doesn't affect this PR, so let's avoid discussing it here. I just wanted to give you heads up since you worked hard on fixing it.

homer-scream

ok thanks I'll take a look!

@matt-goldman
Copy link
Copy Markdown
Contributor Author

Hey @matt-goldman! Could you take a look at CoPilot's comments on this PR and either implement them or comment on why we shouldn't then click Resolve conversation for each??

Hey @TheCodeTraveler, I've been through and addressed the feedback on these, except the iOS one which I think needs a bit more thought.

First off, in any realistic scenario, CanSeek will always be true, so really the existing code block is potentially overly defensive, and was added in response to Copilot feedback here: #3181 (comment). (You could break it, but you would have to mean to).

Second, I'm not convinced that errorring or returning false is the right approach here anyway. I get the point that playback may be "corrupted", but this is a very hypothetical edge case, and it's protected by the API contract anyway; AVFoundation assumes range-addressable content, and non-seekable media just doesn't make sense.

If we did want to address this, the right place to do so would be a layer back, in the constructor. Then we have a new problem, actually two. The first is that we now either have consistent error handling on each platform, or we move this up a layer into the cross-platform API. If we do the latter, then we have an inconsistent API for Stream media source than we do for everything else, or we take on the task of updating this at the cross-platform layer, which requires discussion and acceptance by the team.

And then we have the problem of what to do. I'm really not a fan of throwing exceptions for an anticipated or known state (that ExoPlayer thing I added above is different, that genuinely shouldn't happen, but we can't be responsible for it; I still don't like it but accept it's a legitimate use case). So I wouldn't want to throw an exception, I would rather gracefully handle it, in a way that is available to consumers on all platforms.

In reviewing this though I did discover another edge case, which is that stream.Read may not read the whole stream. I thought about this and how it can be addressed and this actually brings in some additional, but tangentially related, problems.

The first is that to fix it requires forcibly reading the stream to the end, but that could be counter to how people want to use this. That works, for example, for a FileStream, but what about a network stream where they may want to actually request it in chunks? (which actually AVFoundation can do here itself anyway, but that's an abstract use case not coming in through this vector). Then I thought some more and when it's MemoryStream, it will always actually read the whole stream anyway, and we have FromFile already for file streams. So we would have to either surface an API for allowing streaming in chunks, which in a sense this already does, or try and anticipate intent and act accordingly.

Where this leaves me: I think the risk flagged by Copilot is a hypothetical edge case and doesn't need to be addressed here. It does raise some other considerations, but I would like to open a follow-up discussion to address those at a later stage. For example, we could consider adding an analyzer that raises a warning or suggestion if someone passes a FileStream, advising them to use FromFile instead of FromStream. And the bigger decision about chunking needs its own breathing room and consideration, I think, outside the scope of a PR comment.

@TheCodeTraveler
Copy link
Copy Markdown
Collaborator

That all sounds good! I totally agree.

Let me know if this is ready for me to review and I'll dive into this weekend.

@matt-goldman
Copy link
Copy Markdown
Contributor Author

That all sounds good! I totally agree.

Let me know if this is ready for me to review and I'll dive into this weekend.

Sorry for the delay, it's ready! I wanted to make sure I'd pulled it down and tested across all platforms with all the latest changes. Can confirm tested successfully on macOS, Windows, and iOS and Android physical devices.

Copy link
Copy Markdown
Collaborator

@TheCodeTraveler TheCodeTraveler left a comment

Choose a reason for hiding this comment

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

Thanks Matt! You rock 🙌

@TheCodeTraveler TheCodeTraveler merged commit d217048 into CommunityToolkit:main May 11, 2026
9 checks passed
@matt-goldman matt-goldman deleted the add-stream-media-source branch May 12, 2026 00:36
@github-actions github-actions Bot locked and limited conversation to collaborators May 13, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants