Skip to content

Commit 7f5d12f

Browse files
YouTube fix
1 parent 9038db1 commit 7f5d12f

8 files changed

Lines changed: 495 additions & 42 deletions

File tree

yuuna/android/app/src/main/java/app/lrorpilla/yuuna/AnkiDroidHelper.java renamed to yuuna/android/app/src/main/java/app/arianneorpilla/yuuna/AnkiDroidHelper.java

File renamed without changes.

yuuna/android/app/src/main/java/app/lrorpilla/yuuna/MainActivity.java renamed to yuuna/android/app/src/main/java/app/arianneorpilla/yuuna/MainActivity.java

File renamed without changes.

yuuna/lib/media.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export 'src/media/source_types/viewer_media_source.dart';
1414
export 'src/media/sources/player_local_media_source.dart';
1515
export 'src/media/sources/player_network_stream_source.dart';
1616
export 'src/media/sources/player_youtube_source.dart';
17+
export 'src/media/sources/player_youtube_source_util.dart';
1718
export 'src/media/sources/reader_ttu_source.dart';
1819
export 'src/media/sources/reader_browser_source.dart';
1920
export 'src/media/sources/reader_lyrics_source.dart';

yuuna/lib/src/media/source_types/player_media_source.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import 'dart:async';
22
import 'dart:io';
33

4+
import 'package:ffmpeg_kit_https_flutter/ffmpeg_kit.dart';
45
import 'package:ffmpeg_kit_https_flutter/ffmpeg_session.dart';
56
import 'package:flutter/material.dart';
67
import 'package:flutter/services.dart';
7-
import 'package:ffmpeg_kit_https_flutter/ffmpeg_kit.dart';
88
import 'package:flutter_riverpod/flutter_riverpod.dart';
99
import 'package:flutter_vlc_player/flutter_vlc_player.dart';
1010
import 'package:fluttertoast/fluttertoast.dart';
@@ -255,14 +255,16 @@ abstract class PlayerMediaSource extends MediaSource {
255255

256256
MediaSource source = item.getMediaSource(appModel: appModel);
257257
if (source is PlayerYoutubeSource) {
258-
inputPath = await source.getAudioUrl(item, playerController.dataSource);
258+
inputPath =
259+
await source.getAudioExportUrl(item, playerController.dataSource);
259260
audioIndex = 0;
260261
}
261262

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

265266
await FFmpegKit.execute(command);
267+
debugPrint(inputPath, wrapWidth: 10000);
266268

267269
return audioFile;
268270
}

yuuna/lib/src/media/sources/player_youtube_source.dart

Lines changed: 23 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ class PlayerYoutubeSource extends PlayerMediaSource {
479479
/// Get cached item.
480480
List<String>? getSubtitleItems(String videoId) {
481481
return getPreference<List<String>?>(
482-
key: 'subtitles_cache/$videoId',
482+
key: 'subs_cache/$videoId',
483483
defaultValue: null,
484484
);
485485
}
@@ -488,15 +488,15 @@ class PlayerYoutubeSource extends PlayerMediaSource {
488488
void setSubtitleItems(
489489
{required String videoId, required List<String> subtitles}) async {
490490
await setPreference<List<String>?>(
491-
key: 'subtitles_cache/$videoId',
491+
key: 'subs_cache/$videoId',
492492
value: subtitles,
493493
);
494494
}
495495

496496
/// Get cached item.
497497
List<String>? getSubtitleMetadata(String videoId) {
498498
return getPreference<List<String>?>(
499-
key: 'subtitle_metadata_cache/$videoId',
499+
key: 'subs_meta_cache/$videoId',
500500
defaultValue: null,
501501
);
502502
}
@@ -505,7 +505,7 @@ class PlayerYoutubeSource extends PlayerMediaSource {
505505
void setSubtitleMetadata(
506506
{required String videoId, required List<String> metadata}) async {
507507
await setPreference<List<String>?>(
508-
key: 'subtitle_metadata_cache/$videoId',
508+
key: 'subs_meta_cache/$videoId',
509509
value: metadata,
510510
);
511511
}
@@ -559,20 +559,21 @@ class PlayerYoutubeSource extends PlayerMediaSource {
559559
Future<String> getAudioUrl(MediaItem item, String dataSource) async {
560560
StreamManifest manifest = getStreamManifest(item);
561561

562-
if (manifest.muxed
563-
.where((e) => e.videoCodec.contains('avc1'))
564-
.map((e) => e.url.toString())
565-
.contains(dataSource)) {
562+
if (manifest.muxed.map((e) => e.url.toString()).contains(dataSource)) {
566563
return dataSource;
567564
} else {
568565
AudioStreamInfo streamAudioInfo =
569-
manifest.audioOnly.sortByBitrate().lastWhere((info) {
570-
return info.audioCodec.contains('mp4a');
571-
});
566+
manifest.audioOnly.sortByBitrate().first;
572567
return streamAudioInfo.url.toString();
573568
}
574569
}
575570

571+
/// Used to get the audio source for a video.
572+
Future<String> getAudioExportUrl(MediaItem item, String dataSource) async {
573+
StreamManifest manifest = getStreamManifest(item);
574+
return manifest.audio.first.url.toString();
575+
}
576+
576577
/// Gets the video qualities available for a [StreamManifest].
577578
List<VideoQuality> getVideoQualities(
578579
StreamManifest manifest,
@@ -997,33 +998,21 @@ Future<VideoManifest> computeManifests(ComputeManifestParams params) async {
997998
if (!params.subtitlesCached) {
998999
entries.addAll(
9991000
await Future.wait(
1000-
tracksByLanguage.values.map(
1001+
tracksByLanguage.values.whereNot((e) => e.isAutoGenerated).map(
10011002
(trackInfo) async {
10021003
String shortCode = trackInfo.language.code.substring(0, 2);
1003-
String subtitles =
1004-
await yt.videos.closedCaptions.getSubTitles(trackInfo);
1005-
1006-
if (trackInfo.isAutoGenerated) {
1007-
subtitles = subtitles.replaceAllMapped(vttRegex, (match) {
1008-
String text = match.group(11) ?? '';
1009-
List<String> lines = text.split('\n');
1010-
1011-
String currentSubtitle =
1012-
subtitles.substring(match.start, match.end);
1013-
int position = currentSubtitle
1014-
.lastIndexOf(text)
1015-
.clamp(0, currentSubtitle.length);
1016-
1017-
String newSubtitle = currentSubtitle.replaceFirst(
1018-
text, lines.last.trim(), position);
1019-
1020-
return newSubtitle;
1021-
});
1004+
String xml = await YouTubeTranscriptFetcher().fetchCaptions(
1005+
params.videoId,
1006+
languageCode: trackInfo.language.code);
1007+
final captions = CaptionParser.parseXml(xml);
1008+
final sb = StringBuffer('WEBVTT\n');
1009+
1010+
for (final caption in captions) {
1011+
sb.write(caption.vtt);
10221012
}
10231013

1024-
String metadata = trackInfo.isAutoGenerated
1025-
? 'YouTube - Auto - [$shortCode]'
1026-
: 'YouTube - CC - [$shortCode]';
1014+
final metadata = 'YouTube - CC - [$shortCode]';
1015+
final subtitles = sb.toString().trim();
10271016

10281017
return MapEntry(metadata, subtitles);
10291018
},

0 commit comments

Comments
 (0)