Skip to content

Conversation

@ksokolovskyi
Copy link
Contributor

Fixes First Frame of Video Once VideoPlayer Controller doesn't show in iOS Safari/Chrome

This PR fixes the blank first frame issue by adding a _videoElement.load() call at the end of the initialize function. This call forces the browser to load media in preparation for playback (https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/load).

Additionally, this PR removes loadedmetadata event listener, as the canplay event is now reliably emitted across all platforms. Keeping loadedmetadata listener could result in marking the video controller as initialized before the first frame is actually rendered. This causes the loader to disappear too early, leaving a blank space where the video should be until the browser displays the first frame. Relying on canplay ensures the first frame is ready before we proceed.

Note

It turns out that this issue is iOS-specific and was reported not only in Flutter, but in some other packages and tools:

  1. video-react/First frame not shown as the poster on iOS Safari
  2. WordPress/gutenberg/Video Block: First frame not shown as the poster on iOS Safari — Fix: Use Fragment URL

Tip

As a temporary workaround until this PR is merged, users can append the #t=0.001 fragment to the asset or URL src to force the browser to load the first frame (e.g., assets/butterfly.mp4#t=0.001, https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4#t=0.001).

The following repository was used for issue reproduction and testing: https://github.com/ksokolovskyi/video_player_blank_frame_bug

Before After
https://video-player-blank-frame-bug.web.app https://video-player-blank-frame-fix.web.app
bug.mp4
fix.mp4

Pre-Review Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

Footnotes

  1. Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling. 2 3

Copy link
Member

@ditman ditman left a comment

Choose a reason for hiding this comment

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

Thanks for the fix! Very small comment about attaching the load event in tests.

@ksokolovskyi ksokolovskyi requested a review from ditman April 22, 2025 08:15
Copy link
Member

@ditman ditman left a comment

Choose a reason for hiding this comment

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

LGTM! Let's go!

@ditman ditman added the autosubmit Merge PR when tree becomes green via auto submit App label Apr 22, 2025
@auto-submit auto-submit bot merged commit 6ce3776 into flutter:main Apr 22, 2025
82 checks passed
@ksokolovskyi
Copy link
Contributor Author

@ditman thanks a lot for your review!

engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Apr 23, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Apr 23, 2025
github-merge-queue bot pushed a commit to flutter/flutter that referenced this pull request Apr 23, 2025
flutter/packages@f1fc965...41211cf

2025-04-22 [email protected] [gis_web] Make
maybeEnum more robust in google_identity_services_web shared file.
(flutter/packages#8999)
2025-04-22 [email protected] [video_player_web] Fix blank
first frame on iOS. (flutter/packages#9025)
2025-04-22 [email protected] [go_router]
Add missing `caseSensitive` parameter to `GoRouteData.$route`
(flutter/packages#9126)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages-flutter-autoroll
Please CC [email protected] on the revert to ensure that a
human
is aware of the problem.

To file a bug in Flutter:
https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
raju-muliyashiya pushed a commit to raju-muliyashiya/flutter_packages that referenced this pull request Apr 26, 2025
Fixes [First Frame of Video Once VideoPlayer Controller doesn't show in iOS Safari/Chrome](flutter/flutter#139107)

This PR fixes the blank first frame issue by adding a `_videoElement.load()` call at the end of the `initialize` function. This call forces the browser to load media in preparation for playback (https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/load).

Additionally, this PR removes `loadedmetadata` event listener, as the `canplay` event is now reliably emitted across all platforms. Keeping `loadedmetadata` listener could result in marking the video controller as initialized before the first frame is actually rendered. This causes the loader to disappear too early, leaving a blank space where the video should be until the browser displays the first frame. Relying on `canplay` ensures the first frame is ready before we proceed.

> [!NOTE]
> It turns out that this issue is iOS-specific and was reported not only in Flutter, but in some other packages and tools:
> 1) [video-react/First frame not shown as the poster on iOS Safari](video-react/video-react#328)
> 2) [WordPress/gutenberg/Video Block: First frame not shown as the poster on iOS Safari — Fix: Use Fragment URL](WordPress/gutenberg#51995)

> [!TIP]
> As a temporary workaround until this PR is merged, users can append the `#t=0.001` fragment to the asset or URL `src` to force the browser to load the first frame (e.g., `assets/butterfly.mp4#t=0.001`, `https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4#t=0.001`).

The following repository was used for issue reproduction and testing: https://github.com/ksokolovskyi/video_player_blank_frame_bug

| Before | After |
| :---: | :---: |
| https://video-player-blank-frame-bug.web.app | https://video-player-blank-frame-fix.web.app |
| <video src="https://github.com/user-attachments/assets/4077fcc4-10cf-4dbd-8c59-2fd824b4e4c4" /> | <video src="https://github.com/user-attachments/assets/2951af36-1569-4a5c-90dd-1d52a5d1e7f2" /> |

## Pre-Review Checklist

[^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
androidseb pushed a commit to androidseb/packages that referenced this pull request Jun 8, 2025
Fixes [First Frame of Video Once VideoPlayer Controller doesn't show in iOS Safari/Chrome](flutter/flutter#139107)

This PR fixes the blank first frame issue by adding a `_videoElement.load()` call at the end of the `initialize` function. This call forces the browser to load media in preparation for playback (https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/load).

Additionally, this PR removes `loadedmetadata` event listener, as the `canplay` event is now reliably emitted across all platforms. Keeping `loadedmetadata` listener could result in marking the video controller as initialized before the first frame is actually rendered. This causes the loader to disappear too early, leaving a blank space where the video should be until the browser displays the first frame. Relying on `canplay` ensures the first frame is ready before we proceed.

> [!NOTE]
> It turns out that this issue is iOS-specific and was reported not only in Flutter, but in some other packages and tools:
> 1) [video-react/First frame not shown as the poster on iOS Safari](video-react/video-react#328)
> 2) [WordPress/gutenberg/Video Block: First frame not shown as the poster on iOS Safari — Fix: Use Fragment URL](WordPress/gutenberg#51995)

> [!TIP]
> As a temporary workaround until this PR is merged, users can append the `#t=0.001` fragment to the asset or URL `src` to force the browser to load the first frame (e.g., `assets/butterfly.mp4#t=0.001`, `https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4#t=0.001`).

The following repository was used for issue reproduction and testing: https://github.com/ksokolovskyi/video_player_blank_frame_bug

| Before | After |
| :---: | :---: |
| https://video-player-blank-frame-bug.web.app | https://video-player-blank-frame-fix.web.app |
| <video src="https://github.com/user-attachments/assets/4077fcc4-10cf-4dbd-8c59-2fd824b4e4c4" /> | <video src="https://github.com/user-attachments/assets/2951af36-1569-4a5c-90dd-1d52a5d1e7f2" /> |

## Pre-Review Checklist

[^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
FMorschel pushed a commit to FMorschel/packages that referenced this pull request Jun 9, 2025
Fixes [First Frame of Video Once VideoPlayer Controller doesn't show in iOS Safari/Chrome](flutter/flutter#139107)

This PR fixes the blank first frame issue by adding a `_videoElement.load()` call at the end of the `initialize` function. This call forces the browser to load media in preparation for playback (https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/load).

Additionally, this PR removes `loadedmetadata` event listener, as the `canplay` event is now reliably emitted across all platforms. Keeping `loadedmetadata` listener could result in marking the video controller as initialized before the first frame is actually rendered. This causes the loader to disappear too early, leaving a blank space where the video should be until the browser displays the first frame. Relying on `canplay` ensures the first frame is ready before we proceed.

> [!NOTE]
> It turns out that this issue is iOS-specific and was reported not only in Flutter, but in some other packages and tools:
> 1) [video-react/First frame not shown as the poster on iOS Safari](video-react/video-react#328)
> 2) [WordPress/gutenberg/Video Block: First frame not shown as the poster on iOS Safari — Fix: Use Fragment URL](WordPress/gutenberg#51995)

> [!TIP]
> As a temporary workaround until this PR is merged, users can append the `#t=0.001` fragment to the asset or URL `src` to force the browser to load the first frame (e.g., `assets/butterfly.mp4#t=0.001`, `https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4#t=0.001`).

The following repository was used for issue reproduction and testing: https://github.com/ksokolovskyi/video_player_blank_frame_bug

| Before | After |
| :---: | :---: |
| https://video-player-blank-frame-bug.web.app | https://video-player-blank-frame-fix.web.app |
| <video src="https://github.com/user-attachments/assets/4077fcc4-10cf-4dbd-8c59-2fd824b4e4c4" /> | <video src="https://github.com/user-attachments/assets/2951af36-1569-4a5c-90dd-1d52a5d1e7f2" /> |

## Pre-Review Checklist

[^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
Ortes pushed a commit to Ortes/packages that referenced this pull request Jun 25, 2025
Fixes [First Frame of Video Once VideoPlayer Controller doesn't show in iOS Safari/Chrome](flutter/flutter#139107)

This PR fixes the blank first frame issue by adding a `_videoElement.load()` call at the end of the `initialize` function. This call forces the browser to load media in preparation for playback (https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/load).

Additionally, this PR removes `loadedmetadata` event listener, as the `canplay` event is now reliably emitted across all platforms. Keeping `loadedmetadata` listener could result in marking the video controller as initialized before the first frame is actually rendered. This causes the loader to disappear too early, leaving a blank space where the video should be until the browser displays the first frame. Relying on `canplay` ensures the first frame is ready before we proceed.

> [!NOTE]
> It turns out that this issue is iOS-specific and was reported not only in Flutter, but in some other packages and tools:
> 1) [video-react/First frame not shown as the poster on iOS Safari](video-react/video-react#328)
> 2) [WordPress/gutenberg/Video Block: First frame not shown as the poster on iOS Safari — Fix: Use Fragment URL](WordPress/gutenberg#51995)

> [!TIP]
> As a temporary workaround until this PR is merged, users can append the `#t=0.001` fragment to the asset or URL `src` to force the browser to load the first frame (e.g., `assets/butterfly.mp4#t=0.001`, `https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4#t=0.001`).

The following repository was used for issue reproduction and testing: https://github.com/ksokolovskyi/video_player_blank_frame_bug

| Before | After |
| :---: | :---: |
| https://video-player-blank-frame-bug.web.app | https://video-player-blank-frame-fix.web.app |
| <video src="https://github.com/user-attachments/assets/4077fcc4-10cf-4dbd-8c59-2fd824b4e4c4" /> | <video src="https://github.com/user-attachments/assets/2951af36-1569-4a5c-90dd-1d52a5d1e7f2" /> |

[^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
romanejaquez pushed a commit to romanejaquez/flutter that referenced this pull request Aug 14, 2025
flutter/packages@f1fc965...41211cf

2025-04-22 [email protected] [gis_web] Make
maybeEnum more robust in google_identity_services_web shared file.
(flutter/packages#8999)
2025-04-22 [email protected] [video_player_web] Fix blank
first frame on iOS. (flutter/packages#9025)
2025-04-22 [email protected] [go_router]
Add missing `caseSensitive` parameter to `GoRouteData.$route`
(flutter/packages#9126)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages-flutter-autoroll
Please CC [email protected] on the revert to ensure that a
human
is aware of the problem.

To file a bug in Flutter:
https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autosubmit Merge PR when tree becomes green via auto submit App p: video_player platform-web

Projects

None yet

Development

Successfully merging this pull request may close these issues.

First Frame of Video Once VideoPlayer Controller doesn't show in iOS Safari/Chrome

2 participants