Skip to content

Commit

Permalink
feat: add a subtitle menu
Browse files Browse the repository at this point in the history
  • Loading branch information
solsticedhiver committed Nov 21, 2023
1 parent 2b120dc commit e87f6f6
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 19 deletions.
1 change: 1 addition & 0 deletions devtools_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
extensions:
77 changes: 63 additions & 14 deletions lib/controls.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,13 @@ class VideoButtons extends StatefulWidget {
class _VideoButtonsState extends State<VideoButtons> {
late Version selectedVersion;
late Format selectedFormat;
late Subtitle? selectedSubtitle;
List<Version> versions = [];
List<Format> formats = [];
List<Subtitle> subtitles = [];
List<DropdownMenuItem<Version>> versionItems = [];
List<DropdownMenuItem<Format>> formatItems = [];
List<Format> formats = [];
List<DropdownMenuItem<Subtitle>> subtitleItems = [];
late VideoData video = widget.videos[widget.index];
late String _stream;

Expand All @@ -57,9 +60,10 @@ class _VideoButtonsState extends State<VideoButtons> {

debugPrint('programId: $programId');
try {
final (cv, tf) = await _getDetails(lang, programId);
final (cv, tf, ss) = await _getDetails(lang, programId);
debugPrint('Versions: $cv');
debugPrint('Formats: $tf');
debugPrint('Subtitles: $ss');
if (cv.isNotEmpty && mounted) {
setState(() {
versions = cv;
Expand All @@ -85,6 +89,24 @@ class _VideoButtonsState extends State<VideoButtons> {
.toList();
});
}
if (ss.isNotEmpty && mounted) {
ss.insert(
0,
Subtitle(
name: AppLocalizations.of(context)!.strNone,
url: null,
audioLanguage: 'None'));
setState(() {
subtitles = ss;
selectedSubtitle = subtitles.first;
subtitleItems = subtitles
.map((e) =>
DropdownMenuItem<Subtitle>(value: e, child: Text(e.name)))
.toList();
});
} else {
selectedSubtitle = null;
}
} catch (e) {
if (e is Map<String, dynamic>) {
final messengerState = ScaffoldMessenger.of(context);
Expand All @@ -98,7 +120,7 @@ class _VideoButtonsState extends State<VideoButtons> {
});
}

Future<(List<Version>, List<Format>)> _getDetails(
Future<(List<Version>, List<Format>, List<Subtitle>)> _getDetails(
String lang, String programId) async {
final cache = Provider.of<Cache>(context, listen: false);

Expand All @@ -107,11 +129,13 @@ class _VideoButtonsState extends State<VideoButtons> {
Map<String, dynamic>? jr;
List<Version> cv = [];
List<Format> tf = [];
List<Subtitle> ss = [];

jr = await cache.get(url);
if (jr['data'] == null ||
jr['data']['attributes'] == null ||
jr['data']['attributes']['streams'] == null) {
return (<Version>[], <Format>[]);
return (<Version>[], <Format>[], <Subtitle>[]);
}
//debugPrint(json.encode(jr).toString());
final streams = jr['data']['attributes']['streams'];
Expand All @@ -138,7 +162,11 @@ class _VideoButtonsState extends State<VideoButtons> {
int bb = int.parse(b.bandwidth);
return aa.compareTo(bb);
});
return (cv, tf);
for (var s in stream.subtitle.keys) {
ss.add(Subtitle(
name: s, url: stream.subtitle[s]!, audioLanguage: 'unknown'));
}
return (cv, tf, ss);
}

String _outputFilename() {
Expand Down Expand Up @@ -182,7 +210,7 @@ class _VideoButtonsState extends State<VideoButtons> {
// we download subtitle to modify it and then stream video, audio and subtitle separatly
final (videoStream, audioStream, subtitleUrl) =
await MediaStream.getMediaStream(
selectedFormat.url, selectedVersion.url, null);
selectedFormat.url, selectedVersion.url, selectedSubtitle?.url);
debugPrint('Playing $video');
debugPrint(videoStream.toString());
ProcessManager mgr = const LocalProcessManager();
Expand Down Expand Up @@ -393,7 +421,7 @@ class _VideoButtonsState extends State<VideoButtons> {

final (videoStream, audioStream, subtitleUrl) =
await MediaStream.getMediaStream(
selectedFormat.url, selectedVersion.url, null);
selectedFormat.url, selectedVersion.url, selectedSubtitle?.url);
debugPrint('Playing $video');

String subtitleData = '';
Expand Down Expand Up @@ -551,7 +579,7 @@ class _VideoButtonsState extends State<VideoButtons> {
return Container(
padding: const EdgeInsets.only(left: 10),
alignment: Alignment.centerLeft,
constraints: const BoxConstraints(minWidth: 100),
//constraints: const BoxConstraints(minWidth: 100),
child: Text(
//v.shortLabel,
v.label,
Expand Down Expand Up @@ -582,7 +610,7 @@ class _VideoButtonsState extends State<VideoButtons> {
return Container(
padding: const EdgeInsets.only(left: 10),
alignment: Alignment.centerLeft,
constraints: const BoxConstraints(minWidth: 100),
//constraints: const BoxConstraints(minWidth: 100),
child: Text(
'${f.resolution.split('x').last}p',
),
Expand All @@ -596,13 +624,34 @@ class _VideoButtonsState extends State<VideoButtons> {
});
})
: const SizedBox(height: 24),
const SizedBox(width: 10),
subtitleItems.isNotEmpty
? DropdownButton<Subtitle>(
underline: const SizedBox.shrink(),
hint: const Text('Subtitle'),
value: selectedSubtitle,
selectedItemBuilder: (BuildContext context) {
return subtitles.map<Widget>((s) {
return Container(
padding: const EdgeInsets.only(left: 10),
alignment: Alignment.centerLeft,
//constraints: const BoxConstraints(minWidth: 100),
child: Text(
s.name,
),
);
}).toList();
},
items: subtitleItems,
onChanged: (value) {
setState(() {
selectedSubtitle = value!;
});
})
: const SizedBox(height: 24),
];

if (widget.oneLine) {
return Row(children: [...top, ...bottom]);
} else {
return Column(children: [Row(children: top), Row(children: bottom)]);
}
return Column(children: [Row(children: top), Row(children: bottom)]);
}

void _showMessage(ScaffoldMessengerState messengerState, ThemeData themeData,
Expand Down
13 changes: 11 additions & 2 deletions lib/helpers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,15 @@ class Format {
}
}

class Subtitle {
String name;
Uri? url;
String audioLanguage;

Subtitle(
{required this.name, required this.url, required this.audioLanguage});
}

class LocaleModel with ChangeNotifier {
Locale? _locale;
Locale? get locale => _locale;
Expand Down Expand Up @@ -512,12 +521,12 @@ class MediaStream {
}
if (playlist.audios.isNotEmpty) {
for (var a in playlist.audios) {
audio[a.name!] = a.url!;
audio[a.name!.trim()] = a.url!;
}
}
if (playlist.subtitles.isNotEmpty) {
for (var s in playlist.subtitles) {
subtitle[s.name!] = s.url!;
subtitle[s.name!.trim()] = s.url!;
}
}
return MediaStream(
Expand Down
3 changes: 2 additions & 1 deletion lib/l10n/app_de.arb
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,6 @@
"strYouAreAboutToWatch": "Die Sendung, die Sie gerade ansehen, enthält Szenen, die nicht für junge oder sensible Zuschauer geeignet sind.",
"strCancel": "Abbrechen",
"strContinue": "Weiter",
"strWarning": "Warnung"
"strWarning": "Warnung",
"strNone": "Keine"
}
3 changes: 2 additions & 1 deletion lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,6 @@
"strYouAreAboutToWatch": "The program you are about to watch contains scenes not recommended for young or sensitive audiences.",
"strCancel": "Cancel",
"strContinue": "Continue",
"strWarning": "Warning"
"strWarning": "Warning",
"strNone": "None"
}
3 changes: 2 additions & 1 deletion lib/l10n/app_fr.arb
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,6 @@
"strYouAreAboutToWatch": "Le programme que vous vous apprétez à regarder comporte des scènes déconseillées à un public jeune ou sensible.",
"strCancel": "Annuler",
"strContinue": "Continuer",
"strWarning": "Avertissement"
"strWarning": "Avertissement",
"strNone": "Aucun"
}

0 comments on commit e87f6f6

Please sign in to comment.