Can't alternate between external/internal subtitles
I am currently setting subtitles this way:
var subList = subtitleTracks.asMap().entries.map((entry) {
int index = entry.key;
var track = entry.value;
var title = track.metadata['title'] ??
track.metadata['language'] ??
'Unknown';
return ListTile(
title: Text(title),
onTap: () {
player.activeSubtitleTracks = [index];
closeDialog();
},
);
}).toList();
for (var exSub in widget.item.subtitles) {
subList.add(ListTile(
title: Text(exSub.language),
onTap: () {
player.setMedia(
"${widget.item.originURL}${exSub.link}", MediaType.subtitle);
closeDialog();
},
));
}
This is building a list of subtitles, that are clickable. I can individually either set an internal OR external subtitles on a video. BUT if I set an external subtitle, I have to call player.setMedia, and after that, subsequent attempts at setting internal subtitle will fail. I attempted to fix the issue by recalling setMedia() for internal subtitle like this (with the video stream URL):
onTap: () {
print('Selected subtitle track: $index');
player.setMedia("${widget.item.originURL}${widget.item.stream}",
MediaType.subtitle);
player.activeSubtitleTracks = [index];
closeDialog();
},
It works, if I select an external and then an internal one, it will select it. But when i do this, if I select an internal subtitle (which is going to call SetMedia with the video) THEN an external subtitle, the player just freezes, so I am assuming I'm not supposed to do that
Thanks for your help
can you provide a complete minimal code so I can test?
Experiencing the same.
// load file and then on tap:
player.setMedia(
"<url-to-same-file-that-was-loaded-before>", MediaType.subtitle);
Just this causes memory usage to go crazy, stutters and eventually crashed my laptop in 30 seconds.
@23doors what's your OS?
With the latest fvp, you can use VideoPlayerController to use subtitle apis. I tested modified version of this example with the following patch and it works as expected
diff --git a/flutter/simple/lib/main.dart b/flutter/simple/lib/main.dart
index e79afde..c04ed5a 100644
--- a/flutter/simple/lib/main.dart
+++ b/flutter/simple/lib/main.dart
@@ -192,6 +192,9 @@ class _VideoAppState extends State<VideoApp> {
final result = await FilePicker.platform.pickFiles(
type: FileType.any,
);
+ if (result?.files.isNotEmpty ?? false) {
+ _controller.setExternalSubtitle(result!.files.first.path!);
+ }
if (result?.files.isNotEmpty ?? false) {
playFile(result!.files.first.path!);
}
@@ -202,12 +205,16 @@ class _VideoAppState extends State<VideoApp> {
FloatingActionButton(
heroTag: 'uri',
tooltip: 'Open [Uri]',
- onPressed: () {
- showURIPicker(context).then((value) {
- if (value != null) {
- playUri(value);
- }
- });
+ onPressed: () async {
+ final result = await FilePicker.platform.pickFiles(
+ type: FileType.any,
+ );
+ if (result?.files.isNotEmpty ?? false) {
+ _controller.setExternalSubtitle(result!.files.first.path!);
+ }
+ if (result?.files.isNotEmpty ?? false) {
+ _controller.setExternalSubtitle(result!.files.first.path!);
+ }
},
child: const Icon(Icons.link),
),
@@ -242,15 +249,15 @@ class _VideoAppState extends State<VideoApp> {
class _ControlsOverlay extends StatelessWidget {
const _ControlsOverlay({required this.controller});
- static const List<double> _examplePlaybackRates = <double>[
- 0.25,
- 0.5,
- 1.0,
- 1.5,
- 2.0,
- 3.0,
- 5.0,
- 10.0,
+ static const List<int> _InternalSubtileTracks = <int>[
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
];
final VideoPlayerController controller;
@@ -283,18 +290,19 @@ class _ControlsOverlay extends StatelessWidget {
),
Align(
alignment: Alignment.topRight,
- child: PopupMenuButton<double>(
- initialValue: controller.value.playbackSpeed,
- tooltip: 'Playback speed',
- onSelected: (double speed) {
- controller.setPlaybackSpeed(speed);
+ child: PopupMenuButton<int>(
+ initialValue: 0,
+ tooltip: 'Embedded subtitle track index',
+ onSelected: (int track) {
+ controller.setExternalSubtitle(""); // disable external subtitle
+ controller.setSubtitleTracks([track]);
},
itemBuilder: (BuildContext context) {
- return <PopupMenuItem<double>>[
- for (final double speed in _examplePlaybackRates)
- PopupMenuItem<double>(
- value: speed,
- child: Text('${speed}x'),
+ return <PopupMenuItem<int>>[
+ for (final int track in _InternalSubtileTracks)
+ PopupMenuItem<int>(
+ value: track,
+ child: Text('${track}x'),
)
];
},
MacOS Sequoia 15.1.1 Just tested with fresh fvp example, only thing I changed was: in initstate used localfile:
_controller = VideoPlayerController.file(
File(
'<path to local file>'),
closedCaptionFile: _loadCaptions(),
videoPlayerOptions: VideoPlayerOptions(mixWithOthers: true),
);
and in build added:
TextButton(
onPressed: () {
_controller.setExternalSubtitle(
"file://<path to same file>");
},
child: Text("switch")),
When I click the button, memory goes crazy pretty much immediately and ends up crashing.
I just tried what you suggested instead - _controller.setExternalSubtitle("") to switch back to embedded subs - and this works fine, no issues!
When I click the button, memory goes crazy pretty much immediately and ends up crashing
show me the log. iirc i had a similar result because some fonts are missing on macos15
How are fonts related here?
I play the file - works fine with embedded subs. I use _controller.setExternalSubtitle() with exactly same file - crashes.
And there is nothing in the logs.
# file was playing, I paused it here to keep logs clean
0x1358b1e00>1857 00:00:01.7/00:15:59 cache 0v 31.2s/47905KB 82374KB/s |-65|>4ms update infms 24.0fps draw 0/0 +41ms
# button pressed:
[AVCoderBase.subrip] EOF
0x1358b1e00>1833 00:00:01.8/00:15:59 cache 0v 2.1s/21993KB 825KB/s |+1833|>4ms update 2053.0ms 23.4fps draw 0/0 +42ms
And that's it. Nothing happens but memory pressure starts rising quickly.
@23doors can you share your subtitle file so i can test?
It's a movie with embedded srt track inside a mkv container. So I play this movie and called setExternalSubtitle with path to this specific movie as well. But if you want, I can extract the subs. Not sure if it will behave the same though. I can also test with a different movie file if you want and see if this happens. Just need to find some free to download mkv with subs.
It's a movie with embedded srt track inside a mkv container. So I play this movie and called setExternalSubtitle with path to this specific movie as well. But if you want, I can extract the subs. Not sure if it will behave the same though. I can also test with a different movie file if you want and see if this happens. Just need to find some free to download mkv with subs.
@23doors i can't reproduce the issue with my videos. you can extract srt and let me try