getVideoThumbnail static method

Future<FFmpegVideoResult?> getVideoThumbnail(
  1. String inputPath,
  2. String outputPath
)

Implementation

static Future<FFmpegVideoResult?> getVideoThumbnail(
    String inputPath, String outputPath) async {
  try {
    final inputName = p.basenameWithoutExtension(inputPath);
    final exten = _extension(outputPath);
    outputPath = await _fixUnicodeFileName(
        '${p.dirname(outputPath)}/$inputName$exten');
    if (File(outputPath).existsSync()) {
      await File(outputPath).delete();
    }
    // === Video info ===
    var videoInfo = await getVideoInfo(inputPath);
    debugPrint('==========Video input info==========');
    debugPrint('Duration: ${videoInfo.duration}');
    debugPrint('Width: ${videoInfo.width}');
    debugPrint('Height: ${videoInfo.height}');

    final duration = double.tryParse(videoInfo.duration ?? "0")?.toInt() ?? 0;
    const startTime = 1;

    final outputPathVideoTrim = (await _fixUnicodeFileName(inputPath))
        .replaceAll(RegExp(r'\.[a-zA-Z0-9]+$'), '_trimmed.mp4');

    // === FFmpeg trim command ===
    final trimCmd =
        '-i "$inputPath" -ss $startTime -t $duration -c:v copy -c:a copy "$outputPathVideoTrim"';

    final trimSession = await FFmpegKit.execute(trimCmd);

    final trimState = await trimSession.getState();
    final trimCode = await trimSession.getReturnCode();

    debugPrint("TRIM STATE: $trimState");
    debugPrint("TRIM CODE: $trimCode");

    if (!ReturnCode.isSuccess(trimCode)) {
      debugPrint(
          "❌ Trim video failed: ${await trimSession.getAllLogsAsString()}");
      return null;
    }
    await Future.delayed(const Duration(milliseconds: 500));

    if (!await File(outputPathVideoTrim).exists()) {
      debugPrint("❌ Trimmed video file does NOT exist after trim!");
      return null;
    }

    // === FFmpeg create thumbnail ===
    final thumbCmd =
        '-i "$outputPathVideoTrim" -ss 1 -frames:v 1 -vf scale=320:-1 "$outputPath"';

    final thumbSession = await FFmpegKit.execute(thumbCmd);
    final thumbState = await thumbSession.getState();
    final thumbCode = await thumbSession.getReturnCode();

    debugPrint("THUMB STATE: $thumbState");
    debugPrint("THUMB CODE: $thumbCode");

    if (!ReturnCode.isSuccess(thumbCode)) {
      debugPrint(
          "❌ Thumbnail creation failed: ${await thumbSession.getAllLogsAsString()}");
      return null;
    }

    await Future.delayed(const Duration(milliseconds: 500));

    if (!await File(outputPath).exists()) {
      debugPrint("❌ Thumbnail file NOT FOUND after creation!");
      return null;
    }

    // final thumbnailInfo = await getImageInfo(outputPath);

    // return FFmpegVideoResult(
    //     outputPath, thumbSession, videoInfo, thumbnailInfo);
    return FFmpegVideoResult(
        outputPath, thumbSession, videoInfo, null);
  } catch (e) {
    return null;
  }
}