arthenica / ffmpeg-kit

FFmpeg Kit for applications. Supports Android, Flutter, iOS, Linux, macOS, React Native and tvOS. Supersedes MobileFFmpeg, flutter_ffmpeg and react-native-ffmpeg.
https://arthenica.github.io/ffmpeg-kit
GNU Lesser General Public License v3.0
3.99k stars 541 forks source link

MissingPluginException(No implementation found for method getLogLevel on channel flutter.arthenica.com/ffmpeg_kit) package:flutter/src/services/platform_channel.dart 332:7 MethodChannel._invokeMethod #985

Open stephane-archer opened 1 month ago

stephane-archer commented 1 month ago

I added ffmpeg_kit_flutter to my Flutter app but when doing flutter test I get the following message:

  MissingPluginException(No implementation found for method getLogLevel on channel flutter.arthenica.com/ffmpeg_kit)
  package:flutter/src/services/platform_channel.dart 332:7  MethodChannel._invokeMethod

How to solve this?

kkuivi commented 1 month ago

Hi @stephane-archer were you able to find a solution to this?

stephane-archer commented 1 month ago

Hi @kkuivi, no I didn't find a solution

RudyTM commented 1 month ago

I am getting the error if I run it in a Background service or another isolate; When I run it in my main Isolate it works fine T_T

duggisetty commented 1 month ago

Hi @RudyTM were you able to find a solution to this?

RudyTM commented 1 month ago

Sadly no @duggisetty

I am using flutter 3.19.6 The package what I am using for this, is flutter_background_service I have tried using FlutterIsolate; I have used DartPluginRegistrant.ensureInitialized() in my service too. I also tried t oregister the plugins at app level instead of Activity :|

But no, no success I'll try today, if I can come with something new.

It's the isolate, In the main isolate it works like a charm.

kkuivi commented 1 month ago

Hi @RudyTM do you mind sharing a code snippet of what you are doing in main isolate to make it work?

RudyTM commented 1 month ago

Right now I'm using this

@pragma('vm:entry-point')
Future<String?> compressVideo(Map<String, dynamic> json) async {
  final config = VideoCompressionConfig.fromJson(json);
  List<String> commandParts = ["-i", config.inputPath, "-vcodec", "libx264"];

  if (config.crf != null) {
    commandParts.addAll(["-crf", config.getCRF().toString()]);
  }
  if (config.preset != null) {
    commandParts.addAll(["-preset", config.getPreset()]);
  }
  if (config.bitrate != null) {
    commandParts.addAll([
      "-b:v",
      "${config.bitrate}k",
      "-maxrate",
      "${config.bitrate}k",
      "-bufsize",
      "${config.bitrate! * 2}k"
    ]);
  }

  commandParts.add(config.outputPath);

  final String command = commandParts.join(" ");
  final session = await FFmpegKit.execute(command);
  final returnCode = await session.getReturnCode();

  if (ReturnCode.isSuccess(returnCode)) {
    return config.outputPath;
  } else {
    final log = await session.getOutput();
    Fimber.e("FFmpeg process failed with log: $log");
    return null;
  }
}

I use it normal :P right now is a top level function because the service, but being a class function it works too...

My config class is this

@JsonSerializable(explicitToJson: true)
class VideoCompressionConfig {
  final String inputPath;
  final String outputPath;
  final VideoPreset? preset;
  final CRF? crf;
  final int? bitrate;

  VideoCompressionConfig({
    required this.inputPath,
    required this.outputPath,
    this.preset,
    this.crf,
    this.bitrate,
  });

  factory VideoCompressionConfig.fromJson(Map<String, dynamic> json) =>
      _$VideoCompressionConfigFromJson(json);

  Map<String, dynamic> toJson() => _$VideoCompressionConfigToJson(this)..removeWhere((dynamic key, dynamic value) => key == null || value == null);

  @override
  String toString() => toJson().toString();

  String getPreset() {
    switch (preset) {
      case VideoPreset.ultrafast:
        return 'ultrafast';
      case VideoPreset.superFast:
        return 'superfast';
      case VideoPreset.veryFast:
        return 'veryfast';
      case VideoPreset.faster:
        return 'faster';
      case VideoPreset.fast:
        return 'fast';
      case VideoPreset.medium:
        return 'medium';
      case VideoPreset.slow:
        return 'slow';
      case VideoPreset.slower:
        return 'slower';
      case VideoPreset.verySlow:
        return 'veryslow';
      default:
        return 'medium';
    }
  }

  int getCRF() {
    switch (crf) {
      case CRF.low:
        return 18;
      case CRF.medium:
        return 28;
      case CRF.high:
        return 35;
      default:
        return 28;
    }
  }
}
duggisetty commented 1 month ago

Hi @RudyTM .If you find the solution , can u please share it

eokdev commented 2 weeks ago

Hi @RudyTM any luck?