justsoft / video_thumbnail

This plugin generates thumbnail from video file or URL. It returns image in memory or writes into a file. It offers rich options to control the image format, resolution and quality. Supports iOS and Android.
MIT License
183 stars 238 forks source link

Failed to write data to File #109

Closed FilledStacks closed 2 years ago

FilledStacks commented 2 years ago

I have been trying to debug this issue but I can't figure out why it's happening. The library has been failing to load thumbnails for some videos recorded on iOS. This is one of the videos and you'll see that the video works just fine.

If I retry to load it 5 times then it shows up 3 out of 5 times. I'm using the suggested code for this.

  _videoThumbnails[videoFileUrl] = await VideoThumbnail.thumbnailFile(
                  video: element.url,
                  thumbnailPath: (await getTemporaryDirectory()).path,
                ) ??
                '';

I've tried using a Fork mentioned in #94 but it doesn't work. Is there any way to get a clearer message of why this is happening. I'm running on iOS 15 and also on ipadOS 14.6.

Flutter Doctor [✓] Flutter (Channel stable, 2.10.4, on macOS 12.3.1 21E258 darwin-arm, locale en-ZA) • Flutter version 2.10.4 at /Users/danemackier/src/flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision c860cba910 (6 weeks ago), 2022-03-25 00:23:12 -0500 • Engine revision 57d3bac3dd • Dart version 2.16.2 • DevTools version 2.9.2 [✓] Android toolchain - develop for Android devices (Android SDK version 32.1.0-rc1) • Android SDK at /Users/danemackier/Library/Android/sdk • Platform android-32, build-tools 32.1.0-rc1 • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 11.0.11+0-b60-7772763) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 13.3.1) • Xcode at /Applications/Xcode.app/Contents/Developer • CocoaPods version 1.11.3 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 2021.1) • 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 • Java version OpenJDK Runtime Environment (build 11.0.11+0-b60-7772763) [✓] VS Code (version 1.67.0) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.40.0 [✓] Connected device (2 available) • Dane’s iPad (mobile) • 00008027-001648481E07002E • ios • iOS 14.6 18F72 • Chrome (web) • chrome • web-javascript • Google Chrome 101.0.4951.54 [✓] HTTP Host Availability • All required HTTP hosts are available
ahmadvicky commented 2 years ago

I got error in iOS

[VERBOSE-2:ui_dart_state.cc(198)] Unhandled Exception: PlatformException(IO Error, Failed to write data to file, null, null)

0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:607:7)

1 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:167:18)

#2 VideoThumbnail.thumbnailFile (package:video_thumbnail/video_thumbnail.dart:48:12)
justsoft commented 2 years ago

Please try the thumbnailData function first to detect what is causing this problem, if video source causes the issue or the writing data on device.

ahmadvicky commented 2 years ago

I already resolve it,

I mixed the function with the video player.

you can try this

VideoPlayerController videoPlayerController;

prepare(){ videoPlayerController = VideoPlayerController.file(valuepath); File file = File(valuepath); generateThumbnail(file, file.path); }

generateThumbnail(File video, String fileAnother) async { final String _videoPath = video.path;

double _eachPart = _videoDuration / _numberOfThumbnails;

List<Uint8List> _byteList = [];
// the cache of last thumbnail
Uint8List _lastBytes;

for (int i = 1; i <= _numberOfThumbnails; i++) {
  Uint8List _bytes;
  _bytes = await VideoThumbnail.thumbnailData(
    video: _videoPath,
    imageFormat: ImageFormat.JPEG,
    timeMs: (_eachPart * i).toInt(),
    quality: 75,
  );

  // if current thumbnail is null use the last thumbnail
  if (_bytes != null) {
    _lastBytes = _bytes;
    _byteList.add(_bytes);
  } else {
    // _bytes = _lastBytes;
    // _byteList.add(_bytes);
  }
}

// print("_bytes=== ${_lastBytes}");

if (_byteList.length > 0) {
  final tempDir = await getTemporaryDirectory();
  await File(
          '${tempDir.path}${DateTime.now().toString()}-${DateTime.now().microsecondsSinceEpoch}.png')
      .create()
      .then((value2) {
    value2.writeAsBytesSync(_byteList.first);

    videoFile.add(ImageFileUploadCommunity(
        file: video,
        fileAnother: fileAnother,
        fileThumbnail: value2,
        urlThumbnail: ""));

    setState(() {

      videoPlayerController.dispose();

      setState(() {

      });
    });
  });
}

}

justsoft commented 2 years ago

Thanks for the work around. The URL must be properly encoded, also the writing file path must be valid.