Implement ClosedCaption unit tests and fix closed captions api.

This commit is contained in:
Hexah 2020-06-07 15:11:07 +02:00
parent 0d0b8f2185
commit 66ff1c3e02
6 changed files with 59 additions and 8 deletions

View File

@ -9,7 +9,7 @@ class ClosedCaptionTrackResponse {
ClosedCaptionTrackResponse(this._root);
Iterable<ClosedCaption> get closedCaptions =>
_root.findElements('p').map((e) => ClosedCaption._(e));
_root.findAllElements('p').map((e) => ClosedCaption._(e));
ClosedCaptionTrackResponse.parse(String raw) : _root = xml.parse(raw);
@ -37,7 +37,7 @@ class ClosedCaption {
ClosedCaption._(this._root);
String get text => _root.toXmlString();
String get text => _root.text;
Duration get offset =>
Duration(milliseconds: int.parse(_root.getAttribute('t') ?? 0));
@ -48,7 +48,7 @@ class ClosedCaption {
Duration get end => offset + duration;
Iterable<ClosedCaptionPart> getParts() =>
_root.findElements('s').map((e) => ClosedCaptionPart._(e));
_root.findAllElements('s').map((e) => ClosedCaptionPart._(e));
}
class ClosedCaptionPart {
@ -56,8 +56,8 @@ class ClosedCaptionPart {
ClosedCaptionPart._(this._root);
String get text => _root.toXmlString();
String get text => _root.text;
Duration get offset =>
Duration(milliseconds: int.parse(_root.getAttribute('t') ?? 0));
Duration(milliseconds: int.parse(_root.getAttribute('t') ?? '0'));
}

View File

@ -85,7 +85,8 @@ class PlayerResponse {
.get('captions')
?.get('playerCaptionsTracklistRenderer')
?.getValue('captionTracks')
?.map((e) => ClosedCaptionTrack(e)) ??
?.map((e) => ClosedCaptionTrack(e))
?.cast<ClosedCaptionTrack>() ??
const [];
String getVideoPlayabilityError() =>

View File

@ -14,6 +14,9 @@ class ClosedCaption {
/// Duration this caption is displayed.
final Duration duration;
/// Time at which this caption ends being displayed.
Duration get end => offset + duration;
/// Caption parts (usually individual words).
/// May be empty because not all captions contain parts.
final UnmodifiableListView<ClosedCaptionPart> parts;

View File

@ -28,7 +28,8 @@ class ClosedCaptionClient {
var tracks = playerResponse.closedCaptionTrack.map((track) =>
ClosedCaptionTrackInfo(Uri.parse(track.url),
Language(track.languageCode, track.languageName)));
Language(track.languageCode, track.languageName),
isAutoGenerated: track.autoGenerated));
return ClosedCaptionManifest(tracks);
}

View File

@ -10,4 +10,9 @@ class ClosedCaptionTrack {
/// Initializes an instance of [ClosedCaptionTrack].
ClosedCaptionTrack(Iterable<ClosedCaption> captions)
: captions = UnmodifiableListView(captions);
/// Gets the caption displayed at the specified point in time.
/// Returns null if not found.
ClosedCaption getByTime(Duration time) => captions
.firstWhere((e) => time >= e.offset && time <= e.end, orElse: () => null);
}

View File

@ -1 +1,42 @@
//TODO: Implement this
import 'package:test/test.dart';
import 'package:youtube_explode_dart/youtube_explode_dart.dart';
void main() {
group('Search', () {
YoutubeExplode yt;
setUp(() {
yt = YoutubeExplode();
});
tearDown(() {
yt.close();
});
test('GetClosedCaptionTracksOfAnyVideo', () async {
var manifest = await yt.videos.closedCaptions.getManifest('_QdPW8JrYzQ');
expect(manifest.tracks, isNotEmpty);
});
test('GetClosedCaptionTrackOfAnyVideoSpecific', () async {
var manifest = await yt.videos.closedCaptions.getManifest('_QdPW8JrYzQ');
var trackInfo = manifest.tracks.first;
var track = await yt.videos.closedCaptions.get(trackInfo);
expect(track, isNotEmpty);
});
test('GetClosedCaptionTrackAtSpecificTime', () async {
var manifest = await yt.videos.closedCaptions
.getManifest('https://www.youtube.com/watch?v=YltHGKX80Y8');
var trackInfo = manifest.getByLanguage('en');
var track = await yt.videos.closedCaptions.get(trackInfo);
var caption =
track.getByTime(const Duration(hours: 0, minutes: 10, seconds: 41));
var captionPart =
caption.getPartByTime(const Duration(milliseconds: 650));
expect(caption, isNotNull);
expect(captionPart, isNotNull);
expect(caption.text, 'know I worked really hard on not doing');
expect(captionPart.text, ' hard');
});
});
}