generateAudio method

  1. @override
Future<File?>? generateAudio(
  1. {required AppModel appModel,
  2. required MediaItem item,
  3. List<Subtitle>? subtitles,
  4. SubtitleOptions? options,
  5. String? data}
)
override

If this source is non-null, this will be used as the initial function for the audio field over the auto enhancement.

Implementation

@override
Future<File?>? generateAudio({
  required AppModel appModel,
  required MediaItem item,
  List<Subtitle>? subtitles,
  SubtitleOptions? options,
  String? data,
}) async {
  while (appModel.blockCreatorInitialMedia) {
    await Future.delayed(const Duration(seconds: 1), () {});
  }

  if (appModel.isProcessingEmbeddedSubtitles) {
    return null;
  }

  Directory appDirDoc = await getApplicationSupportDirectory();
  String playerPreviewPath = '${appDirDoc.path}/playerAudioPreview';
  Directory playerPreviewDir = Directory(playerPreviewPath);
  if (playerPreviewDir.existsSync()) {
    playerPreviewDir.deleteSync(recursive: true);
  }
  playerPreviewDir.createSync();

  File audioFile = appModel.getAudioPreviewFile(playerPreviewDir);
  String outputPath = audioFile.path;
  if (audioFile.existsSync()) {
    audioFile.deleteSync();
  }

  String timeStart = '';
  String timeEnd = '';

  VlcPlayerController playerController = appModel.currentPlayerController!;
  Map<int, String> embeddedTracks = await playerController.getAudioTracks();

  int audioIndex = await playerController.getAudioTrack() ?? 0;
  for (int i = 0; i < embeddedTracks.length; i++) {
    MapEntry<int, String> entry = embeddedTracks.entries.elementAt(i);
    if (audioIndex == entry.key) {
      audioIndex = i;
    }
  }

  Duration allowance = Duration(milliseconds: options!.audioAllowance);
  Duration delay = Duration(milliseconds: options.subtitleDelay);

  if (subtitles == null && _transcriptSubtitle != null) {
    subtitles = [_transcriptSubtitle!];
  }

  if (subtitles == null && appModel.currentSubtitle.value != null) {
    subtitles ??= [appModel.currentSubtitle.value!];
  }

  Duration adjustedStart = subtitles!.first.start - delay - allowance;
  Duration adjustedEnd = subtitles.last.end - delay + allowance;
  timeStart = JidoujishoTimeFormat.getFfmpegTimestamp(adjustedStart);
  timeEnd = JidoujishoTimeFormat.getFfmpegTimestamp(adjustedEnd);

  String inputPath = item.mediaIdentifier;

  MediaSource source = item.getMediaSource(appModel: appModel);
  if (source is PlayerYoutubeSource) {
    inputPath = await source.getAudioUrl(item, playerController.dataSource);
    audioIndex = 0;
  }

  String command =
      '-ss $timeStart -to $timeEnd -y -i "$inputPath" -map 0:a:$audioIndex "$outputPath"';

  final FlutterFFmpeg _flutterFFmpeg = FlutterFFmpeg();
  await _flutterFFmpeg.execute(command);

  return audioFile;
}