video_thumbnail icon indicating copy to clipboard operation
video_thumbnail copied to clipboard

[feature/web]: Add Support for Flutter Web (sample provided)

Open Ahmadre opened this issue 4 years ago • 27 comments

I encountered,. that this package only works for ios and android.

I got pure 100% dart solution for flutter web:

  void getVideoThumbnail(String path, callback) {
    html.VideoElement video = html.document.createElement('video');
    video.src = path;

    video.onSeeked.listen((html.Event e) {
      html.CanvasElement canvas = html.document.createElement('canvas');
      canvas.height = video.videoHeight;
      canvas.width = video.videoWidth;
      html.CanvasRenderingContext2D ctx = canvas.getContext('2d');
      ctx.drawImage(video, canvas.width, canvas.height);
      html.ImageElement img = new html.ImageElement();
      img.src = canvas.toDataUrl();
      callback.call(img, e);
    });
    video.onError.listen((html.Event e) {
      callback.call(null, e);
    });
  }

Maybe you can combine that with your platform channels and create a platform interface :).

Code ported from: https://cwestblog.com/2017/05/03/javascript-snippet-get-video-frame-as-an-image/

Ahmadre avatar Feb 27 '20 03:02 Ahmadre

Thanks, will take a deep look once find some free time.

justsoft avatar Feb 27 '20 08:02 justsoft

I encountered that video_player package itself is supporting thumbnails on init:

Bildschirmfoto 2020-02-28 um 21 09 16

You only need to:

VideoPlayerController controller =
            VideoPlayerController.network(snapshot.data()['mediaURL'])..initialize();
return VideoPlayer(controller);

Ahmadre avatar Feb 28 '20 20:02 Ahmadre

I encountered that video_player package itself is supporting thumbnails on init:

Bildschirmfoto 2020-02-28 um 21 09 16

You only need to:

VideoPlayerController controller =
            VideoPlayerController.network(snapshot.data()['mediaURL'])..initialize();
return VideoPlayer(controller);

Hello @Ahmadre , I'm trying to find a way to create thumbnail on Flutter Web. can you explain how I can achieve it using this? I had two data that can hold my video, using image_picker_for_web that gives a network path or a byte data.

markgrancapal avatar Jun 13 '20 08:06 markgrancapal

I encountered,. that this package only works for ios and android.

I got pure 100% dart solution for flutter web:

  void getVideoThumbnail(String path, callback) {
    html.VideoElement video = html.document.createElement('video');
    video.src = path;

    video.onSeeked.listen((html.Event e) {
      html.CanvasElement canvas = html.document.createElement('canvas');
      canvas.height = video.videoHeight;
      canvas.width = video.videoWidth;
      html.CanvasRenderingContext2D ctx = canvas.getContext('2d');
      ctx.drawImage(video, canvas.width, canvas.height);
      html.ImageElement img = new html.ImageElement();
      img.src = canvas.toDataUrl();
      callback.call(img, e);
    });
    video.onError.listen((html.Event e) {
      callback.call(null, e);
    });
  }

Maybe you can combine that with your platform channels and create a platform interface :).

Code ported from: https://cwestblog.com/2017/05/03/javascript-snippet-get-video-frame-as-an-image/

I see that you are the one who develop image_picker_web, how can I use this code using your package? can I use html.File for the path? Thank you for the help @Ahmadre

markgrancapal avatar Jun 13 '20 11:06 markgrancapal

Hi, any updates on this one? Are we planning to add Flutter web support to this package?

allcui avatar May 01 '21 20:05 allcui

I encountered,. that this package only works for ios and android. I got pure 100% dart solution for flutter web:

  void getVideoThumbnail(String path, callback) {
    html.VideoElement video = html.document.createElement('video');
    video.src = path;

    video.onSeeked.listen((html.Event e) {
      html.CanvasElement canvas = html.document.createElement('canvas');
      canvas.height = video.videoHeight;
      canvas.width = video.videoWidth;
      html.CanvasRenderingContext2D ctx = canvas.getContext('2d');
      ctx.drawImage(video, canvas.width, canvas.height);
      html.ImageElement img = new html.ImageElement();
      img.src = canvas.toDataUrl();
      callback.call(img, e);
    });
    video.onError.listen((html.Event e) {
      callback.call(null, e);
    });
  }

Maybe you can combine that with your platform channels and create a platform interface :). Code ported from: https://cwestblog.com/2017/05/03/javascript-snippet-get-video-frame-as-an-image/

I see that you are the one who develop image_picker_web, how can I use this code using your package? can I use html.File for the path? Thank you for the help @Ahmadre

Not working with latest html version

abdullah432 avatar May 07 '21 20:05 abdullah432

Any updates on this?

bismarabia avatar Oct 06 '21 13:10 bismarabia

Any updates on this?

Alvarocda avatar Mar 16 '22 14:03 Alvarocda

Any update?

Thanks.

jcblancomartinez avatar Mar 16 '22 14:03 jcblancomartinez

did any one figure out this?

nathansdev avatar Mar 22 '22 10:03 nathansdev

Hi,

Here you have a newer working version with CORS enabled:

Future<void> _getVideoThumbnail(
      String path, void Function(Uint8List? imageBytes) callback) async {
    VideoElement video = VideoElement()
      ..crossOrigin = 'anonymous'
      ..src = path
      ..muted = true;
    CanvasElement canvas = CanvasElement();
    video.onLoadedMetadata.listen((Event event) async {
      canvas.width = video.videoWidth;
      canvas.height = video.videoHeight;
      video.currentTime = 0;
    });
    video.onSeeked.listen((Event event) async {
      CanvasRenderingContext2D ctx = canvas.context2D;
      ctx.drawImage(video, 0, 0);
      Blob blob = await canvas.toBlob('image/png', 0.95);
      XFile xFile = XFile(Url.createObjectUrlFromBlob(blob),
          mimeType: 'image/png',
          lastModified: DateTime.now(),
          length: blob.size);
      debugPrint('Obtained xFile=[${xFile.path}] for path=[$path].');
      callback.call(await xFile.readAsBytes());
    });
    video.onError.listen((Event event) async {
      debugPrint('Error processing path=[$path] with event=[$event].');
      callback.call(null);
    });
  }

Regards.

jcblancomartinez avatar Mar 31 '22 18:03 jcblancomartinez

Check out #135 PR.

Clone the repo (unfortunately dependency_overrides doesn't work since the PR contains local path)

git clone -b feat-web_implementation https://github.com/maRci002/video_thumbnail.git

Add it to your pubspec.yaml

dependencies:
  video_thumbnail:
    path: ../video_thumbnail/video_thumbnail

I have already tested it with video_editor package:

https://user-images.githubusercontent.com/8436039/229935809-2f146b7e-fe0a-4b50-99bc-a78ee63266a0.mp4

maRci002 avatar Apr 04 '23 22:04 maRci002

Can you give us a sample project for web?

I'm getting error when i run git clone code:

[video_thumbnail/video_thumbnail_web] flutter pub get Resolving dependencies... Git error. Command: git clone --mirror [email protected]:maRci002/video_thumbnail.git /Users/emre/.pub-cache/git/cache/video_thumbnail-eeb03d34cb54759a210a222943f9e014ba59971c stdout: stderr: Cloning into bare repository '/Users/emre/.pub-cache/git/cache/video_thumbnail-eeb03d34cb54759a210a222943f9e014ba59971c'... [email protected]: Permission denied (publickey). fatal: Could not read from remote repository.

Please make sure you have the correct access rights and the repository exists. exit code: 128 exit code 69

mehmetemregokberk avatar Jul 10 '23 23:07 mehmetemregokberk

I'm getting error when i run git clone code:

https://stackoverflow.com/a/51820472/4609658

use https link ( instead of [email protected] ): git clone --mirror https://github.com/maRci002/video_thumbnail.git

maRci002 avatar Jul 11 '23 07:07 maRci002

I'm getting error when i run git clone code:

https://stackoverflow.com/a/51820472/4609658

use https link ( instead of [email protected] ): git clone --mirror https://github.com/maRci002/video_thumbnail.git

Actually i'm running https url (git clone -b feat-web_implementation https://github.com/maRci002/video_thumbnail.git)

This is my vscode terminal output:

emre@Emres-MBP kindergarten % git clone -b feat-web_implementation https://github.com/maRci002/video_thumbnail.git
Cloning into 'video_thumbnail'...
remote: Enumerating objects: 820, done.
remote: Counting objects: 100% (201/201), done.
remote: Compressing objects: 100% (111/111), done.
remote: Total 820 (delta 83), reused 163 (delta 68), pack-reused 619
Receiving objects: 100% (820/820), 422.72 KiB | 2.04 MiB/s, done.
Resolving deltas: 100% (368/368), done.
emre@Emres-MBP kindergarten % 

And this is my Output window:

[video_thumbnail/video_thumbnail_web] flutter pub get
Resolving dependencies...
Git error. Command: `git clone --mirror [email protected]:maRci002/video_thumbnail.git /Users/emre/.pub-cache/git/cache/video_thumbnail-eeb03d34cb54759a210a222943f9e014ba59971c`
stdout: 
stderr: Cloning into bare repository '/Users/emre/.pub-cache/git/cache/video_thumbnail-eeb03d34cb54759a210a222943f9e014ba59971c'...
[email protected]: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
exit code: 128
exit code 69

mehmetemregokberk avatar Jul 11 '23 08:07 mehmetemregokberk

Okay I think I got it. Recently I made a commit to avoid local path and replace with git path and your output window using different SSH agent than the terminal https://github.com/justsoft/video_thumbnail/pull/135/commits/47435c7933c0b0b148acb9d79100e2e4aa369fae

I think if you run flutter pub get in the terminal your problem will be solved (because therminal has registered SSH key in your Github account)

So currently you do not need to manually clone the project and configuring local path, instead you can use this:

  video_thumbnail:
    git:
      url: [email protected]:maRci002/video_thumbnail.git
      ref: feat-web_implementation
      path: video_thumbnail

But I think this way you will get the same error, since the SSH agent which is used by Output window is not registered in your Github's SSH keys. https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account

If you cannot add SSH key to your github account for output window then

  • git clone -b feat-web_implementation https://github.com/maRci002/video_thumbnail.git
  • Go to video_thumbnail folder which is a git project and git checkout aa322f8fa61130b4ca56183aaebe82e0fb1c172c (this commit uses local path inside)
  • and in your project use local path
dependencies:
  video_thumbnail:
    path: ../video_thumbnail/video_thumbnail

maRci002 avatar Jul 11 '23 09:07 maRci002

Thank you so much. Your last opinion worked!

I'm normally call thumnail data like "final thumbData = await VideoThumbnail.thumbnailData(.." for ios-android. Do i need call differently for web?

mehmetemregokberk avatar Jul 11 '23 09:07 mehmetemregokberk

I think example is updated, you can also check out readme. https://github.com/justsoft/video_thumbnail/blob/47435c7933c0b0b148acb9d79100e2e4aa369fae/video_thumbnail/README.md

XFile thumbnailFile = await VideoThumbnail.thumbnailFile( ... );

final image = kIsWeb ? Image.network(thumbnailFile.path) : Image.file(File(thumbnailFile.path));


final uint8list = await VideoThumbnail.thumbnailData( ... );

final image = Image.memory(uint8list );

maRci002 avatar Jul 11 '23 11:07 maRci002

If I'm not mistaken, the video needs to be called via the url to be able to create thumbnails on the web? I choose videos from gallery on ios and android. In the same way, I plan to select videos on the web from the computer. But as you mentioned, in the documentation "This plugin requires the server hosting the video to support HTTP range headers." specified as. As I understand from here, there is no way to use it other than the url on the web?

mehmetemregokberk avatar Jul 12 '23 16:07 mehmetemregokberk

You can use localy picked files too since it lives on the filesystem and in that case the underlying VideoElement is smart enough to not create network calls with range headers.

In the example you can pick a media, for test choose a long one. https://github.com/maRci002/video_thumbnail/blob/47435c7933c0b0b148acb9d79100e2e4aa369fae/video_thumbnail/example/lib/main.dart#L381C1-L405C13

maRci002 avatar Jul 12 '23 18:07 maRci002

@maRci002 Sorry for the late reply due to the holiday. I was able to create thumbnail on web in debug mode but when i send it to hosting chrome gives below error. I think I'm getting this error because the plugin folder is on root? If so how can I include this folder in release?

Uncaught MissingPluginException(No implementation found for method data on channel plugins.justsoft.xyz/video_thumbnail) at Object.c (https://app.xyz.com.tr/main.dart.js:5341:3) at https://app.xyz.com.tr/main.dart.js:115732:15 at bQe.a (https://app.xyz.com.tr/main.dart.js:6674:62) at bQe.$2 (https://app.xyz.com.tr/main.dart.js:71952:14) at bOK.$1 (https://app.xyz.com.tr/main.dart.js:71946:21) at bKW.bvY (https://app.xyz.com.tr/main.dart.js:73065:34) at bKW.abA (https://app.xyz.com.tr/main.dart.js:73067:22) at bEy.$0 (https://app.xyz.com.tr/main.dart.js:72365:11) at Object.RJ (https://app.xyz.com.tr/main.dart.js:6810:40) at aA.yN (https://app.xyz.com.tr/main.dart.js:72289:3)

mehmetemregokberk avatar Jul 18 '23 10:07 mehmetemregokberk

@maRci002 Thank you for making this addition to support thumbnail generation on the web! I just tried your branch and it works perfectly.

Do you know what's the timeline to merge your PR ?

louisdeveseleer avatar Aug 03 '23 15:08 louisdeveseleer

Unfortunately, I don't have a timeline for the merge since I've just made the PR. It appears that the author of this package is no longer active.

maRci002 avatar Aug 03 '23 16:08 maRci002

Ok thank you for the information and for your work!

louisdeveseleer avatar Aug 03 '23 18:08 louisdeveseleer

@maRci002 If this package is abandoned and you feel like creating your own package from this one, I think it would be popular, because I've met many comments online from people looking for a solution to generate thumbnails for videos on the web.

louisdeveseleer avatar Aug 03 '23 18:08 louisdeveseleer

I'm getting error when i run git clone code:

https://stackoverflow.com/a/51820472/4609658 use https link ( instead of [email protected] ): git clone --mirror https://github.com/maRci002/video_thumbnail.git

Actually i'm running https url (git clone -b feat-web_implementation https://github.com/maRci002/video_thumbnail.git)

This is my vscode terminal output:

emre@Emres-MBP kindergarten % git clone -b feat-web_implementation https://github.com/maRci002/video_thumbnail.git
Cloning into 'video_thumbnail'...
remote: Enumerating objects: 820, done.
remote: Counting objects: 100% (201/201), done.
remote: Compressing objects: 100% (111/111), done.
remote: Total 820 (delta 83), reused 163 (delta 68), pack-reused 619
Receiving objects: 100% (820/820), 422.72 KiB | 2.04 MiB/s, done.
Resolving deltas: 100% (368/368), done.
emre@Emres-MBP kindergarten % 

And this is my Output window:

[video_thumbnail/video_thumbnail_web] flutter pub get
Resolving dependencies...
Git error. Command: `git clone --mirror [email protected]:maRci002/video_thumbnail.git /Users/emre/.pub-cache/git/cache/video_thumbnail-eeb03d34cb54759a210a222943f9e014ba59971c`
stdout: 
stderr: Cloning into bare repository '/Users/emre/.pub-cache/git/cache/video_thumbnail-eeb03d34cb54759a210a222943f9e014ba59971c'...
[email protected]: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
exit code: 128
exit code 69

@mehmetemregokberk sorry to go back to this but I had the same issue with the same responses and all. As @maRci002 said is a problem with the SSH key, in my case the Key on my mac to authenticate to GitHub was outdated (you can check by running ssh -vT [email protected] in your terminal)

What worked for me was removing the old key following this official instructions: https://github.blog/2023-03-23-we-updated-our-rsa-ssh-host-key/ (from https://github.com/orgs/community/discussions/50878) and then adding new SSH keys to my account following the instructions on the link that maRci002 provided: https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account there are a lot of steps but they are easy to follow.

lucho-dev avatar Aug 03 '23 23:08 lucho-dev

Playing with SSH is not fun at all. In my case, Git Bash was configured while PowerShell was not. Git, during the installation phase, asks if it should use the operating system's SSH agent or its own, so every terminal might work differently. Furthermore, if your project is managed via CI/CD on the cloud, it has its own terminal.

https://dart.dev/tools/pub/dependencies#git-packages So, I decided to use the HTTPS Git link instead of SSH, so you can use this in your pubspec.yaml:

dependencies:
  video_thumbnail:
    git:
      url: https://github.com/maRci002/video_thumbnail.git
      ref: feat-web_implementation
      path: video_thumbnail

maRci002 avatar Aug 05 '23 11:08 maRci002