Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
2 tasks done
austinlee1993 opened this issue Nov 28, 2023 · 12 comments
Open
2 tasks done
Labels
c: rendering UI glitches reported at the engine/skia rendering level found in release: 3.16 Found to occur in 3.16 found in release: 3.17 Found to occur in 3.17 has reproducible steps The issue has been confirmed reproducible and is ready to work on p: video_player The Video Player plugin P2 Important issues not at the top of the work list package flutter/packages repository. See also p: labels. platform-ios iOS applications specifically platform-web Web applications specifically team-web Owned by Web platform team triaged-web Triaged by Web platform team

Comments

@austinlee1993
Copy link

austinlee1993 commented Nov 28, 2023

Is there an existing issue for this?

What package does this bug report belong to?

video_player

What target platforms are you seeing this bug on?

iOS

Have you already upgraded your packages?

Yes

Dependency versions

pubspec.lock
[Paste file content here]

Steps to reproduce

Initialize VideoPlayer Controller with video with SetState called

Expected results

I expect to see the first frame of the video to appear

Actual results

Nothing shows up for iOS Safari/chrome - the width and height of the frame appear so its a blank box. What's also strange is it works in Android and my MacOS Desktop.

Code sample

Code sample
controller = VideoPlayerController.networkUrl(Uri.parse(
        'https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4'))
      ..initialize().then((_) {
        // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
        setState(() {});
      });

Screenshots or Videos

Screenshots / Video demonstration

First photo is the code in iOS Safari, next one is MacOS Desktop

Screen Shot 2023-11-27 at 4 25 03 PM

Logs

Logs
[Paste your logs here]

Flutter Doctor output

Doctor output
[✓] Flutter (Channel stable, 3.13.9, on macOS 12.6.7 21G651 darwin-x64, locale en-US)
    • Flutter version 3.13.9 on channel stable at /Users/austinlee/Desktop/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision d211f42860 (5 weeks ago), 2023-10-25 13:42:25 -0700
    • Engine revision 0545f8705d
    • Dart version 3.1.5
    • DevTools version 2.25.0

[!] Android toolchain - develop for Android devices (Android SDK version 30.0.1)
    • Android SDK at /Users/austinlee/Library/Android/sdk
    ✗ cmdline-tools component is missing
      Run `path/to/sdkmanager --install "cmdline-tools;latest"`
      See https://developer.android.com/studio/command-line for more details.
    ✗ Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/docs/get-started/install/macos#android-setup for more details.

[!] Xcode - develop for iOS and macOS (Xcode 14.2)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14C18
    ✗ CocoaPods not installed.
        CocoaPods is used to retrieve the iOS and macOS platform side's plugin code that responds to your
        plugin usage on the Dart side.
        Without CocoaPods, plugins will not work on iOS or macOS.
        For more info, see https://flutter.dev/platform-plugins
      To install see https://guides.cocoapods.org/using/getting-started.html#installation for
      instructions.

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[!] Android Studio (not installed)
    • Android Studio not found; download from https://developer.android.com/studio/index.html
      (or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed
      instructions).

[✓] VS Code (version 1.79.0)
    • VS Code at /Users/austinlee/Downloads/Visual Studio Code 2.app/Contents
    • Flutter extension version 3.76.0

[✓] Connected device (2 available)
    • macOS (desktop) • macos  • darwin-x64     • macOS 12.6.7 21G651 darwin-x64
    • Chrome (web)    • chrome • web-javascript • Google Chrome 119.0.6045.159

[✓] Network resources
    • All expected network resources are available.
@huycozy huycozy added the in triage Presently being triaged by the triage team label Nov 28, 2023
@huycozy
Copy link
Member

huycozy commented Nov 28, 2023

Hi @austinlee1993
I can reproduce this issue without setState after initialize() as well. Also, it doesn't seem to appear on Web, but on iOS Flutter app as well (iOS target platform). Could you try sample code below and confirm?

Complete sample code
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';

void main() => runApp(const VideoPlayerApp());

class VideoPlayerApp extends StatelessWidget {
  const VideoPlayerApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Video Player Demo',
      home: VideoPlayerScreen(),
    );
  }
}

class VideoPlayerScreen extends StatefulWidget {
  const VideoPlayerScreen({super.key});

  @override
  State<VideoPlayerScreen> createState() => _VideoPlayerScreenState();
}

class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
  late VideoPlayerController _controller;
  late Future<void> _initializeVideoPlayerFuture;

  @override
  void initState() {
    super.initState();

    // Create and store the VideoPlayerController. The VideoPlayerController
    // offers several different constructors to play videos from assets, files,
    // or the internet.
    _controller = VideoPlayerController.networkUrl(
      Uri.parse(
        'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4',
      ),
    );

    // Initialize the controller and store the Future for later use.
    _initializeVideoPlayerFuture = _controller.initialize();

    // Use the controller to loop the video.
    _controller.setLooping(true);
  }

  @override
  void dispose() {
    // Ensure disposing of the VideoPlayerController to free up resources.
    _controller.dispose();

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Butterfly Video'),
      ),
      // Use a FutureBuilder to display a loading spinner while waiting for the
      // VideoPlayerController to finish initializing.
      body: FutureBuilder(
        future: _initializeVideoPlayerFuture,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            // If the VideoPlayerController has finished initialization, use
            // the data it provides to limit the aspect ratio of the video.
            return AspectRatio(
              aspectRatio: _controller.value.aspectRatio,
              // Use the VideoPlayer widget to display the video.
              child: VideoPlayer(_controller),
            );
          } else {
            // If the VideoPlayerController is still initializing, show a
            // loading spinner.
            return const Center(
              child: CircularProgressIndicator(),
            );
          }
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // Wrap the play or pause in a call to `setState`. This ensures the
          // correct icon is shown.
          setState(() {
            // If the video is playing, pause it.
            if (_controller.value.isPlaying) {
              _controller.pause();
            } else {
              // If the video is paused, play it.
              _controller.play();
            }
          });
        },
        // Display the correct icon depending on the state of the player.
        child: Icon(
          _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
        ),
      ),
    );
  }
}

This may be similar to #41156.

@huycozy huycozy added the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Nov 28, 2023
@austinlee1993
Copy link
Author

Hi @huycozy - thanks for the quick response - I tried the following code and the first frame still does not initialize in iOS Safari. I attached a screen recording of the implementation.

RPReplay_Final1701200748.mov

@github-actions github-actions bot removed the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Nov 28, 2023
@huycozy
Copy link
Member

huycozy commented Nov 29, 2023

Sorry, I typed it wrong. I meant the issue appears on both Web (iOS browsers) and iOS app.

I checked this again and confirmed the issue is only on Web (iOS browsers: Safari, Chrome).

On iOS Flutter app, the first frame (or video thumbnail) is rendering normally; the same on Chrome browser on Android.

iOS app Android browser: Chrome iOS browsers: Safari, Chrome

✅: No Issue ❗: Issue reproduced

flutter doctor -v (stable and master)
[✓] Flutter (Channel stable, 3.16.1, on macOS 14.1 23B74 darwin-x64, locale en-VN)
    • Flutter version 3.16.1 on channel stable at /Users/huynq/Documents/GitHub/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 7f20e5d18c (9 hours ago), 2023-11-27 09:47:30 -0800
    • Engine revision 22b600f240
    • Dart version 3.2.1
    • DevTools version 2.28.3

[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    • Android SDK at /Users/huynq/Library/Android/sdk
    • Platform android-34, build-tools 34.0.0
    • ANDROID_HOME = /Users/huynq/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 15.0.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 15A507
    • CocoaPods version 1.13.0

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[!] Android Studio (version unknown)
    • Android Studio at /Applications/Android Studio Preview.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    ✗ Unable to determine Android Studio version.
    • Java version OpenJDK Runtime Environment (build 17.0.8+0-17.0.8b1000.22-10799086)

[✓] Android Studio (version 2022.3)
    • Android Studio at /Applications/Android Studio Giraffe Patch 3.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231)

[✓] Android Studio (version 2022.2)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • android-studio-dir = /Applications/Android Studio.app/
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)

[✓] VS Code (version 1.84.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.76.0

[✓] Connected device (3 available)
    • RMX2001 (mobile) • EUYTFEUSQSRGDA6D • android-arm64  • Android 11 (API 30)
    • macOS (desktop)  • macos            • darwin-x64     • macOS 14.1 23B74 darwin-x64
    • Chrome (web)     • chrome           • web-javascript • Google Chrome 119.0.6045.159

[✓] Network resources
    • All expected network resources are available.

! Doctor found issues in 1 category.
[!] Flutter (Channel master, 3.17.0-17.0.pre.47, on macOS 14.1 23B74 darwin-x64, locale en-VN)
    • Flutter version 3.17.0-17.0.pre.47 on channel master at /Users/huynq/Documents/GitHub/flutter_master
    ! Warning: `flutter` on your path resolves to /Users/huynq/Documents/GitHub/flutter/bin/flutter, which is not inside your current Flutter SDK checkout at /Users/huynq/Documents/GitHub/flutter_master. Consider adding /Users/huynq/Documents/GitHub/flutter_master/bin to the front of your path.
    ! Warning: `dart` on your path resolves to /Users/huynq/Documents/GitHub/flutter/bin/dart, which is not inside your current Flutter SDK checkout at /Users/huynq/Documents/GitHub/flutter_master. Consider adding /Users/huynq/Documents/GitHub/flutter_master/bin to the front of your path.
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 7a0508e5de (10 minutes ago), 2023-11-28 22:01:04 -0500
    • Engine revision 4beaa1195b
    • Dart version 3.3.0 (build 3.3.0-170.0.dev)
    • DevTools version 2.30.0-dev.4
    • If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and upgrades.

[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    • Android SDK at /Users/huynq/Library/Android/sdk
    • Platform android-34, build-tools 34.0.0
    • ANDROID_HOME = /Users/huynq/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 15.0.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 15A507
    • CocoaPods version 1.13.0

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[!] Android Studio (version unknown)
    • Android Studio at /Applications/Android Studio Preview.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    ✗ Unable to determine Android Studio version.
    • Java version OpenJDK Runtime Environment (build 17.0.8+0-17.0.8b1000.22-10799086)

[✓] Android Studio (version 2022.3)
    • Android Studio at /Applications/Android Studio Giraffe Patch 3.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231)

[✓] Android Studio (version 2022.2)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • android-studio-dir = /Applications/Android Studio.app/
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)

[✓] VS Code (version 1.84.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.76.0

[✓] Connected device (4 available)
    • RMX2001 (mobile) • EUYTFEUSQSRGDA6D                         • android-arm64  • Android 11 (API 30)
    • iPhone (mobile)  • d9a94afe2b649fef56ba0bfeb052f0f2a7dae95e • ios            • iOS 15.8 19H370
    • macOS (desktop)  • macos                                    • darwin-x64     • macOS 14.1 23B74 darwin-x64
    • Chrome (web)     • chrome                                   • web-javascript • Google Chrome 119.0.6045.159

[✓] Network resources
    • All expected network resources are available.

! Doctor found issues in 2 categories.

@huycozy huycozy added platform-ios iOS applications specifically platform-web Web applications specifically p: video_player The Video Player plugin package flutter/packages repository. See also p: labels. c: rendering UI glitches reported at the engine/skia rendering level team-web Owned by Web platform team has reproducible steps The issue has been confirmed reproducible and is ready to work on found in release: 3.16 Found to occur in 3.16 found in release: 3.17 Found to occur in 3.17 fyi-ecosystem For the attention of Ecosystem team and removed in triage Presently being triaged by the triage team labels Nov 29, 2023
@debasmitasarkar
Copy link

Sorry, I typed it wrong. I meant the issue appears on both Web (iOS browsers) and iOS app.

I checked this again and confirmed the issue is only on Web (iOS browsers: Safari, Chrome).

On iOS Flutter app, the first frame (or video thumbnail) is rendering normally; the same on Chrome browser on Android.

iOS app Android browser: Chrome iOS browsers: Safari, Chrome
✅ ✅ ❗
✅: No Issue ❗: Issue reproduced

flutter doctor -v (stable and master)

I am still facing this on ios, the first frame does not automatically show up. Is there any work around?

@stuartmorgan stuartmorgan added the triaged-ecosystem Triaged by Ecosystem team label Dec 5, 2023
@flutter-triage-bot flutter-triage-bot bot removed fyi-ecosystem For the attention of Ecosystem team triaged-ecosystem Triaged by Ecosystem team labels Dec 5, 2023
@yjbanov yjbanov added triaged-web Triaged by Web platform team P2 Important issues not at the top of the work list labels Dec 7, 2023
@rogisolorzano
Copy link

rogisolorzano commented Dec 21, 2023

The issue seems to be that when we call setState to re-render immediately after initialization, the first frame might not actually be ready yet. The video could still be buffering.

I fixed it by adding a listener that checks that something has actually buffered (_controller.value.buffered.isNotEmpty), then calls setState:

@override
void initState() {
  super.initState();
  _controller = VideoPlayerController.networkUrl(Uri.parse(url));
  _controller.initialize();
  _controller.addListener(_listenForFirstFrameReady);
}

void _listenForFirstFrameReady() {
  if (_controller.value.buffered.isNotEmpty) {
    _controller.removeListener(_listenForFirstFrameReady);
    setState(() {});
  }
}

@austinlee1993
Copy link
Author

HI @rogisolorzano thanks for looking into this - I'm trying the code you provided but it seems when the _controller.value.buffered is being checked on whether or not it is being empty, the _controller.value.buffered is empty hence the setState is never called; what can be done to make sure the setState will be called?

@rogisolorzano
Copy link

rogisolorzano commented Dec 26, 2023

Hey @austinlee1993, I noticed this as well after testing on more platforms. I ended up going with seeking after initialization to force something to be buffered.

@override
void initState() {
  super.initState();
  _controller = VideoPlayerController.networkUrl(Uri.parse(url));
  _controller
      .initialize()
      .then((value) => _controller.seekTo(const Duration(milliseconds: 5)));
  _controller.addListener(_listenForFirstFrameReady);
}

Future<void> _listenForFirstFrameReady() async {
  if (_controller.value.buffered.isNotEmpty) {
    _controller.removeListener(_listenForFirstFrameReady);
    await Future.delayed(const Duration(milliseconds: 75));
    setState(() {});
  }
}

I also had to add a small delay between when we detect something is buffered and when we call setState. There seems to be a race condition between when something is buffered and when it is ready to display. I wasn't able to find a way around that without an arbitrary delay.

It seems like having a way to reliably know when the first frame is ready across platforms would be valuable to have in video_player.

@austinlee1993
Copy link
Author

@rogisolorzano - I'm still encountering the same issue I had before - even adding the .seekTo method after initialization, by the time _listenForFirstFrameReady() is running, the _controller.value.buffered is still empty, so I cant get the other things to even run - interesting to see how you got it to run on your end.

@rogisolorzano
Copy link

@austinlee1993 I only tested on iOS and Android (native), looks like it might not work in browsers for some reason 😭

FWIW, I ultimately abandoned that approach and decided to generate a thumbnail in my backend as part of processing the video. I show the thumbnail before the video is played for the first time, using a Stack and Image.

For larger videos, getting that first frame in a state where it is ready to display can take a bit. A lightweight thumbnail image loads quickly and feels much snappier to the user.

@austinlee1993
Copy link
Author

@rogisolorzano - would be interested in seeing how to generate the thumbnail in the backend! Maybe there's a small chance it could work for me..

But anyway - really odd the thumbnail doesn't generate by default for mobile browser - it works for desktop browser hence why I was hoping the video_player team could look into this.

@austinlee1993

This comment was marked as duplicate.

@osh91
Copy link

osh91 commented Jan 27, 2024

The issue seems to be that when we call setState to re-render immediately after initialization, the first frame might not actually be ready yet. The video could still be buffering.

I fixed it by adding a listener that checks that something has actually buffered (_controller.value.buffered.isNotEmpty), then calls setState:

@override
void initState() {
  super.initState();
  _controller = VideoPlayerController.networkUrl(Uri.parse(url));
  _controller.initialize();
  _controller.addListener(_listenForFirstFrameReady);
}

void _listenForFirstFrameReady() {
  if (_controller.value.buffered.isNotEmpty) {
    _controller.removeListener(_listenForFirstFrameReady);
    setState(() {});
  }
}

How can I ever thank you?
I was about to loose my hope. This is the answer. Thank you so much!

rajveermalviya added a commit to rajveermalviya/zulip-flutter that referenced this issue Mar 26, 2024
Implement thumbnail image based video previews for Youtube & Vimeo
video links, and inline video player preview using the video_player
package for user uploaded videos.

For user uploaded video, current implementation will fetch the metadata
when the message containing the video comes into view. This metadata
is used by the player to determine if video is supported on the device.
If it isn't then there will be no preview, and tapping on the play
button will open the video externally. If the video is supported, then
the first frame of the video will be presented as a preview in the
message container while tapping on the play button will start buffering
and playing the video in the lightbox.

There are still some quirks with the current implementation:

- On iOS/macOS, there is a bug where whole video is downloaded before
  playing: flutter/flutter#126760

- On iOS/macOS, unlike on Android the first frame is not shown after
  initialization: flutter/flutter#139107

- Current implementation uses url_launcher for fallback in case video
  is not supported by video_player, we should switch to webview
  instead to correctly handle auth headers for private videos.

Fixes zulip#356
rajveermalviya added a commit to rajveermalviya/zulip-flutter that referenced this issue Mar 26, 2024
Implement thumbnail image based video previews for Youtube & Vimeo
video links, and inline video player preview using the video_player
package for user uploaded videos.

For user uploaded video, current implementation will fetch the metadata
when the message containing the video comes into view. This metadata
is used by the player to determine if video is supported on the device.
If it isn't then there will be no preview, and tapping on the play
button will open the video externally. If the video is supported, then
the first frame of the video will be presented as a preview in the
message container while tapping on the play button will start buffering
and playing the video in the lightbox.

There are still some quirks with the current implementation:

- On iOS/macOS, there is a bug where whole video is downloaded before
  playing: flutter/flutter#126760

- On iOS/macOS, unlike on Android the first frame is not shown after
  initialization: flutter/flutter#139107

- Current implementation uses url_launcher for fallback in case video
  is not supported by video_player, we should switch to webview
  instead to correctly handle auth headers for private videos.

Fixes zulip#356
rajveermalviya added a commit to rajveermalviya/zulip-flutter that referenced this issue Mar 26, 2024
Implement thumbnail image based video previews for Youtube & Vimeo
video links, and inline video player preview using the video_player
package for user uploaded videos.

For user uploaded video, current implementation will fetch the metadata
when the message containing the video comes into view. This metadata
is used by the player to determine if video is supported on the device.
If it isn't then there will be no preview, and tapping on the play
button will open the video externally. If the video is supported, then
the first frame of the video will be presented as a preview in the
message container while tapping on the play button will start buffering
and playing the video in the lightbox.

There are still some quirks with the current implementation:

- On iOS/macOS, there is a bug where whole video is downloaded before
  playing: flutter/flutter#126760

- On iOS/macOS, unlike on Android the first frame is not shown after
  initialization: flutter/flutter#139107

- Current implementation uses url_launcher for fallback in case video
  is not supported by video_player, we should switch to webview
  instead to correctly handle auth headers for private videos.

Fixes zulip#356
rajveermalviya added a commit to rajveermalviya/zulip-flutter that referenced this issue Mar 28, 2024
Implement thumbnail image based video previews for Youtube & Vimeo
video links, and inline video player preview using the video_player
package for user uploaded videos.

For user uploaded video, current implementation will fetch the metadata
when the message containing the video comes into view. This metadata
is used by the player to determine if video is supported on the device.
If it isn't then there will be no preview, and tapping on the play
button will open the video externally. If the video is supported, then
the first frame of the video will be presented as a preview in the
message container while tapping on the play button will start buffering
and playing the video in the lightbox.

There are still some quirks with the current implementation:

- On iOS/macOS, there is a bug where whole video is downloaded before
  playing: flutter/flutter#126760

- On iOS/macOS, unlike on Android the first frame is not shown after
  initialization: flutter/flutter#139107

- Current implementation uses url_launcher for fallback in case video
  is not supported by video_player, we should switch to webview
  instead to correctly handle auth headers for private videos.

Fixes zulip#356
rajveermalviya added a commit to rajveermalviya/zulip-flutter that referenced this issue Mar 29, 2024
Implement thumbnail image based video previews for Youtube & Vimeo
video links, and inline video player preview using the video_player
package for user uploaded videos.

For user uploaded video, current implementation will fetch the metadata
when the message containing the video comes into view. This metadata
is used by the player to determine if video is supported on the device.
If it isn't then there will be no preview, and tapping on the play
button will open the video externally. If the video is supported, then
the first frame of the video will be presented as a preview in the
message container while tapping on the play button will start buffering
and playing the video in the lightbox.

There are still some quirks with the current implementation:

- On iOS/macOS, there is a bug where whole video is downloaded before
  playing: flutter/flutter#126760

- On iOS/macOS, unlike on Android the first frame is not shown after
  initialization: flutter/flutter#139107

- Current implementation uses url_launcher for fallback in case video
  is not supported by video_player, we should switch to webview
  instead to correctly handle auth headers for private videos.

Fixes zulip#356
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c: rendering UI glitches reported at the engine/skia rendering level found in release: 3.16 Found to occur in 3.16 found in release: 3.17 Found to occur in 3.17 has reproducible steps The issue has been confirmed reproducible and is ready to work on p: video_player The Video Player plugin P2 Important issues not at the top of the work list package flutter/packages repository. See also p: labels. platform-ios iOS applications specifically platform-web Web applications specifically team-web Owned by Web platform team triaged-web Triaged by Web platform team
Projects
None yet
Development

No branches or pull requests

7 participants