70 lines
2.7 KiB
Dart
70 lines
2.7 KiB
Dart
import '../../extensions/helpers_extension.dart';
|
|
import '../../reverse_engineering/responses/closed_caption_client.dart' as re
|
|
show ClosedCaptionClient;
|
|
import '../../reverse_engineering/responses/video_info_client.dart';
|
|
import '../../reverse_engineering/youtube_http_client.dart';
|
|
import '../videos.dart';
|
|
import 'closed_caption.dart';
|
|
import 'closed_caption_format.dart';
|
|
import 'closed_caption_manifest.dart';
|
|
import 'closed_caption_part.dart';
|
|
import 'closed_caption_track.dart';
|
|
import 'closed_caption_track_info.dart';
|
|
import 'language.dart';
|
|
|
|
/// Queries related to closed captions of YouTube videos.
|
|
class ClosedCaptionClient {
|
|
final YoutubeHttpClient _httpClient;
|
|
|
|
/// Initializes an instance of [ClosedCaptionClient]
|
|
ClosedCaptionClient(this._httpClient);
|
|
|
|
/// Gets the manifest that contains information
|
|
/// about available closed caption tracks in the specified video.
|
|
Future<ClosedCaptionManifest> getManifest(
|
|
dynamic videoId,
|
|
{@Deprecated('Not used anymore, use track.isAutoGenerated to see if a track is autogenerated or not.') // ignore: lines_longer_than_80_chars
|
|
bool autoGenerated = false,
|
|
List<ClosedCaptionFormat> formats = const [
|
|
ClosedCaptionFormat.srv1,
|
|
ClosedCaptionFormat.srv2,
|
|
ClosedCaptionFormat.srv3,
|
|
ClosedCaptionFormat.ttml,
|
|
ClosedCaptionFormat.vtt
|
|
]}) async {
|
|
videoId = VideoId.fromString(videoId);
|
|
var tracks = <ClosedCaptionTrackInfo>{};
|
|
var videoInfoResponse =
|
|
await VideoInfoClient.get(_httpClient, videoId.value);
|
|
var playerResponse = videoInfoResponse.playerResponse;
|
|
|
|
for (final track in playerResponse.closedCaptionTrack) {
|
|
for (final ext in formats) {
|
|
tracks.add(ClosedCaptionTrackInfo(
|
|
Uri.parse(track.url)
|
|
.replaceQueryParameters({'fmt': ext.formatCode}),
|
|
Language(track.languageCode, track.languageName),
|
|
isAutoGenerated: track.autoGenerated,
|
|
format: ext));
|
|
}
|
|
}
|
|
return ClosedCaptionManifest(tracks);
|
|
}
|
|
|
|
/// Gets the actual closed caption track which is
|
|
/// identified by the specified metadata.
|
|
Future<ClosedCaptionTrack> get(ClosedCaptionTrackInfo trackInfo) async {
|
|
var response = await re.ClosedCaptionClient.get(_httpClient, trackInfo.url);
|
|
|
|
var captions = response.closedCaptions
|
|
.where((e) => !e.text.isNullOrWhiteSpace)
|
|
.map((e) => ClosedCaption(e.text, e.offset, e.duration,
|
|
e.parts.map((f) => ClosedCaptionPart(f.text, f.offset))));
|
|
return ClosedCaptionTrack(captions);
|
|
}
|
|
|
|
/// Returns the subtitles as a string.
|
|
Future<String> getSubTitles(ClosedCaptionTrackInfo trackInfo) =>
|
|
_httpClient.getString(trackInfo.url);
|
|
}
|