Skip to content

Commit e212065

Browse files
committed
fix subs
1 parent 5d5a12b commit e212065

3 files changed

Lines changed: 42 additions & 30 deletions

File tree

lib/models/captions.dart

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,31 @@ abstract class LocalClosedCaptionFile {
2424
}
2525
return null;
2626
}
27+
28+
String toSRT() {
29+
final buffer = StringBuffer();
30+
for (int i = 0; i < captions.length; i++) {
31+
final caption = captions[i];
32+
buffer.writeln(i + 1);
33+
buffer.writeln(
34+
'${_formatSRTTimestamp(caption.start)} --> ${_formatSRTTimestamp(caption.end)}',
35+
);
36+
buffer.writeln(caption.text);
37+
buffer.writeln(); // blank line between entries
38+
}
39+
return buffer.toString();
40+
}
41+
42+
static String _formatSRTTimestamp(Duration duration) {
43+
final hours = duration.inHours.toString().padLeft(2, '0');
44+
final minutes = (duration.inMinutes % 60).toString().padLeft(2, '0');
45+
final seconds = (duration.inSeconds % 60).toString().padLeft(2, '0');
46+
final milliseconds = (duration.inMilliseconds % 1000).toString().padLeft(
47+
3,
48+
'0',
49+
);
50+
return '$hours:$minutes:$seconds,$milliseconds';
51+
}
2752
}
2853

2954
class WebVTTCaptionFile extends LocalClosedCaptionFile {

lib/models/player.dart

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class PlayerModel extends ChangeNotifier {
2525
final PlaylistModel playlist;
2626

2727
bool showControls = false;
28+
bool hasSubtitleTrack = false;
2829
Timer? controlsTimer;
2930

3031
bool _showMessageIcon = false;
@@ -179,8 +180,15 @@ class PlayerModel extends ChangeNotifier {
179180
}();
180181

181182
initPlayerFuture?.whenComplete(() {
183+
hasSubtitleTrack = false;
182184
_loadCaptions(item)?.then((subs) {
183-
_currentCaptions = subs;
185+
var srt = subs.toSRT();
186+
hasSubtitleTrack = srt.isNotEmpty;
187+
player.setSubtitleTrack(
188+
SubtitleTrack.data(
189+
srt,
190+
),
191+
);
184192
notifyListeners();
185193
});
186194
app.send(
@@ -194,10 +202,7 @@ class PlayerModel extends ChangeNotifier {
194202
notifyListeners();
195203
}
196204

197-
LocalClosedCaptionFile? _currentCaptions;
198-
199205
String fullscreenTooltipText = 'Double-tap or long-tap to toggle fullscreen';
200-
LocalClosedCaptionFile? get currentCaptions => _currentCaptions;
201206

202207
Future<double> getVideoDuration(String url) async {
203208
// mediakit will parse segment durations for a minute while loading them,
@@ -454,8 +459,7 @@ class PlayerModel extends ChangeNotifier {
454459

455460
Future<LocalClosedCaptionFile>? _loadCaptions(VideoList item) {
456461
if (item.url.contains('youtu')) {
457-
item.subs = item.url;
458-
return compute(_loadYoutubeCaptionsFuture, item);
462+
return compute(_loadYoutubeCaptionsFuture, item.url);
459463
}
460464
var subsUrl = item.subs ?? '';
461465
if (subsUrl.isEmpty) return null;
@@ -470,10 +474,9 @@ class PlayerModel extends ChangeNotifier {
470474
}
471475

472476
static Future<LocalClosedCaptionFile> _loadYoutubeCaptionsFuture(
473-
VideoList item,
477+
String url,
474478
) async {
475-
final subs = await getYoutubeSubtitles(item.url);
476-
if (subs.captions.isEmpty) item.subs = '';
479+
final subs = await getYoutubeSubtitles(url);
477480
return subs;
478481
}
479482

@@ -609,6 +612,7 @@ class PlayerModel extends ChangeNotifier {
609612
}
610613

611614
bool hasCaptions() {
615+
if (hasSubtitleTrack) return true;
612616
final item = playlist.getItem(playlist.pos);
613617
final subs = item?.subs;
614618
return subs != null && subs.isNotEmpty;

lib/video_player.dart

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,6 @@ class VideoPlayerScreen extends StatelessWidget {
6666
final playerWidth = playerState.width?.toDouble() ?? (1280 / 2);
6767
final playerHeight = playerState.height?.toDouble() ?? (1280 / 2);
6868

69-
final captionText = player.currentCaptions
70-
?.getCaptionFor(playerState.position)
71-
?.text;
7269
return MultiTapListener(
7370
onDoubleTap: () => goLandscapeOrFullscreen(player.app),
7471
child: GestureDetector(
@@ -89,27 +86,13 @@ class VideoPlayerScreen extends StatelessWidget {
8986
height: playerHeight,
9087
pauseUponEnteringBackgroundMode:
9188
!player.app.hasBackgroundAudio,
89+
subtitleViewConfiguration: SubtitleViewConfiguration(
90+
textScaler: .linear(0.55),
91+
visible: player.app.showSubtitles,
92+
),
9293
),
9394
],
9495
),
95-
if (player.app.showSubtitles &&
96-
captionText != null &&
97-
captionText.isNotEmpty)
98-
Align(
99-
alignment: Alignment.bottomCenter,
100-
child: Padding(
101-
padding: const EdgeInsets.only(bottom: 50),
102-
child: Text(
103-
captionText,
104-
style: const TextStyle(
105-
fontSize: 16,
106-
color: Colors.white,
107-
backgroundColor: Colors.black54,
108-
),
109-
textAlign: TextAlign.center,
110-
),
111-
),
112-
),
11396
_PlayPauseOverlay(player: player),
11497
_ChatToggleButton(player: player),
11598
],

0 commit comments

Comments
 (0)