#874 external subtitle support

This commit is contained in:
Thibault Deckers 2024-04-29 23:20:56 +02:00
parent 8ee213b787
commit 25598163a5
5 changed files with 41 additions and 3 deletions

View file

@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file.
- Cataloguing: identify Apple variant of HDR images - Cataloguing: identify Apple variant of HDR images
- Collection: allow using hash (md5/sha1/sha256) when bulk renaming - Collection: allow using hash (md5/sha1/sha256) when bulk renaming
- Info: color palette - Info: color palette
- Video: external subtitle support (SRT)
- option to force using western arabic numerals for dates - option to force using western arabic numerals for dates
### Changed ### Changed

View file

@ -1,4 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'dart:io';
import 'package:aves_model/aves_model.dart'; import 'package:aves_model/aves_model.dart';
import 'package:aves_utils/aves_utils.dart'; import 'package:aves_utils/aves_utils.dart';
@ -9,6 +10,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:media_kit/media_kit.dart'; import 'package:media_kit/media_kit.dart';
import 'package:media_kit_video/media_kit_video.dart'; import 'package:media_kit_video/media_kit_video.dart';
import 'package:path/path.dart' as p;
class MpvVideoController extends AvesVideoController { class MpvVideoController extends AvesVideoController {
late Player _instance; late Player _instance;
@ -19,6 +21,9 @@ class MpvVideoController extends AvesVideoController {
final StreamController<VideoStatus> _statusStreamController = StreamController.broadcast(); final StreamController<VideoStatus> _statusStreamController = StreamController.broadcast();
final StreamController<String?> _timedTextStreamController = StreamController.broadcast(); final StreamController<String?> _timedTextStreamController = StreamController.broadcast();
final AChangeNotifier _completedNotifier = AChangeNotifier(); final AChangeNotifier _completedNotifier = AChangeNotifier();
final List<SubtitleTrack> _externalSubtitleTracks = [];
static final _pContext = p.Context();
@override @override
double get minSpeed => .25; double get minSpeed => .25;
@ -118,6 +123,22 @@ class MpvVideoController extends AvesVideoController {
final settingsStream = settings.updateStream; final settingsStream = settings.updateStream;
_subscriptions.add(settingsStream.where((event) => event.key == SettingKeys.enableVideoHardwareAccelerationKey).listen((_) => _initController())); _subscriptions.add(settingsStream.where((event) => event.key == SettingKeys.enableVideoHardwareAccelerationKey).listen((_) => _initController()));
_subscriptions.add(settingsStream.where((event) => event.key == SettingKeys.videoLoopModeKey).listen((_) => _applyLoop())); _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() { void _stopListening() {
@ -280,7 +301,13 @@ class MpvVideoController extends AvesVideoController {
List<AudioTrack> get _audioTracks => _tracks.audio.skip(fakeTrackCount).toList(); List<AudioTrack> get _audioTracks => _tracks.audio.skip(fakeTrackCount).toList();
List<SubtitleTrack> get _subtitleTracks => _tracks.subtitle.skip(fakeTrackCount).toList(); List<SubtitleTrack> get _subtitleTracks {
final externalTitles = _externalSubtitleTracks.map((v) => v.title).toSet();
return [
..._tracks.subtitle.skip(fakeTrackCount).where((v) => !externalTitles.contains(v.title)),
..._externalSubtitleTracks,
];
}
@override @override
List<MediaStreamSummary> get streams { List<MediaStreamSummary> 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;
}
}
} }

View file

@ -36,7 +36,7 @@ extension ExtraSubtitleTrack on SubtitleTrack {
index: index, index: index,
codecName: null, codecName: null,
language: language, language: language,
title: title, title: title ?? '$index ($codec)',
width: null, width: null,
height: null, height: null,
); );

View file

@ -241,7 +241,7 @@ packages:
source: hosted source: hosted
version: "3.0.0" version: "3.0.0"
path: path:
dependency: transitive dependency: "direct main"
description: description:
name: path name: path
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"

View file

@ -19,6 +19,7 @@ dependencies:
media_kit_libs_android_video: media_kit_libs_android_video:
media_kit_native_event_loop: media_kit_native_event_loop:
media_kit_video: media_kit_video:
path:
dev_dependencies: dev_dependencies:
flutter_lints: flutter_lints: