parent
cb14e37f39
commit
4f01455f8f
|
@ -1,3 +1,5 @@
|
|||
## 1.7.1
|
||||
- `ClosedCaptionTrackInfo` and it's members are now json serializable.
|
||||
|
||||
## 1.7.0
|
||||
- BREAKING CHANGES: `ClosedCaptionManifest.getByLanguage` now returns a List.
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
import 'package:youtube_explode_dart/youtube_explode_dart.dart';
|
||||
import 'dart:convert';
|
||||
|
||||
Future<void> main() async {
|
||||
var yt = YoutubeExplode();
|
||||
|
||||
var manifest = await yt.videos.closedCaptions
|
||||
.getManifest('Pxgvgh9IFqA', autoGenerated: true);
|
||||
print(manifest.tracks);
|
||||
print('\n\n---------------------\n\n');
|
||||
|
||||
manifest = await yt.videos.closedCaptions
|
||||
.getManifest('Pxgvgh9IFqA', autoGenerated: false);
|
||||
print(manifest.tracks);
|
||||
yt.close();
|
||||
.getManifest('ppJy5uGZLi4', autoGenerated: true);
|
||||
var trackInfo = manifest.getByLanguage('en');
|
||||
var track = await yt.videos.closedCaptions.get(trackInfo.first);
|
||||
print(json.encode(track.toJson()));
|
||||
}
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
import 'dart:collection';
|
||||
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import 'closed_caption_part.dart';
|
||||
|
||||
part 'closed_caption.g.dart';
|
||||
|
||||
/// Text that gets displayed at specific time during video playback,
|
||||
/// as part of a [ClosedCaptionTrack]
|
||||
@JsonSerializable()
|
||||
class ClosedCaption {
|
||||
/// Text displayed by this caption.
|
||||
final String text;
|
||||
|
@ -35,4 +40,11 @@ class ClosedCaption {
|
|||
|
||||
@override
|
||||
String toString() => 'Text: $text';
|
||||
|
||||
///
|
||||
factory ClosedCaption.fromJson(Map<String, dynamic> json) =>
|
||||
_$ClosedCaptionFromJson(json);
|
||||
|
||||
///
|
||||
Map<String, dynamic> toJson() => _$ClosedCaptionToJson(this);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'closed_caption.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
ClosedCaption _$ClosedCaptionFromJson(Map<String, dynamic> json) {
|
||||
return ClosedCaption(
|
||||
json['text'] as String,
|
||||
json['offset'] == null
|
||||
? null
|
||||
: Duration(microseconds: json['offset'] as int),
|
||||
json['duration'] == null
|
||||
? null
|
||||
: Duration(microseconds: json['duration'] as int),
|
||||
(json['parts'] as List)?.map((e) => e == null
|
||||
? null
|
||||
: ClosedCaptionPart.fromJson(e as Map<String, dynamic>)),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$ClosedCaptionToJson(ClosedCaption instance) =>
|
||||
<String, dynamic>{
|
||||
'text': instance.text,
|
||||
'offset': instance.offset?.inMicroseconds,
|
||||
'duration': instance.duration?.inMicroseconds,
|
||||
'parts': instance.parts,
|
||||
};
|
|
@ -1,19 +1,24 @@
|
|||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'closed_caption_format.g.dart';
|
||||
|
||||
/// SubTiles format.
|
||||
@JsonSerializable()
|
||||
class ClosedCaptionFormat {
|
||||
/// .srv format(1).
|
||||
static const ClosedCaptionFormat srv1 = ClosedCaptionFormat._('srv1');
|
||||
static const ClosedCaptionFormat srv1 = ClosedCaptionFormat('srv1');
|
||||
|
||||
/// .srv format(2).
|
||||
static const ClosedCaptionFormat srv2 = ClosedCaptionFormat._('srv2');
|
||||
static const ClosedCaptionFormat srv2 = ClosedCaptionFormat('srv2');
|
||||
|
||||
/// .srv format(3).
|
||||
static const ClosedCaptionFormat srv3 = ClosedCaptionFormat._('srv3');
|
||||
static const ClosedCaptionFormat srv3 = ClosedCaptionFormat('srv3');
|
||||
|
||||
/// .ttml format.
|
||||
static const ClosedCaptionFormat ttml = ClosedCaptionFormat._('ttml');
|
||||
static const ClosedCaptionFormat ttml = ClosedCaptionFormat('ttml');
|
||||
|
||||
/// .vtt format.
|
||||
static const ClosedCaptionFormat vtt = ClosedCaptionFormat._('vtt');
|
||||
static const ClosedCaptionFormat vtt = ClosedCaptionFormat('vtt');
|
||||
|
||||
/// List of all sub titles format.
|
||||
static const List<ClosedCaptionFormat> values = [srv1, srv2, srv3, ttml, vtt];
|
||||
|
@ -21,5 +26,13 @@ class ClosedCaptionFormat {
|
|||
/// Format code as string.
|
||||
final String formatCode;
|
||||
|
||||
const ClosedCaptionFormat._(this.formatCode);
|
||||
///
|
||||
const ClosedCaptionFormat(this.formatCode);
|
||||
|
||||
///
|
||||
factory ClosedCaptionFormat.fromJson(Map<String, dynamic> json) =>
|
||||
_$ClosedCaptionFormatFromJson(json);
|
||||
|
||||
///
|
||||
Map<String, dynamic> toJson() => _$ClosedCaptionFormatToJson(this);
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'closed_caption_format.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
ClosedCaptionFormat _$ClosedCaptionFormatFromJson(Map<String, dynamic> json) {
|
||||
return ClosedCaptionFormat(
|
||||
json['formatCode'] as String,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$ClosedCaptionFormatToJson(
|
||||
ClosedCaptionFormat instance) =>
|
||||
<String, dynamic>{
|
||||
'formatCode': instance.formatCode,
|
||||
};
|
|
@ -1,4 +1,9 @@
|
|||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'closed_caption_part.g.dart';
|
||||
|
||||
/// Part of a closed caption (usually a single word).
|
||||
@JsonSerializable()
|
||||
class ClosedCaptionPart {
|
||||
/// Text displayed by this caption part.
|
||||
final String text;
|
||||
|
@ -12,4 +17,11 @@ class ClosedCaptionPart {
|
|||
|
||||
@override
|
||||
String toString() => text;
|
||||
|
||||
///
|
||||
factory ClosedCaptionPart.fromJson(Map<String, dynamic> json) =>
|
||||
_$ClosedCaptionPartFromJson(json);
|
||||
|
||||
///
|
||||
Map<String, dynamic> toJson() => _$ClosedCaptionPartToJson(this);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'closed_caption_part.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
ClosedCaptionPart _$ClosedCaptionPartFromJson(Map<String, dynamic> json) {
|
||||
return ClosedCaptionPart(
|
||||
json['text'] as String,
|
||||
json['offset'] == null
|
||||
? null
|
||||
: Duration(microseconds: json['offset'] as int),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$ClosedCaptionPartToJson(ClosedCaptionPart instance) =>
|
||||
<String, dynamic>{
|
||||
'text': instance.text,
|
||||
'offset': instance.offset?.inMicroseconds,
|
||||
};
|
|
@ -1,8 +1,13 @@
|
|||
import 'dart:collection';
|
||||
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import 'closed_caption.dart';
|
||||
|
||||
part 'closed_caption_track.g.dart';
|
||||
|
||||
/// Track that contains closed captions in a specific language.
|
||||
@JsonSerializable()
|
||||
class ClosedCaptionTrack {
|
||||
/// Closed captions.
|
||||
final UnmodifiableListView<ClosedCaption> captions;
|
||||
|
@ -15,4 +20,11 @@ class ClosedCaptionTrack {
|
|||
/// Returns null if not found.
|
||||
ClosedCaption getByTime(Duration time) => captions
|
||||
.firstWhere((e) => time >= e.offset && time <= e.end, orElse: () => null);
|
||||
|
||||
///
|
||||
factory ClosedCaptionTrack.fromJson(Map<String, dynamic> json) =>
|
||||
_$ClosedCaptionTrackFromJson(json);
|
||||
|
||||
///
|
||||
Map<String, dynamic> toJson() => _$ClosedCaptionTrackToJson(this);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'closed_caption_track.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
ClosedCaptionTrack _$ClosedCaptionTrackFromJson(Map<String, dynamic> json) {
|
||||
return ClosedCaptionTrack(
|
||||
(json['captions'] as List)?.map((e) =>
|
||||
e == null ? null : ClosedCaption.fromJson(e as Map<String, dynamic>)),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$ClosedCaptionTrackToJson(ClosedCaptionTrack instance) =>
|
||||
<String, dynamic>{
|
||||
'captions': instance.captions,
|
||||
};
|
|
@ -1,10 +1,14 @@
|
|||
import 'package:equatable/equatable.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import '../../extensions/helpers_extension.dart';
|
||||
import 'closed_caption_format.dart';
|
||||
import 'language.dart';
|
||||
|
||||
part 'closed_caption_track_info.g.dart';
|
||||
|
||||
/// Metadata associated with a certain [ClosedCaptionTrack]
|
||||
@JsonSerializable()
|
||||
class ClosedCaptionTrackInfo extends Equatable {
|
||||
/// Manifest URL of the associated track.
|
||||
final Uri url;
|
||||
|
@ -25,13 +29,12 @@ class ClosedCaptionTrackInfo extends Equatable {
|
|||
|
||||
/// Returns this auto-translated to another language.
|
||||
/// Keeping the same format.
|
||||
ClosedCaptionTrackInfo autoTranslate(
|
||||
ClosedCaptionTrackInfo trackInfo, String lang) {
|
||||
ClosedCaptionTrackInfo autoTranslate(String lang) {
|
||||
return ClosedCaptionTrackInfo(
|
||||
trackInfo.url.replaceQueryParameters({'tlang': lang}),
|
||||
url.replaceQueryParameters({'tlang': lang}),
|
||||
Language(lang, ''),
|
||||
isAutoGenerated: trackInfo.isAutoGenerated,
|
||||
format: trackInfo.format);
|
||||
isAutoGenerated: isAutoGenerated,
|
||||
format: format);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -39,4 +42,12 @@ class ClosedCaptionTrackInfo extends Equatable {
|
|||
|
||||
@override
|
||||
List<Object> get props => [url, language, isAutoGenerated];
|
||||
|
||||
|
||||
///
|
||||
factory ClosedCaptionTrackInfo.fromJson(Map<String, dynamic> json) =>
|
||||
_$ClosedCaptionTrackInfoFromJson(json);
|
||||
|
||||
///
|
||||
Map<String, dynamic> toJson() => _$ClosedCaptionTrackInfoToJson(this);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'closed_caption_track_info.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
ClosedCaptionTrackInfo _$ClosedCaptionTrackInfoFromJson(
|
||||
Map<String, dynamic> json) {
|
||||
return ClosedCaptionTrackInfo(
|
||||
json['url'] == null ? null : Uri.parse(json['url'] as String),
|
||||
json['language'] == null
|
||||
? null
|
||||
: Language.fromJson(json['language'] as Map<String, dynamic>),
|
||||
isAutoGenerated: json['isAutoGenerated'] as bool,
|
||||
format: json['format'] == null
|
||||
? null
|
||||
: ClosedCaptionFormat.fromJson(json['format'] as Map<String, dynamic>),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$ClosedCaptionTrackInfoToJson(
|
||||
ClosedCaptionTrackInfo instance) =>
|
||||
<String, dynamic>{
|
||||
'url': instance.url?.toString(),
|
||||
'language': instance.language,
|
||||
'isAutoGenerated': instance.isAutoGenerated,
|
||||
'format': instance.format,
|
||||
};
|
|
@ -1,6 +1,10 @@
|
|||
import 'package:equatable/equatable.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'language.g.dart';
|
||||
|
||||
/// Language information.
|
||||
@JsonSerializable()
|
||||
class Language extends Equatable {
|
||||
/// ISO 639-1 code of this language.
|
||||
final String code;
|
||||
|
@ -16,4 +20,11 @@ class Language extends Equatable {
|
|||
|
||||
@override
|
||||
String toString() => 'Language: $name';
|
||||
|
||||
///
|
||||
factory Language.fromJson(Map<String, dynamic> json) =>
|
||||
_$LanguageFromJson(json);
|
||||
|
||||
///
|
||||
Map<String, dynamic> toJson() => _$LanguageToJson(this);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'language.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
Language _$LanguageFromJson(Map<String, dynamic> json) {
|
||||
return Language(
|
||||
json['code'] as String,
|
||||
json['name'] as String,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$LanguageToJson(Language instance) => <String, dynamic>{
|
||||
'code': instance.code,
|
||||
'name': instance.name,
|
||||
};
|
|
@ -1,6 +1,6 @@
|
|||
name: youtube_explode_dart
|
||||
description: A port in dart of the youtube explode library. Supports several API functions without the need of Youtube API Key.
|
||||
version: 1.7.0
|
||||
version: 1.7.1
|
||||
homepage: https://github.com/Hexer10/youtube_explode_dart
|
||||
|
||||
environment:
|
||||
|
@ -13,6 +13,7 @@ dependencies:
|
|||
xml: '>=3.0.0 <5.0.0'
|
||||
equatable: ^1.1.0
|
||||
meta: ^1.1.8
|
||||
json_annotation: ^3.1.0
|
||||
|
||||
dev_dependencies:
|
||||
effective_dart: ^1.2.4
|
||||
|
@ -20,3 +21,5 @@ dev_dependencies:
|
|||
test: ^1.12.0
|
||||
grinder: ^0.8.5
|
||||
pedantic: ^1.9.2
|
||||
json_serializable: ^3.5.0
|
||||
build_runner: ^1.10.4
|
||||
|
|
Loading…
Reference in New Issue