diff --git a/CHANGELOG.md b/CHANGELOG.md index dfe948fce..cfc91f4cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file. - Cataloguing: identify Apple variant of HDR images - Collection: allow using hash (md5/sha1/sha256) when bulk renaming - Info: color palette +- Video: external subtitle support (SRT) - option to force using western arabic numerals for dates ### Changed diff --git a/plugins/aves_video_mpv/lib/src/controller.dart b/plugins/aves_video_mpv/lib/src/controller.dart index 8958e86db..bd47ffeb9 100644 --- a/plugins/aves_video_mpv/lib/src/controller.dart +++ b/plugins/aves_video_mpv/lib/src/controller.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:io'; import 'package:aves_model/aves_model.dart'; import 'package:aves_utils/aves_utils.dart'; @@ -9,6 +10,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:media_kit/media_kit.dart'; import 'package:media_kit_video/media_kit_video.dart'; +import 'package:path/path.dart' as p; class MpvVideoController extends AvesVideoController { late Player _instance; @@ -19,6 +21,9 @@ class MpvVideoController extends AvesVideoController { final StreamController _statusStreamController = StreamController.broadcast(); final StreamController _timedTextStreamController = StreamController.broadcast(); final AChangeNotifier _completedNotifier = AChangeNotifier(); + final List _externalSubtitleTracks = []; + + static final _pContext = p.Context(); @override double get minSpeed => .25; @@ -118,6 +123,22 @@ class MpvVideoController extends AvesVideoController { final settingsStream = settings.updateStream; _subscriptions.add(settingsStream.where((event) => event.key == SettingKeys.enableVideoHardwareAccelerationKey).listen((_) => _initController())); _subscriptions.add(settingsStream.where((event) => event.key == SettingKeys.videoLoopModeKey).listen((_) => _applyLoop())); + + final path = entry.path; + if (path != null) { + final videoBasename = _pContext.basenameWithoutExtension(path); + // list subtitle files in the same directory + _subscriptions.add(File(path).parent.list().where((v) => v is File && _isSubtitle(v.path)).listen((v) { + final subtitleBasename = _pContext.basename(v.path); + if (subtitleBasename.startsWith(videoBasename)) { + _externalSubtitleTracks.add(SubtitleTrack.uri( + v.uri.toString(), + title: 'File ${subtitleBasename.substring(videoBasename.length)}', + )); + _externalSubtitleTracks.sort((a, b) => a.title!.compareTo(b.title!)); + } + })); + } } void _stopListening() { @@ -280,7 +301,13 @@ class MpvVideoController extends AvesVideoController { List get _audioTracks => _tracks.audio.skip(fakeTrackCount).toList(); - List get _subtitleTracks => _tracks.subtitle.skip(fakeTrackCount).toList(); + List get _subtitleTracks { + final externalTitles = _externalSubtitleTracks.map((v) => v.title).toSet(); + return [ + ..._tracks.subtitle.skip(fakeTrackCount).where((v) => !externalTitles.contains(v.title)), + ..._externalSubtitleTracks, + ]; + } @override List get streams { @@ -375,4 +402,13 @@ class MpvVideoController extends AvesVideoController { } } } + + static bool _isSubtitle(String path) { + switch (_pContext.extension(path)) { + case '.srt': + return true; + default: + return false; + } + } } diff --git a/plugins/aves_video_mpv/lib/src/tracks.dart b/plugins/aves_video_mpv/lib/src/tracks.dart index e4c499ddc..7deba54d4 100644 --- a/plugins/aves_video_mpv/lib/src/tracks.dart +++ b/plugins/aves_video_mpv/lib/src/tracks.dart @@ -36,7 +36,7 @@ extension ExtraSubtitleTrack on SubtitleTrack { index: index, codecName: null, language: language, - title: title, + title: title ?? '$index ($codec)', width: null, height: null, ); diff --git a/plugins/aves_video_mpv/pubspec.lock b/plugins/aves_video_mpv/pubspec.lock index 5e6153949..51f705fee 100644 --- a/plugins/aves_video_mpv/pubspec.lock +++ b/plugins/aves_video_mpv/pubspec.lock @@ -241,7 +241,7 @@ packages: source: hosted version: "3.0.0" path: - dependency: transitive + dependency: "direct main" description: name: path sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" diff --git a/plugins/aves_video_mpv/pubspec.yaml b/plugins/aves_video_mpv/pubspec.yaml index 2ce9bd951..8321e92ab 100644 --- a/plugins/aves_video_mpv/pubspec.yaml +++ b/plugins/aves_video_mpv/pubspec.yaml @@ -19,6 +19,7 @@ dependencies: media_kit_libs_android_video: media_kit_native_event_loop: media_kit_video: + path: dev_dependencies: flutter_lints: