packages
packages copied to clipboard
[video_player] Windows Support
Creates a video_player_windows package that uses Windows' Media Foundation APIs to deliver a decent video player on windows.
Fixes: https://github.com/flutter/flutter/issues/37673
Pre-launch Checklist
- [X] I read the Contributor Guide and followed the process outlined there for submitting PRs.
- [X] I read the Tree Hygiene wiki page, which explains my responsibilities.
- [X] I read and followed the relevant style guides and ran the auto-formatter. (Unlike the flutter/flutter repo, the flutter/packages repo does use
dart format
.) - [X] I signed the CLA.
- [X] The title of the PR starts with the name of the package surrounded by square brackets, e.g.
[shared_preferences]
- [X] I listed at least one issue that this PR fixes in the description above.
- [x] I updated
pubspec.yaml
with an appropriate new version according to the pub versioning philosophy, or this PR is exempt from version changes. - [x] I updated
CHANGELOG.md
to add a description of the change, following repository CHANGELOG style. - [X] I updated/added relevant documentation (doc comments with
///
). - [X] I added new tests to check the change I am making, or this PR is test-exempt.
- [X] All existing and new tests are passing.
When I updated to 16.0.0 of Pigeon, found a bug: https://github.com/flutter/flutter/issues/141499
When I updated to 16.0.0 of Pigeon, found a bug: flutter/flutter#141499
Thanks, that should probably be an easy fix.
FYI we're generally moving away from dartHostTestHandler
in favor of just mocking/faking the host API itself, as we've generally found over time that it makes the tests simpler.
@stuartmorgan I have no idea why the tests are timing out. They are working fine locally.
@stuartmorgan I have no idea why the tests are timing out. They are working fine locally.
We have an ongoing problem in our Windows CI where some kinds of failures (even compile failures in at least some cases) somehow cause the CI to think something is still running and then they time out without much output, which unfortunately makes identifying the cause of a CI failure difficult. I'll try running the tests on my machine later today and see if I see any failures locally.
Went through most of the comments and fixed most of the issues.
I tried running this locally, and I'm getting an assertion failure in the THROW_IF_FAILED(D3D11CreateDevice(...))
in InitializeVideo
on startup as a modal dialog; this may well be what's happening in CI. Specifically, it's the m_ptr == nullptr
assertion in put()
on the com_ptr<ID3D11Device>
in that call.
Interestingly if I press Ignore, the app then launches and the video plays.
MediaEngineWrapper::Initialize
is calling:
-
InitializeVideo
-
CreateMediaEngine
- which itself has a call to
InitializeVideo
early on, andInitializeVideo
doesn't appear to handle being called multiple times, since it passesd3d11_device_.put()
each time, and re-usingput
without nulling it is a programming error.
- which itself has a call to
I'm curious how you aren't seeing this locally.
Oh, nice catch. No idea why it is not failing on my box. I've tested it in two Win11 machines with no issues. I'll update this to properly propagate initialization errors back to dart.
This seems to be an issue on the media foundation samples. It has exactly the same pattern. It isn't a bigger issue there since the d3d11Device is a local variable there, not a member field like here, but it shouldn't be doing that anyway.
Thank you for sending this pull request, this is amazing!!
I did a first pass from a Windows perspective. I'm still ramping up on Windows Media Foundation, so I'll need to do another pass later.
/cc @yaakovschectman who also works on Windows
I played with the latest version locally a bit, and I can confirm that those assertions are gone for me! A few things I noticed:
- Playback seems intermittently choppy. It feels like maybe the buffer swap is not being driven consistently? (This is just speculation, since it feels somewhat like the bad playback I had in early versions of the macOS version when I hadn't gotten the display link timer set up correctly.)
- I'm getting logging from the engine about an event being sent from a non-platform thread. I'm going to see if I can quickly track that down.
- Resizing the window pretty reliably crashes, sometimes with logging from the engine that sounds like it might be an assertion failure.
- I'm getting logging from the engine about an event being sent from a non-platform thread. I'm going to see if I can quickly track that down.
Looks like this is the event_sink_
call in VideoPlayer::SendInitialized
, which is coming from MFWorkItem::Invoke
on a thread called (if I'm reading this VS UI correctly) ntdll.dll thread
.
And then also VideoPlayer::SetBuffering
on the same thread, from MediaEngineCallbackHelper::EventNotify
- Resizing the window pretty reliably crashes
Running this under the debugger, in one case I saw an assertion failure in MediaEngineWrapper::EnsureTextureCreated
; as with the earlier crash, it's texture_.put()
being non-null.
But the actual crash seems to be an abort coming from deep in the Flutter engine on the raster thread. I don't have a debug engine on Windows so I don't have more detail. Given that it's resize, I'm guessing that the most likely situation is that a buffer is being destroyed while the engine is still using it.
I created a generic RunOnMainThread method, that adds a delegate to a queue, registers a top-level Window Proc Delegate, which dequeues the delegate and run it. This solved these issues, but I think other plugins might benefit from this, as there is an equivalent in Android and iOS.
This solved these issues, but I think other plugins might benefit from this, as there is an equivalent in Android and iOS.
https://github.com/flutter/flutter/issues/134346 has some related discussion; we've considered, rejected, and now are reconsidering building that into the plugin APIs.
Your input there would be welcome as a significant stakeholder :)
When would this feature merge? It's really needed!
Hello, I've found an issue with video_player_windows. It throws an error when playing a locally stored video file with a filename containing Chinese characters.
The error log is as follows:
#0 WindowsVideoPlayerApi.create (package:video_player_windows/src/messages.g.dart:89:7)
<asynchronous suspension>
#1 WindowsVideoPlayer.create (package:video_player_windows/src/windows_video_player.dart:56:27)
<asynchronous suspension>
#2 VideoPlayerController.initialize (package:video_player/video_player.dart:434:19)
@FZY456 You've only included the stack there, not the actual error.
@FZY456 You've only included the stack there, not the actual error.
PlatformException(uri_load_failed, , null, null)
From triage: What's the current status of this PR? Is it just waiting for an updated review?
No, review is probably still updated, but there is work on my end. I just didn't have time to do yet. My bad.
Any update on this pr?
From triage: @azchohfi Is this still something you're planning to come back to?
Unfortunately, I do not have time right now to look at this. I would say that most of the code works but it needs some tweaking to make it production ready. Feel free to work on top of this to get it merged.