import '../../extensions/helpers_extension.dart'; import '../../reverse_engineering/responses/closed_caption_track_response.dart' show ClosedCaptionTrackResponse; import '../../reverse_engineering/responses/video_info_response.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 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 formats = const [ ClosedCaptionFormat.srv1, ClosedCaptionFormat.srv2, ClosedCaptionFormat.srv3, ClosedCaptionFormat.ttml, ClosedCaptionFormat.vtt ]}) async { videoId = VideoId.fromString(videoId); var tracks = {}; var videoInfoResponse = await VideoInfoResponse.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 get(ClosedCaptionTrackInfo trackInfo) async { var response = await ClosedCaptionTrackResponse.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 getSubTitles(ClosedCaptionTrackInfo trackInfo) => _httpClient.getString(trackInfo.url); }